Как проверить, установлена ​​ли Apple Music на устройстве пользователя?


9

Я делаю музыкальное приложение со Swift. Приложение позволяет пользователям воспроизводить музыку через подписку на Apple Music через приложение Apple Music. Я могу проверить, есть ли у пользователя подписка на Apple Music через:

SKCloudServiceController().requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in

    guard err == nil else {
        print("error in capability check is \(err!)")
        return
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) {
        print("user has Apple Music subscription")
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) {
        print("user does not have subscription")
    }

}

Тем не менее: существуют сценарии, когда у кого-то по какой-то причине будет подписка Apple Music, но на его устройстве не будет загружено приложение Apple Music. Если у пользователя есть подписка, но нет устройства, я хочу по существу рассматривать этот случай так, как будто у него вообще нет подписки, то есть мы не можем воспроизводить музыку через Apple Music.

Итак, я ищу способы добавить проверку, если Apple Music на устройстве пользователя. Я нахожу этот ответ: Проверьте , установлено ли приложение с помощью Swift в сочетании с этим ресурсом для поиска схемы URL - адреса Apple Music в и сделать вывод я могу проверить , если пользователь имеет как подписку Apple Music и приложение Apple Music , установленное на устройстве с помощью:

SKCloudServiceController()requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in

    guard err == nil else {
        print("error in capability check is \(err!)")
        return
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && UIApplication.shared.canOpenURL(URL(string: "music://")!) {
        print("user has Apple Music subscription and has the apple music app installed")
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) || !UIApplication.shared.canOpenURL(URL(string: "music://")!) {
        print("user does not have subscription or doesn't have apple music installed")
    }

}

Проблема заключается в том, что даже после удаления Apple Music с моего устройства первый случай, то есть тот, который печатается user has Apple Music subscription and has the apple music app installed, все еще вызывается. Я считаю , что я правильно схему URL - адрес , так как при переходе "music://"к "musi://", во втором случае, то есть тот , который печатает user does not have subscription or doesn't have apple music installedвызывается.

При попытке открыть через URL(string: "music://")Apple Music, удаленную через UIApplication.shared.open(URL(string: "music://")!), я получаю следующее предупреждение:

введите описание изображения здесь

Так почему устройство говорит, что я могу открыть URL(string: "music://")даже после удаления Apple Music? Способна ли URLбыть открыта, но результатом является просто представление вышеупомянутого предупреждения? Это правильный способ подтвердить, что пользователь установил Apple Music на своем устройстве? Есть ли способ подтвердить, что пользователь установил Apple Music на свое устройство? Если Apple дает пользователям возможность удалить приложение Apple Music, они также должны дать разработчикам возможность проверить, установлено ли приложение.


Я никогда не работал с музыкой Apple сам, но я считаю, что Apple относится к этой схеме URL-адреса особым образом, поскольку это их собственный продукт, поэтому, когда вы включаете эту схему URL-адреса, они лучше предлагают пользователю загрузить приложение, а не возвращать его. ложный. Вы пытались определить правильную схему URL, которая фактически открывала бы настоящий альбом в Apple Music или воспроизводила настоящую песню? Напр .: URL(string: "music://trackID=3214534"). Возможно, эта схема явного URL будет рассматриваться обычным способом, но не вызовет app restoreоповещение.
Старский

Я пытался несколько URL - адресов с использованием действительных идентификаторов треков и исполнителей Apple Music , которые не кажутся глубокой связи с Apple , музыка: URL(string: "music://trackId=1377813289")!, URL(string: "music://track=1377813289"), URL(string: "music://artist=562555")!, URL(string: "music://artistId=562555")!. Единственный способ, которым я смог получить глубокие ссылки - это что-то вроде URL(string: "https://music.apple.com/us/artist/562555")!, но это, очевидно, не помогает, так как это HTTP.
Дэвид Шопен

Вы занесли в белый список "music: //" в info.plist с помощью LSApplicationQueriesSchemes ?. Если нет, canOpenUrl должен неправильно вести себя.
Картик Рамеш

1
К сожалению, внесение в белый список схемы в моем info.plist совсем не меняет поведение. Моя проблема в том, что UIApplication.shared.canOpenURL(URL(string: "music://")!)возвращается trueвсе время, даже если приложение Apple Music удалено. Мне нужно, чтобы вернуться, falseкогда приложение будет удалено. Белый список URL-адресов не решит эту проблему (я пробовал).
Дэвид Шопен

Вы нашли лучшее решение для этого?
Мартин Млостек

Ответы:


3

Лучшее решение, которое у меня есть, хотя я ожидаю, что есть что-то лучшее, это использовать, MPMusicPlayer.prepareToPlay(completionHandler:)чтобы проверить, есть ли ошибка при попытке воспроизведения трека:

