Сегодня наши партнеры – разработчики компании Music Paradise – приготовили новый материал для читателей нашего блога. На этот раз ребята подробно расскажут об интеграции Apple Music в собственное приложение. Аналогичный опыт уже был описан на Хабре, однако статья разработчиков Music Paradise призвана не столько познакомить читателей с данным процессом, сколько подробно рассказать о нем и о некоторых важных, но неочевидных моментах при работе с Apple Music.
«С релизом iOS 9.3 яблочная корпорация дала возможность использовать свой сервис Apple Music для воспроизведения музыки. Мы решили опробовать эту возможность в работе над своим приложением Music Paradise Player. Опыт оказался весьма поучительным — в системе обнаружились некоторые подводные камни и слабые места, о которых полезно знать заранее. В этой статье мы постараемся кратко изложить основные моменты работы с Apple Music, а также некоторые особенности этой системы.
Проверка доступа к Apple Music
Поддержка Apple Music для разработчиков доступна в SDK начиная с версии 9.3, так что, если ваше приложение разрабатывалось под более ранние версии iOS, стоит обработать данное исключение.
Следующий шаг на пути выяснения возможности воспроизведения Apple Music — запрос авторизации к SKCloudServiceController:
[SKCloudServiceController requestAuthorization:^(SKCloudServiceAuthorizationStatus status) {
//Обрабатываем полученный статус
}];
В качестве статуса может прийти несколько значений:
- SKCloudServiceAuthorizationStatusAuthorized – всё отлично. Это наш целевой статус, в любом другом случае воспроизвести полноценно музыку не получится;
- SKCloudServiceAuthorizationStatusDenied – пользователь запретил приложению доступ к медиатеке устройства, дальше продвинуться нам не удастся. Хорошим выходом в этой ситуации будет предложить пользователю перейти в настройки и предоставить доступ вручную;
- SKCloudServiceAuthorizationStatusRestricted – тот же неутешительный результат, с той лишь разницей, что доступ невозможен из-за обстоятельств, не зависящих от пользователя.
Заметим, что в данном случае статус SKCloudServiceAuthorizationStatusNotDetermined нам прийти не может, так как пользователю придётся выбрать ответ во всплывающем окне, чтобы продолжать работу. Соответственно, обрабатывать данный вариант не имеет смысла.
Теперь, когда мы разобрались с доступом к медиатеке пользователя, необходимо проверить наличие у него подписки на Apple Music:
SKCloudServiceController *controller = [[SKCloudServiceController alloc] init];
[controller requestCapabilitiesWithCompletionHandler:^(SKCloudServiceCapability capabilities, NSError * _Nullable error) {
//Обрабатываем полученный ответ
}];
Тут тоже существует множество вариантов статусов, однако приемлемыми для нас будут только два:
- SKCloudServiceCapabilityMusicCatalogPlayback – пользователь может проигрывать музыку из Apple Music, медиатека iCloud выключена.
- SKCloudServiceCapabilityAddToCloudMusicLibrary – пользователь может проигрывать музыку из Apple Music, медиатека iCloud включена.
При желании можно также обработать неуспешный SKCloudServiceCapabilityNone (у пользователя нет подписки на Apple Music) – то есть предложить пользователю оформить подписку.
Запрос списка треков
Поиск и вывод топа треков — процесс весьма неоднозначный для тех, кто никогда не сталкивался с iTunes Search API. Для ясности разобьём его на несколько пунктов:
Поиск по ключевому слову
Общий вид запроса таков:
itunes.apple.com/search?term=%@&limit=%ld&s=%@&entity=song&explicit=No
Разберем каждый параметр:
Term – наш запрос, по которому производится поиск. Имейте в виду: если он состоит из нескольких слов, нужно заменять пробелы на + (возможно, это для многих будет очевидно, но оговорить стоит).
Limit – максимальное количество результатов. Тут всё интуитивно понятно. По умолчанию выставляется значение 50, но в каких-то случаях этого может быть недостаточно.
S (хорошая работа Apple, сразу всё понятно по названию) — данный аргумент поиска обязателен, он обозначает страну App Store, к которой привязана учетная запись пользователя. Дело в том, что для разных государств в Apple Music представлены различные композиции. Кроме того, один и тот же трек может иметь разные идентификаторы в разных странах.
Чтобы получить данный идентификатор для конкретного пользователя используем:
SKCloudServiceController *controller = [[SKCloudServiceController alloc] init];
[controller requestStorefrontIdentifierWithCompletionHandler:^(NSString * _Nullable storefrontIdentifier, NSError * _Nullable error) {
if(!error)
{
storeID = storefrontIdentifier; //Идентификатор
}
}];
Entity – необходимая сущность, в нашем случае это песня.
Explicit – определяет, включать ли в результаты поиска контент с ненормативной лексикой. В первую очередь тут стоит отталкиваться от возрастных ограничений в вашем приложении.
Более подробную информацию по использованию поиска можно получить тут.
Получение топ-чартов
Для получения топ-чартов следует воспользоваться генератором RSS ленты от Apple. На выходе из генератора мы получаем url такого типа:
itunes.apple.com/ru/rss/topsongs/limit=100/xml
где выводится топ треков для России в количестве 100 штук в формате xml. На мой взгляд, такой результат нас не устраивает по нескольким причинам.
Во-первых, необходимо поменять страну, так как наше предложение доступно на маркете и для зарубежных потребителей. Значит, нам нужно подставлять вместо ru идентификатор текущей страны пользователя.
Для получения идентификатора мы применили небольшую хитрость. Так как в приложении предусмотрены IAP, берем любой SKProduct и проворачиваем следующее:
SKProduct *product = //Любой IAP из приложения
NSLocale* storeLocale = product.priceLocale;
NSString *storeCountry = (NSString*)CFLocaleGetValue((CFLocaleRef)storeLocale, kCFLocaleCountryCode);
Соответственно, подставляем storeCountry вместо значения ru в наш URL.
И есть ещё один момент, который нас не устраивает — это формат получаемых данных. Но тут всё просто: меняем xml на json в конце строки, в итоге получаем URL такого типа для корректной выгрузки топ-чартов:
itunes.apple.com/%@/rss/topsongs/limit=100/json
Как получить большие обложки из iTunes search api
Очередной проблемой, с которой мы столкнулись при добавлении поиска по iTunes в наше приложение, стало то, что API возвращает нам обложки треков размером не более 100х100. Однако и тут есть свои хитрости. Хотя ссылка на изображение в хорошем качестве не представлена в результативном json, мы можем взять его, воспользовавшись следующим алгоритмом:
- Берем ссылку на изображение из json, которая находится по ключу «artworkUrl100»;
- Заменяем в полученной строке 100x100 на 600x600;
- Получаем ссылку на большое изображение.
Воспроизведение треков из Apple Music
Как бы странно это ни прозвучало после всех приготовлений, данный шаг самый простой во всём процессе добавления Apple Music в приложение. Всё, что нам нужно, — это проинициализировать плеер и задать ему список треков воспроизведения. Список треков воспроизведения задаётся в формате массива, содержащего строки с идентификаторами треков. В качестве кода это выглядит вот так:
-(void)playQuery:(NSArray<NSString*>*)query
{
self.player = [MPMusicPlayerController applicationQueuePlayer];
[self.player setQueueWithStoreIDs:query];
[self.player play];
}
Стоит еще раз напомнить что интересующая нас функция для работы с Apple Music:
setQueueWithStoreIDs: появилась в SDK начиная с iOS 9.3, до этого момента мы могли использовать MPMusicPlayerController только для воспроизведения уже имеющийся у пользователя медиатеки iTunes.
Если говорить о трудностях, с которыми мы столкнулись при изучении функционала, на память приходит тот факт, что после обработки json’ов, пришедших из поискового api, в словарях лежали цифровые значения, а не строковые. За этим нужно следить.
Также стоит упомянуть, что в примере мы используем applicationQueuePlayer. Он появился только в версии iOS 10.3, однако уже сейчас представляется нам более удачным решением по сравнению с applicationMusicPlayer, который сильно сбоит при работе с несколькими треками и при удаленном управлении (например, на заблокированном экране или с наушников), а также systemMusicPlayer, который по факту никак не связан с приложением и может продолжать играть даже после того, как пользователь вышел из него».
Автор: nanton