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.

Replies

SwiftUI's ArtworkImage loads the artworks much quicker and without the errors

Does it? I haven’t touched MusicKit in Xcode 15 beta 5 but my MusicKit app targets iOS 16 and uses SwiftUI only. In previous Xcode 15 betas, I saw all of the same errors you mention above.

  • I tested it again and you’re right, same errors are visible in SwiftUI

Add a Comment

After few updates to iOS this issue still persists. Apple please take a look at it, using MusicKit in the app is currently not viable because of it

I've submitted feedback to Apple, hopefully this gets resolved quickly