SKCloudServiceController().requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in

    guard err == nil else {
        print("error in capability check is \(err!)")
        return
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) {
        print("user has Apple Music subscription")
        MPMusicPlayerController.systemMusicPlayer.setQueue(with: ["1108845248"])
        systemMusicPlayer.prepareToPlay { (error) in
            if error != nil && error!.localizedDescription == "The operation couldn’t be completed. (MPCPlayerRequestErrorDomain error 1.)" {
                //It would appear that the user does not have the Apple Music App installed
            }
        }
    }

    if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) {
        print("user does not have subscription")
    }

}

Я не уверен, как это может относиться к любому, кто использует Apple Music в своем приложении для чего-либо, кроме воспроизведения треков, но, похоже, это определенно работает как чек, когда вы собираетесь сыграть чек. Всякий раз, когда я сталкиваюсь с этой ошибкой, я просто создаю предупреждение, сообщающее человеку, что у него есть подписка Apple Music, но приложение не установлено.

Тем не менее, было бы здорово иметь возможность выполнять проверку без какого-либо обработчика завершения, поскольку это позволило бы интегрировать логическую проверку в условные операторы (через if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && hasAppleMusicAppInstalled { //do something }).


Что ж, это решение работает путем проверки на наличие ошибок, но оно немного хакерское и требует выполнения следующего кода в обработчике завершения. Лучше иметь способ простой проверки, является ли она частью среды MusicKit, установлено ли само приложение.
Дэвид Шопен

Но да, этот ответ - обходной путь, который использует ошибки при подготовке к воспроизведению трека. Разработчику может потребоваться узнать, установлена ​​ли Apple Music без воспроизведения дорожки.
Дэвид Шопен

1
это все еще лучшее решение, которое вы нашли?
Мартин Млостек

К сожалению да
Дэвид Шопен

0

К счастью, Apple предоставляет вам метод, который возвращает false, если на устройстве не зарегистрировано приложение, установленное для обработки схемы URL, или если вы не объявили схему URL в файле Info.plist; в противном случае, правда.

func canOpenURL(_ url: URL) -> Bool

После я публикую схемы URL

Open = music://
Open = musics://
Open = audio-player-event://

Добавьте те, которые вы будете использовать в вашем файле info.plist.

После этого используйте 'canOpenURL', чтобы узнать больше, проверьте документы Apple.

https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl


URL-схема Apple Music всегда возвращается trueпри прохождении canOpenUrl. Это основная проблема, которую я хочу решить с помощью этого вопроса.
Дэвид Шопен

Вы указали «Музыкальное приложение» в LSApplicationQueriesSchemes?
Зеешан Ахмед

проверьте ответ снова, я обновил его.
Зеешан Ахмед

Согласно комментарию Картика Рамеша, я ранее пробовал схемы URL-адресов, внесенные в белый список, без изменения в поведении
Дэвид Шопен

0

Возможное решение заключается в следующем: настройка токена разработчика через API Apple Music (используется для запроса конечных точек Apple Music REST). Отправьте запрос в следующую функцию StoreKit ( Документация ):

requestUserToken(forDeveloperToken:completionHandler:)

Если ваш токен разработчика действителен, а возвращаемое значение токена пользователя по-прежнему равно nil / null, то пользователь устройства не является подписчиком службы Apple Music. Ошибка, генерируемая с кодом состояния HTTP, - 401 (неавторизовано). Для этого по-прежнему требуется проверка ошибки, однако не требуется пытаться воспроизвести конкретную дорожку (особенно по какой-то причине, если идентификатор дорожки контента, с которым вы проверяли, становится недействительным или изменяется).

Для вопроса об учетной записи, зарегистрированной на устройстве и имеющей подписку, но не загруженное приложение Музыка: обработайте ошибку при попытке воспроизведения определенного контента и либо предоставьте информацию пользователю, либо используйте контент, не требующий подписки Apple Music, в качестве альтернативы когда происходит ошибка.


1
Да, так что я уже знаю, как проверить, есть ли у пользователя подписка . Мой ответ, приведенный выше, касается фактической обработки ошибок. Решение, которое я ищу, заключается в том, можете ли вы точно определить, установлено ли на устройстве приложение Apple Music без необходимости воспроизведения дорожки.
Дэвид Шопен

0

Да, мы можем проверить большинство приложений, выполнив следующие шаги:

  1. Используйте Deep URL или URL-схему для конкретного приложения, которое вы хотите открыть, добавьте его в info.plist
  2. Используйте тот же URL и вызовите этот метод
    func canOpenURL(_ url: URL) -> Bool
    let url = URL(string: "music://")

    UIApplication.shared.open(url!) { (result) in
       if result {
          // The URL was delivered successfully!
       }
    }

Это не проблема, изложенный вопрос, который UIApplication.shared.canOpenUrl(URL(string: “music://”)!)всегда возвращается true, даже если приложение не установлено.
Дэвид Шопен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.