📜 ⬆️ ⬇️

Embedding Apple Music in an iOS application

Today, our partners - the developers of the company Music Paradise - have prepared a new material for the readers of our blog. This time, the guys will talk in detail about the integration of Apple Music into their own application. A similar experience has already been described in Habré , but the article by Music Paradise developers is intended not so much to acquaint readers with this process, as to talk in detail about it and about some important, but not obvious points when working with Apple Music.

“With the release of iOS 9.3, Apple Inc. made it possible to use its Apple Music service to play music. We decided to try this opportunity in the work on our application Music Paradise Player . The experience turned out to be quite instructive - some pitfalls and weak points were discovered in the system, which are useful to know in advance. In this article we will try to briefly outline the main points of working with Apple Music, as well as some features of this system.


Apple Music Access Check


Apple Music support for developers is available in the SDK since version 9.3, so if your application was developed for earlier versions of iOS, you should handle this exception.
')
The next step on the road to figuring out Apple Music playback is an authorization request to SKCloudServiceController:

[SKCloudServiceController requestAuthorization:^(SKCloudServiceAuthorizationStatus status) { //   }]; 

Several values ​​can come as a status:


Note that in this case, the status of SKCloudServiceAuthorizationStatusNotDetermined cannot come because the user will have to select a response in the pop-up window in order to continue working. Accordingly, it does not make sense to process this option.

Now, when we figured out access to the user's library, you need to check that he has a subscription to Apple Music:

 SKCloudServiceController *controller = [[SKCloudServiceController alloc] init]; [controller requestCapabilitiesWithCompletionHandler:^(SKCloudServiceCapability capabilities, NSError * _Nullable error) { //   }]; 

Here, too, there are many options for statuses, but only two will be acceptable to us:


If desired, you can also handle the unsuccessful SKCloudServiceCapabilityNone (the user does not have a subscription to Apple Music) - that is, suggest the user to subscribe.



Request track list


Finding and displaying top tracks is a very ambiguous process for those who have never come across the iTunes Search API. For clarity, we break it down into several points:

Search by keyword


The general view of the request is as follows:

itunes.apple.com/search?term=%@&limit=%ld&s=%@&entity=song&explicit=No

Let us analyze each parameter:

Term is our search query. Keep in mind: if it consists of several words, you need to replace the spaces with a + (perhaps this will be obvious to many, but it’s worth it).

Limit - the maximum number of results. It's all intuitive. The default value is 50, but in some cases this may not be enough.

S (Apple's good work, everything is immediately clear by name) - this search argument is obligatory, it designates the country of the App Store to which the user account is associated. The fact is that for different states in Apple Music various compositions are presented. In addition, the same track may have different identifiers in different countries.

To get this identifier for a specific user, use:

 SKCloudServiceController *controller = [[SKCloudServiceController alloc] init]; [controller requestStorefrontIdentifierWithCompletionHandler:^(NSString * _Nullable storefrontIdentifier, NSError * _Nullable error) { if(!error) { storeID = storefrontIdentifier; // } }]; 

Entity is a necessary entity, in our case it is a song.

Explicit - Determines whether to include in the search results content with offensive language. First of all, it is worthwhile to build on the age restrictions in your application.

More information on the use of search can be found here .

Getting top charts


To get top charts, you should use the generator RSS feeds from Apple . At the output of the generator, we get the url of this type:

itunes.apple.com/en/rss/topsongs/limit=100/xml

where the top tracks for Russia are displayed in the amount of 100 pieces in xml format. In my opinion, this result does not suit us for several reasons.

First, it is necessary to change the country, since our offer is available on the market and for foreign consumers. So, we need to substitute the current user's country identifier instead of ru.

We used a little trick to get the ID. Since the application provides for IAP, take any SKProduct and rotate the following:

 SKProduct *product = // IAP   NSLocale* storeLocale = product.priceLocale; NSString *storeCountry = (NSString*)CFLocaleGetValue((CFLocaleRef)storeLocale, kCFLocaleCountryCode); 

Accordingly, we substitute storeCountry for ru in our URL.

And there is one more thing that does not suit us - this is the format of the received data. But everything is simple: we change xml to json at the end of the line, as a result we get the URL of this type for the correct unloading of top charts:

itunes.apple.com/%@/rss/topsongs/limit=100/json



How to get large covers from iTunes search api


Another problem we encountered when adding a search on iTunes to our application was that the API returns us the cover of tracks no larger than 100x100. However, there are some tricks here. Although the link to the image in good quality is not represented in the effective json, we can take it using the following algorithm:

  1. Take the link to the image from json, which is located on the key «artworkUrl100»;
  2. Replace the received line 100x100 by 600x600;
  3. We get a link to a large image.


Playing tracks from Apple Music


However strange it may sound after all the preparations, this step is the easiest in the whole process of adding Apple Music to the application. All we need is to initialize the player and give it a list of playback tracks. The list of playback tracks is specified in the format of an array containing strings with track identifiers. As a code, it looks like this:

 -(void)playQuery:(NSArray<NSString*>*)query { self.player = [MPMusicPlayerController applicationQueuePlayer]; [self.player setQueueWithStoreIDs:query]; [self.player play]; } 

It is worth reminding once again that the function we are interested in to work with Apple Music:
setQueueWithStoreIDs: appeared in the SDK since iOS 9.3, up to this point we could use MPMusicPlayerController only to play the user's iTunes library.

If we talk about the difficulties that we encountered in studying the functional, it comes to mind that after processing json'ov, which came from the search api, in the dictionaries lay digital values, not string values. You need to follow this.

It is also worth mentioning that in the example we use the applicationQueuePlayer. It appeared only in iOS 10.3, but now it seems to us that it is a better solution compared to applicationMusicPlayer, which greatly fails when working with several tracks and when remotely controlled (for example, on a locked screen or from headphones), and also systemMusicPlayer, which The fact is in no way connected with the application and can continue to play even after the user has logged out of it. ”

Source: https://habr.com/ru/post/326868/


All Articles