Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2021 Audio & Video

WWDC21 · 18 min · Audio & Video

Meet MusicKit for Swift

MusicKit makes it easy to integrate Apple Music into your app. Explore the Swift-based framework: We’ll take you through the basic process of using MusicKit — including how to find, request, and play content — and show you how you can incorporate music subscription workflows into your app if someone hasn’t yet signed up to Apple Music.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 6 snippets

Loading and accessing relationships swift · at 2:56 ↗
// Loading and accessing relationships

let detailedAlbum = try await album.with([.artists, .tracks, .relatedAlbums])
print("\(detailedAlbum)")

if let tracks = detailedAlbum.tracks {
    print("  Tracks:")
    tracks.prefix(2).forEach { track in
        print("    \(track)")
    }
}
Loading and accessing associations swift · at 3:31 ↗
// Loading and accessing associations

let detailedAlbum = try await album.with([.artists, .tracks, .relatedAlbums])
print("\(detailedAlbum)")

if let relatedAlbums = detailedAlbum.relatedAlbums {
    print("  \(relatedAlbums.title ?? ""):")
    relatedAlbums.prefix(2).forEach { relatedAlbum in
        print("    \(relatedAlbum)")
    }
}
Loading top level genres swift · at 9:02 ↗
// Loading top level genres

struct MyGenresResponse: Decodable {
    let data: [Genre]
}

let countryCode = try await MusicDataRequest.currentCountryCode
let url = URL(string: "https://api.music.apple.com/v1/catalog/\(countryCode)/genres")!

let dataRequest = MusicDataRequest(urlRequest: URLRequest(url: url))
let dataResponse = try await dataRequest.response()

let decoder = JSONDecoder()
let genresResponse = try decoder.decode(MyGenresResponse.self, from: dataResponse.data)
print("\(genresResponse.data[9])")
Requesting user consent for MusicKit swift · at 10:49 ↗
// Requesting user consent for MusicKit

@State var isAuthorizedForMusicKit = false

func requestMusicAuthorization() {
    detach {
        let authorizationStatus = await MusicAuthorization.request()
        if authorizationStatus == .authorized {
            isAuthorizedForMusicKit = true
        } else {
            // User denied permission.
        }
    }
}
Using music subscription to drive state of a play button swift · at 12:54 ↗
// Using music subscription to drive state of a play button

@State var musicSubscription: MusicSubscription?

var body: some View {
    Button(action: handlePlayButtonSelected) {
        Image(systemName: "play.fill")
    }
    .disabled(!(musicSubscription?.canPlayCatalogContent ?? false))
    .task {
        for await subscription in MusicSubscription.subscriptionUpdates {
            musicSubscription = subscription
        }
    }
}
Showing contextual music subscription offer swift · at 15:34 ↗
// Showing contextual music subscription offer

@State var musicSubscription: MusicSubscription?
@State var isShowingOffer = false

var offerOptions: MusicSubscriptionOffer.Options {
    var offerOptions = MusicSubscriptionOffer.Options()
    offerOptions.itemID = album.id
    return offerOptions
}

var body: some View {
    Button("Show Subscription Offers", action: showSubscriptionOffer)
        .disabled(!(musicSubscription?.canBecomeSubscriber ?? false))
        .musicSubscriptionOffer(isPresented: $isShowingOffer, options: offerOptions)
}

func showSubscriptionOffer() {
    isShowingOffer = true
}

Resources