Ben Dodson

Freelance iOS, macOS, Apple Watch, and Apple TV Developer

Details on the iOS 9.3 Media Library additions

UPDATE: Thanks to my raising this privacy concern, Apple have resolved this issue as of iOS 10. I’ve left the old post below for posterity.

Due to my article on music library security on iOS, I’ve found myself in the position of being misquoted or misunderstood on sites such as AppleInsider (mainly in the comments) with regards to the new media library APIs in iOS 9.3. This article is intended to clear up some misunderstandings that people have about these new APIs.

In iOS 9.3, there are several additions to the music library. Indeed, it is the first item listed in the What’s New in iOS 9.3 developer document:

New methods in the Media Player and StoreKit frameworks let you add an Apple Music track to the music library and play it. First, use the SKCloudServiceController API to determine the current capabilities, such as if the device allows playback of Apple Music catalog tracks and the addition of tracks to the library. Then, you can use the MPMediaLibrary method addItemWithProductID:completionHandler: to add a track to the library and the MPMusicPlayerController method setQueueWithStoreIDs: to play a track.

Firstly, the StoreKit framework has been updated to include an SKCloudServiceController which basically gives an app the opportunity to request access to a user’s media library and to check if they have the ability to stream Apple Music tracks and / or add those tracks to their iCloud Music library.

Next, MPMusicPlayerController has been updated with a new method named setQueueWithStoreIDs which allows you to basically hand over an array of Apple Music identifiers and have those play instantly in the Music app without leaving your own app. Interestingly, this allows you to Rickroll someone in just a few lines of code:

func play() {
    let trackID = "255991760" // use 302053341 in USA, 255991760 in UK
    let controller = MPMusicPlayerController()
    controller.setQueueWithStoreIDs([trackID])
    controller.play()
}

This API, whilst interesting, has a few issues; the identifiers for music tracks are different for each country so a US track will not play on a UK Apple Music account1. There is also no error handling so it’ll just silently fail if you give it an incorrect identifier or one from the wrong store.

The final new addition is to MPMediaLibrary and is a method named addItemWithProductID:completionHandler:. This allows you to add an Apple Music track to the user’s library as long as they gave permission via the SKCloudServiceController and they have a valid Apple Music account. I had some issues getting this working on an iPhone 5c but it worked just fine on an iPad Pro leading me to think this may be an API limited to 64-bit devices (although this is still in beta so that may change). However, the API does not allow you to add MP3s to your library or import Spotify tracks or anything like that; it is just a way to add Apple Music tracks to your library. Why is that useful? The scenario I envision is that it is for apps like Shazam that identify music and then traditionally give you a link to go and see it in Apple Music or the iTunes Store. With this new API, those apps can now add a button such as “add this track to your library?” which will allow them to automatically add the Apple Music track to the media library.

The new APIs do not do any of the following things:

  • They do not allow apps to add music to your library if you are not using Apple Music
  • They do not allow apps to add music to your library that is not available on Apple Music
  • They do not allow apps to delete music from your library
  • They do not allow apps to edit metadata on any music in your library (i.e. changing title, artist, genre, rating, artwork)

Crucially, and linking this back to my previous article, this new permissions system is only for the new “add Apple Music tracks to your library API”; apps do not require permission to scan through your library. I’m still hopeful this will be addressed as at present the ‘Privacy’ settings screen in iOS 9.3 is incredibly misleading:

I take serious issue with the phrase “Apps that have requested access to your media library will appear here” because it makes it sound like apps require permission to access your library which is just not true. My Music Tracker app continues to work unimpeded on iOS 9.3 with no need to request access and, as demonstrated above, you can start playing streamed music in the Music app without authorization. This is all true as of iOS 9.3 beta 4 so hopefully it may get resolved before the final version of iOS 9.3 is released next month.

(Update: This was not resolved in the public version of iOS 9.3)

If you have any queries about how these new APIs work or how they will or won’t affect your media library, please feel free to contact me.

  1. There is a new API to give you a storefront identifier (mine is "143444,29") but I'm not sure how you translate to a single language like "gb" for use with the iTunes Search API - if anyone can shed some light on that, please let me know!

    Update, 10th Mar 2016: Thanks to Loreto Parisi for making me aware of the iTunes Affiliate Link website which contains a full list of the store identifiers and their respective ISO country codes which can be used with the iTunes Search API. I’ve put together a simple class to take care of this automatically.
    Update, 31st Mar 2016: Thanks to Matt Abras it turns out that the above code isn’t necessary; you can just use the undocumented s=143444 instead of country=gb when using the iTunes Search API↩︎

Storefront Additions: A simple way to convert SKCloudServiceController store identifiers into country codes » « The Divide #8 - Drunkstarter: A discussion on crowdfunding

Want to keep up to date? Sign up to my free newsletter which will give you exclusive updates on all of my projects along with early access to future apps.