MusicKit

RSS for tag

Let users play Apple Music and their local music library from your app using MusicKit.

Posts under MusicKit tag

133 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Detect the end of queue in MPMusicPlayerController
Hello, this is building off of another post in which several other posters and I had already attempted solving the issue in hacky ways. I am using MPMusicPlayerController.applicationQueuePlayer. My end goal here is to dynamically add items to the queue when it has ended based on my application's business logic. There is no way for me to know what these items will be when I am initially setting the queue. I have an updated implementation that seems to cover most edge cases, except for a glaringly obvious one – if there is just one item in the queue, and the user skips the track via MPRemoteCommandCenter (eg. lock screen), then it does not work. Currently, when I receive a MPMusicPlayerControllerPlaybackStateDidChange notification, I run this block: if player.playbackState == .paused,            player.currentPlaybackTime == 0,            player.indexOfNowPlayingItem == 0 {             EndOfQueueManager.handle()         } In the absence of a mechanism to detect the end of the queue from the framework, I would love to add the ability to add a target to MPRemoteCommand, like you can do for AVPlayer. I have tried to do exactly that, but it does not work: MPRemoteCommandCenter.shared().nextTrackCommand.addTarget { (event) -> MPRemoteCommandHandlerStatus in         if queue.count == 1 {             EndOfQueueManager.handle() }         return .success } I already have a functioning AVPlayer implementation that achieves my goal without any compromises or edge cases. I would be very disappointed if there is no way to do this with MPMusicPlayerController – being notified about the queue ending feels like a fairly rudimentary API hook.
1
2
748
4w
iOS 16 Music Kit MusicLibrary methods have stopped working
Hi there, I have a related forum thread here and a Feedback Assistant ticket open, but this issue seems different. Sometime within the last 2-3 weeks, code related to MusicLibrary has stopped working. None of my code has changed. For example, the below two snippets used to work fine:  for track in newTracks {    try await MusicLibrary.shared.add(track, to: targetPlaylist)  } try await MusicLibrary.shared.edit(targetPlaylist, items: items) newTracks and items are both fetched using: try await targetPlaylist.with(.tracks, preferredSource: .catalog).tracks Using preferredSource: .catalog was a workaround used to address the issue in the aforementioned post above. All iOS 16 capable functions are decorated with: @available(iOS 16, *) or in an if block: if #available(iOS 16, *) {... What's happening is that the following is showing up in the console: 2022-11-28 23:31:11.279648+0700 MyApp[38653:6736450] [core] Attempted to register account monitor for types client is not authorized to access: {(     "com.apple.account.iTunesStore" )} 2022-11-28 23:31:11.279718+0700 MyApp[38653:6736450] [Default] <ICUserIdentityStoreACAccountBackend: 0x282adb520> Failed to register for account monitoring. err=Error Domain=com.apple.accounts Code=7 "(null)" 2022-11-28 23:31:11.279758+0700 MyApp[38653:6736450] [Default] ICUserIdentity - Unable to retrieve DSID for userIdentity=<ICUserIdentity 0x2806eb120: [Active Account: <unresolved>]> - error=Error Domain=com.apple.accounts Code=7 "(null)" These errors are not caught by a do/catch block, but I assume they are related to the issue, and I believe they have to do with MyApp trying to access things that Music Kit thinks it's not supposed to. For example, if MyApp attempts to work with a playlist that it did not create, errors would be expected, thrown errors. The thing is that I know I'm working with resources that are created by MyApp. In fact, in trying to test this, I just tried to create a playlist with the below, and the same behavior is occurring: @available(iOS 16, *) func createPlaylist2(name: String, description: String) async -> MusicKit.Playlist? {     do {         Logger.log(.info, "Creating Playlist: \(name)")         Logger.log(.shrug, "Does this work?")         let newPlaylist = try await MusicLibrary.shared.createPlaylist(name: name, description: description) // <= Things stop here!         Logger.log(.success, "New playlist created: \(newPlaylist)") // <= this isn't logged.         return newPlaylist // <= nothing is returned     } catch {         Logger.log(.error, "Could not create new playlist: \(error)") // <= no error logged.     }     return nil } The result is: 2022-11-29 00:15:01.875064+0700 MyApp[38794:6760471] [core] Attempted to register account monitor for types client is not authorized to access: {(     "com.apple.account.iTunesStore" )} 2022-11-29 00:15:01.875372+0700 MyApp[38794:6760471] [Default] <ICUserIdentityStoreACAccountBackend: 0x283005720> Failed to register for account monitoring. err=Error Domain=com.apple.accounts Code=7 "(null)" 2022-11-29 00:15:01.876677+0700 MyApp[38794:6760323] [EntityQuery] Finished executing query in 0.000999928s 2022-11-29 00:15:01.889055+0700 MyApp[38794:6760323] [EntityQuery] Finished fetching results in 0.0120001s 2022-11-29 00:15:01.891235+0700 MyApp[38794:6760329] [core] Attempted to register account monitor for types client is not authorized to access: {(     "com.apple.account.iTunesStore" )} 2022-11-29 00:15:01.891684+0700 MyApp[38794:6760329] [Default] <ICUserIdentityStoreACAccountBackend: 0x283005720> Failed to register for account monitoring. err=Error Domain=com.apple.accounts Code=7 "(null)" 📘 Creating Playlist: TEST PLAYLIST 🤷🏻‍♀️ Does this work? 2022-11-29 00:15:06.697374+0700 MyApp[38794:6760329] [] nw_path_necp_check_for_updates Failed to copy updated result (22) What's really nasty is that errors are not thrown, so they can't be caught and handled in a catch block. I know that iOS 16.1 got released around the end of October, but I really don't know what's going on here. The behavior is showing up in both prod and when testing locally. Any help would be most appreciated. @JoeKhun: Did I miss the memo?
9
1
3.9k
May ’24
Apple Music Kit Web API - User's Top Played Songs/Artists
Hello everyone! I am using the web version of the Apple Music Kit API, and similar to how Apple is able to produce a user's year in rewind playlist showing the most played artists/songs from a year, I am trying to replicate it for either a year or all time. I have been searching the internet for days trying to figure it out, but I've been completely stuck. I am able to make the following HTTP request successfully. GET https://api.music.apple.com/v1/me/library/songs/ which returns back the user's library of songs, but I haven't figured out how to get the play count. I have tried adding a query like such ?extend=playCount, but that doesn't work. I can see here that the Swift Music Kit API is able to extend a play count property, but I haven't been able to figure it out for Web. Ideally, I am looking for an endpoint that just shows a user's top artist/tracks similar to Spotify, however, whenever I try to use the heavy in rotation endpoint here, it always returns an empty array. The way that I have described is the long-roundabout way where I'll have to fetch each individual song and sort by playCount. But if anyone happens to know how I can do either of the options I've described, it will be truly appreciated ! I've seen other forums posts from years ago, but hopefully there's been a discovered way. Thank you!
2
1
1.8k
Sep ’23
MusicKit MusicCatalogResourceRequest for artists with top-songs returns 504 in non-json format
I'm making a request to get 10 artists with their top songs at once, but for some artists it will always fail with a 504. The response is also in HTML which leads to a decoding error. This is my code var request = MusicCatalogResourceRequest<Artist>(matching: \.id, memberOf: ids) request.properties = properties let response = try await request.response() where ids is MusicItemId. Below I have an input which will always fail 100% of the time, even when retried. 10 elements  - 0 : "51639"  - 1 : "331584"  - 2 : "120199"  - 3 : "45058"  - 4 : "284786497"  - 5 : "44984"  - 6 : "37299"  - 7 : "518462"  - 8 : "39525"  - 9 : "73568" Example response: [DataRequesting] Failed to parse body of response with status code Unknown (504):  <!DOCTYPE html> <html lang="en"> <head>   <style>     body {       font-family: "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;       font-size: 15px;       font-weight: 200;       line-height: 20px;       color: #4c4c4c;       text-align: center;     }     .section {       margin-top: 50px;     }   </style> </head> <body> <div class="section">   <h1>&#63743;</h1>   <h3>Gateway Timeout</h3>   <p>Correlation Key: WFRI6Q5HXAUJYXGNRKQ6YTBYIM</p> </div> </body> </html> I have also tried batching these into 2 requests of 5 artists instead of 1 request of 10 artists which still fails. However, I do have sets of 10 artists that work fine. Anyone know why?
3
1
2.1k
May ’24
MPMusicPlayerController on watchOS
Hi, I’m looking at using MusicKit in my watchOS app however I don’t seem to have any method of being able to play the audio though the recommended use of MPMusicPlayerController since it isn’t available on watchOS. This method works fine for iOS and iPadOS but not watchOS which seems bizarre considering we have full access to MusicKit but no way to actually play any audio. I’m trying to build an app that includes Apple Music through MusicKit but don’t have any way to actually play the audio. Is there a technical reason for this and if so is there any other way to play audio from MusicKit on watchOS. The docs for MPMusicPlayerController can be found here: https://developer.apple.com/documentation/mediaplayer/mpmusicplayercontroller
1
1
754
Oct ’23
Issues with MusicLibraryRequest on macOS/Mac Catalyst
I've been continuing to port my app to the Mac using Catalyst, and have discovered a couple of big issues with MusicLibraryRequest which make it not particularly usable. I've submitted FBs already, but figured a forum post wouldn't hurt :) filter(matching:) functions unavailable on macOS/Catalyst - FB12301718 The first thing I noticed when building for a macOS or Catalyst target is that a couple of functions are simply not available: I'm hoping this is a bug, as these methods are crucial to being able to interact with the library. request.filter(matching: .id, equalTo:) always returns empty on Mac Catalyst - FB12301908 I have not been able to successfully retrieve an Album using a MusicLibraryRequest. The result is always empty. In the feedback, I attached a sample project that makes an unfiltered MusicLibraryRequest, then takes the first album and tries to make a new MusicLibraryRequest filtered to that album's ID. Fetching albums by ID using this method works just fine on iOS 17. Thanks again for all your work on bringing these capabilities to the Mac!
2
0
1.2k
Jul ’23
Cannot load underlying module for 'MediaPlayer'
I'm getting the following error in Xcode and I can't figure out how to fix it. Cannot load underlying module for 'MediaPlayer' I've searched Google and have come across lots of other people with similar issues whereby they're importing something and it's producing this error alongside it. https://stackoverflow.com/questions/76256875/cannot-load-underlying-module-for-scenekit https://developer.apple.com/forums/thread/115059 https://stackoverflow.com/questions/32673866/cocoapods-cannot-load-underlying-module-for-x The error is being shown inline with this bit of code: import SwiftUI import MusicKit import MediaPlayer <-- this line here I can build and run the project without issue and it disappears. But will quickly reappear again a short while later and it's very annoying. How can I resolve this please?
1
1
1.5k
Jul ’23
App hangs while opening from background
Hi, My app hangs for about a second when I open the app when it's been in background phase. It doesn't hang every time, but it hangs randomly (like once in 10 times) when I open the app again. I am not able to reproduce what causes this hang. Hang Detection provides hang logs (spindump) when hang occurs. It has something to do with MusicKit as logs mention it but I cannot understand what it is. Please help me understand these logs. I am running iOS 17 beta 1 with MusicKit and ApplicationMusicPlayer. Heaviest stack for the main thread of the target process: 69 start + 2104 (dyld + 87288) [0x1b719b4f8] 69 ??? (Timed + 32864) [0x104ae8060] 69 ??? (SwiftUI + 980040) [0x19840a448] 69 ??? (SwiftUI + 1071088) [0x1984207f0] 69 ??? (SwiftUI + 1667804) [0x1984b22dc] 69 UIApplicationMain + 340 (UIKitCore + 3740336) [0x196c602b0] 69 -[UIApplication _run] + 888 (UIKitCore + 3741260) [0x196c6064c] 69 GSEventRunModal + 164 (GraphicsServices + 4644) [0x1d6199224] 69 CFRunLoopRunSpecific + 600 (CoreFoundation + 527792) [0x1947fedb0] 68 __CFRunLoopRun + 1996 (CoreFoundation + 509348) [0x1947fa5a4] 68 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CoreFoundation + 626340) [0x194816ea4] 68 _dispatch_main_queue_callback_4CF + 44 (libdispatch.dylib + 75296) [0x19c404620] 67 _dispatch_main_queue_drain + 744 (libdispatch.dylib + 76056) [0x19c404918] 67 swift_job_runImpl(swift::Job*, swift::ExecutorRef) + 72 (libswift_Concurrency.dylib + 274348) [0x19f58cfac] 67 swift::runJobInEstablishedExecutorContext(swift::Job*) + 416 (libswift_Concurrency.dylib + 269688) [0x19f58bd78] 66 ??? (MusicKit + 4857464) [0x208aabe78] 66 ??? (MusicKit + 4856108) [0x208aab92c] 66 -[MusicKit_SoftLinking_MPMusicPlayerController nowPlayingItem] + 24 (MusicKit + 157364) [0x2086306b4] 66 -[MPMusicPlayerController nowPlayingItem] + 24 (MediaPlayer + 1358540) [0x1a681bacc] 66 -[MPMusicPlayerController _nowPlaying] + 372 (MediaPlayer + 1329552) [0x1a6814990] 66 -[MPMusicPlayerController onServer:] + 52 (MediaPlayer + 1333428) [0x1a68158b4] 63 -[MPMusicPlayerApplicationController _establishConnectionIfNeeded] + 1768 (MediaPlayer + 1553848) [0x1a684b5b8] 63 _NSXPCDistantObjectSimpleMessageSend1 + 60 (Foundation + 208348) [0x1937daddc] 63 -[NSXPCConnection _sendSelector:withProxy:arg1:] + 116 (Foundation + 208548) [0x1937daea4] 62 -[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:] + 2160 (Foundation + 214664) [0x1937dc688] 62 __NSXPCCONNECTION_IS_WAITING_FOR_A_SYNCHRONOUS_REPLY__ + 16 (Foundation + 652944) [0x193847690] 62 xpc_connection_send_message_with_reply_sync + 264 (libxpc.dylib + 67488) [0x1fc00d7a0] 62 dispatch_mach_send_with_result_and_wait_for_reply + 60 (libdispatch.dylib + 127760) [0x19c411310] 62 _dispatch_mach_send_and_wait_for_reply + 540 (libdispatch.dylib + 126832) [0x19c410f70] 62 mach_msg + 24 (libsystem_kernel.dylib + 4692) [0x1da082254] 62 mach_msg_overwrite + 436 (libsystem_kernel.dylib + 83544) [0x1da095658] 62 mach_msg2_trap + 8 (libsystem_kernel.dylib + 3332) [0x1da081d04] *62 ??? (<31E57057-A9A0-3BE5-90CB-5C08E9683B34> + 217132) [0xfffffff007e0102c] Thank you. CC @JoeKun
2
0
1.1k
Oct ’23
MPMediaQuery not returning updated results
I have noticed changes Apple Music made to my library, take in particular a changed album edition that is reflected in how the title is listed. I can see the new title in the Music app in two different devices. On one device MPMediaQuery returns the album with the new title. The other device (an iPad with less memory, in case that matters) is still returning the old edition. Is there anything I can do to make sure the data returned is up to date and matches what is seen in the Music app?
0
0
644
Jul ’23
Terrible performance when using MusicKit's Artwork with UIKit
I'm building a UIKit app that reads user's Apple Music library and displays it. In MusicKit there is the Artwork structure which I need to use to display artwork images in the app. Since I'm not using SwiftUI I cannot use the ArtworkImage view that is recommended way of displaying those images but the Artwork structure has a method that returns url for the image which can be used to read the image. The way I have it setup is really simple: extension MusicKit.Song { func imageURL(for cgSize: CGSize) -> URL? { return artwork?.url( width: Int(cgSize.width), height: Int(cgSize.height) ) } func localImage(for cgSize: CGSize) -> UIImage? { guard let url = imageURL(for: cgSize), url.scheme == "musicKit", let data = try? Data(contentsOf: url) else { return nil } return .init(data: data) } } Now, everytime I access .artwork property (so a lot of times) the main thread gets blocked and the console output gets bombared with messages like these: 2023-07-26 11:49:47.317195+0200 Plum[998:297199] [Artwork] Failed to create color analysis for artwork: <MPMediaLibraryArtwork: 0x289591590> with error; Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.mediaartworkd.xpc was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.apple.mediaartworkd.xpc was invalidated: failed at lookup with error 159 - Sandbox restriction.} 2023-07-26 11:49:47.317262+0200 Plum[998:297199] [Artwork] Failed to create color analysis for artwork: file:///var/mobile/Media/iTunes_Control/iTunes/Artwork/Originals/4b/48d7b8d349d2de858413ae4561b6ba1b294dc7 2023-07-26 11:49:47.323099+0200 Plum[998:297013] [Plum] IIOImageWriteSession:121: cannot create: '/var/mobile/Media/iTunes_Control/iTunes/Artwork/Caches/320x320/4b/48d7b8d349d2de858413ae4561b6ba1b294dc7.sb-f9c7943d-6ciLNp'error = 1 (Operation not permitted) My guess is that the most performance-heavy task here is performing the color analysis for each artwork but IMO the property backgroundColor should not be a stored property if that's the case. I am not planning to use it anywhere and if so it should be a computed async property so it doesn't block the caller. I know I can move the call to a background thread and that fixes the issue of blocking main thread but still the loading times for each artwork are terribly slow and that impacts the UX. SwiftUI's ArtworkImage loads the artworks much quicker and without the errors so there must be a better way to do it.
4
0
935
Feb ’24
MusicKit SDK for Android update?
Hi team, Are there any plans to update the Apple Music SDK for Android? With the upcoming release of the new music experience on iOS and the Apple Music app for Android getting a whole slew of features over the past month, is the (rather out of date - last update was December 2021) MusicKit SDK for Android going to get the new release that would enable developer avail of the new feature or is that SDK abandoned at this stage?
1
0
518
Oct ’23
MusicKit MusicCatalogSearchRequest.response() starting failing with 401 userTokenRequestFailed for users without subscription
Hello, I have an app published on AppStore which relies on MusicKit's functionality to retrieve results of MusicCatalogSearchRequest even when a user doesn't have an Apple Music subscription. (As per other sources and this thread, this is expected to work normally for users without the subscription.) The app used to work fine for months, yet today all the devices I tested on failed to execute the request (both AppStore and dev versions), resulting in the following log: 2023-07-27 23:45:16.036271+0200 Lisyn[6288:3156868] [DataRequesting] Updated user token cache with new error. 2023-07-27 23:45:16.043294+0200 Lisyn[6288:3156868] [DataRequesting] Failed retrieving user token: Error Domain=ICError Code=-8101 "Failed to fetch music user token with Unauthorized (401) status code. Account does not have an active Apple Music Subscription." UserInfo={NSDebugDescription=Failed to fetch music user token with Unauthorized (401) status code. Account does not have an active Apple Music Subscription.}. Throwing .userTokenRequestFailed. 2023-07-27 23:45:16.043413+0200 Lisyn[6288:3156868] [DataRequesting] Failed refreshing user token for MusicDataRequest.Context( url: "https://api.music.apple.com/v1/catalog/it/search?term=B&l=en-GB&types=songs&limit=25&omit%5Bresource%5D=autos", currentRetryCounts: [.userTokenInvalid: 1], activeRetryContext: RetryContext( reason: .userTokenInvalid, previousTokens: .personalizedTokens( developerToken: "some token", userToken: "some other token" ) ) ). Error = .userTokenRequestFailed. I am using automatic token generation and make requests via MusicKit: func searchMusic(searchText: String) async throws -> [PlaybackStoreID] { return try await throttler.schedule { var request = MusicCatalogSearchRequest(term: searchText, types: [Song.self]) request.limit = 25 return try await request.response().songs.map(\.id.rawValue) } } None of the certificate/identifier settings, nor the code related to the issue has been touched between when it was working and now. Also, live versions stopped working as well, so I am sure this isn't related. Is this a temporary issue? Should I roll out a fix using non-automatic token generation? Thank you!
1
0
605
Jul ’23
MusicKit JS Not Resolving/Authorizing User
For some reason when I go through the same process as shown here: https://developer.apple.com/documentation/musickitjs/ using MusicKit JS to authorize a user, the popup opens a user logs in and then on the access request screen you click allow nothing happens. You can see in the network tab when inspecting that the usertoken is being generated but the popup isn't closing and no matter what I try I cannot extract the usertoken, any thoughts?
0
0
629
Jul ’23
Crossfade with MPMusicPlayerController.applicationQueuePlayer
Hi. In iOS 17 Apple introduced crossfading for the Music app. In my app I am using MPMusicPlayerController.applicationQueuePlayer and also want to support crossfading. In an early beta of iOS 17 my app crossfaded automatically with the same setting as for the Music app which maybe was a bug. However, I did not find any way to enable crossfade for my app. Does anybody know how to do that? Thanks, Dirk
1
0
737
Nov ’23
Fetch with time in Apple music API
I'm trying to pull library songs, playlist and artist from authorized user. The API gives me data in alphabetical order and there's no timestamp in the response, is it possible to fetch data with the most recent ones first? It is very difficult to pull all the data and filter ourselves, is it possible to fetch only the first 30-60 most recent ones?
0
0
513
Aug ’23
Change the Volume for ApplicationMusicPlayer to hear the voice synthesizer?
My app uses the voice synthesizer, and I'm trying to integrate apple music into my app using MusicKit to play a playlist during a workout. I want to lower the volume of the music while the synthesizer is speaking so the user can hear it. When I play music locally using AVAudioPlayer this is possible. I'm using the ApplicationMusicPlayer to play the tracks of the playlist. I don't see a way to lower the volume ApplicationMusicPlayer programmatically. Is there a way to programmatically change the volume of the ApplicationMusicPlayer? Or is there a better way to accomplish what I'm trying to do? thanks
1
0
496
Aug ’23