ハイライト
Apple は WWDC21 で MusicKit for Swift を発表しました。開発者は、Swift 同時実行性と SwiftUI を使用して、Apple Music コンテンツのリクエスト、認証とサブスクリプション ステータスの処理、カタログ音楽の再生、アプリ内でのサブスクリプション オファーの表示を行うことができます。
主要内容
以前は、Apple Music をアプリに統合する際、開発者は複数の種類の問題に同時に対処する必要がありました。
コンテンツリクエストはカテゴリです。 Apple Music API を呼び出し、JSON を解析し、結果をアプリで使用できるモデルに変換する必要があります。アルバム、曲、アーティスト、ジャンルの間にも関係があります。アルバム トラックを取得したい場合は、リクエストを整理してロジックを解析する必要があります。
認可とトークンは別のカテゴリです。 Apple Music API には開発者トークンが必要です。これまでの慣例では、開発者のバックエンドに移動して MusicKit 秘密キーを作成し、その秘密キーを独自のサーバーに置き、アプリがサーバーからトークンをリクエストできるようにしていました。ユーザー プロファイルや音楽ライブラリに関しては、ユーザーの同意とユーザー トークンも処理されます。
再生のオプションもあります。ソーシャル アプリでは、システム ミュージック アプリが再生する内容を制御したい場合があります。フィットネス アプリには独自の再生キューが必要な場合がありますが、システムの音楽アプリには影響しません。購読ステータスも、ボタンをクリックできるかどうかに影響します。購読を解除したユーザーには、適切な購読の入り口が表示される必要があります。
MusicKit for Swift は、これらの散在するタスクを Swift フレームワークに取り込みます。これは、厳密に型指定された音楽モデル、構造化リクエスト、汎用データ リクエスト、自動トークン生成、サブスクリプション状態ストリーミング、再生 API、および SwiftUI サブスクリプション オファー修飾子を提供します。
この講演の例はアルバム アプリです。ユーザーは Apple Music のアルバムを検索し、トラックを表示し、クリックして再生できます。その後、このアプリにはコード スキャン機能が追加されました。カメラを使用して古い CD のバーコードを識別し、次に MusicKit を使用して UPC に従って Apple Music カタログをクエリし、物理レコードをデジタル アルバムにマッピングします。
この例は、MusicKit の位置付けを示しています。これにより、音楽コンテンツを通常の Swift データと同様にアプリに取り込むことができます。開発者は検索、表示、再生、サブスクリプションのプロセスに関心を持ち、基礎となる API からブリッジを構築する必要はありません。
詳細
1. 音楽モデル: アルバムの属性、関係、関連付け
(01:23) MusicKit は、音楽アイテムにアクセスするための新しいモデル レイヤーを提供します。リクエストでは、フィルター条件に基づいて Apple Music カタログを検索したり、リソースを取得したりできます。返された結果は、ページネーションのサポートが組み込まれたコレクションに配置されます。
スピーチ用Album音楽モデルの構造を説明します。Album値型(value type)であり、通常の属性、関係(relationships)、関連付け(association)の3種類のデータを含みます。共通の属性には次のものがあります。title、isCompilation、artwork。関係には以下が含まれますartists、genres、tracks。この関連付けは、シナリオの編集に重点を置いています。appearsOnまたはrelatedAlbums、コレクション自体にタイトルが付けられる場合もあります。
(02:56) リレーションシップをロードするときに、MusicKit は次を使用します。with方法。ネットワーク経由で Apple Music API からアルバムのより完全な表現を取得します。
// 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)")
}
}
キーポイント:
album.with([.artists, .tracks, .relatedAlbums])同じアルバムのより完全なバージョンをリクエストします。try awaitこのステップで非同期ネットワーク要求が実行され、エラーがスローされる可能性があることを示します。.artists、.tracksそして.relatedAlbums一緒にロードされる関係と関連付けです。detailedAlbum.tracksこれはオプションの値であり、リクエスト結果にトラックが含まれる場合にのみ入力されます。if let。tracks.prefix(2)最初の 2 曲を取り出して、少数の結果を出力するために使用します。forEach { track in ... }通常の配列と同様に、MusicKit によって返されたコレクションを反復処理します。
(03:31) 同じ方法で関連付けにアクセスします。違いは、関連するコレクションには通常タイトルがあることです。例は次のとおりです。relatedAlbums.title読んでみてください。
// 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)")
}
}
キーポイント:
relatedAlbumsからalbum.withリクエストで指定された.relatedAlbums。if let relatedAlbums = detailedAlbum.relatedAlbums関連データが存在する場合にのみアクセスされることが保証されます。relatedAlbums.title ?? ""関連付けられたコレクションのタイトルを読み取り、タイトルがない場合は空の文字列を出力します。relatedAlbums.prefix(2)最初の 2 つの関連アルバムを取り上げます。relatedAlbumこれは、直接印刷するか、詳細ページに進むことができる MusicKit 音楽プロジェクトです。
2. 構造化リクエスト: UPC を使用してバーコードからアルバムを検索
(05:46) トーク内のアプリはすでに古い CD のバーコードを認識できます。欠けている手順は、認識されたバーコード値を Apple Music のアルバムに変換することです。
MusicKitが提供するのはMusicCatalogResourceRequest。例では、アルバムリクエストを作成し、UPC属性とdetectedBarcode同等のマッチングを行います。UPCユニバーサルプロダクトコード、つまりバーコードです。
let albumsRequest = MusicCatalogResourceRequest<Album>(
matching: \Album.upc,
equalTo: detectedBarcode
)
let albumsResponse = try await albumsRequest.response()
if let firstAlbum = albumsResponse.items.first {
await handleDetectedAlbum(firstAlbum)
}
キーポイント:
MusicCatalogResourceRequest<Album>このリクエストがアルバム リソースを探していることを示します。matching: \Album.upcフィルター フィールドがアルバムの UPC であることを指定します。equalTo: detectedBarcodeカメラで認識したバーコードをクエリ条件として使用します。try await albumsRequest.response()リクエストを実行し、非同期でレスポンスを取得します。albumsResponse.items.first返却されたコレクションから最初のアルバムを入手します。await handleDetectedAlbum(firstAlbum)メインスレッドに関連する処理ロジックを呼び出します。スピーチでは、このメソッドはスキャン コード ビューを閉じて、アルバムの詳細ページをプッシュします。
3. 一般的なデータリクエスト: 任意の Apple Music API URL にアクセスします
(07:47) 構造化リクエストは一般的なシナリオに適しています。 Apple Music API エンドポイントに遭遇すると、MusicKit は次のサービスも提供します。MusicDataRequest。 URLRequest を受信し、生の JSON データを返します。
(09:02) 例では、トップレベルのジャンルリストを読み込みます。 Apple Music API は JSON を返し、コードは次を使用します。JSONDecoderデコード中。Genreそれ自体は以下に準拠しますDecodableしたがって、応答構造では宣言する必要があるのは 1 つだけです。data配列。
// 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])")
キーポイント:
MyGenresResponseマッピング API によって返される最上位の JSON 構造。let data: [Genre]MusicKit を再利用するGenreタイプ。MusicDataRequest.currentCountryCode現在のユーザーに対応する国コードまたは地域コードを取得します。URL(string: ...)Apple Music API のジャンル エンドポイントを詳しく説明します。MusicDataRequest(urlRequest:)通常の使用URLRequestMusicKit データリクエストを作成します。try await dataRequest.response()ネットワーク要求を実行し、応答を返します。JSONDecoder().decode(...)原本を入れてdataResponse.data厳密に型指定された Swift 値にデコードします。genresResponse.data[9]Tenth ジャンル プロジェクトにアクセスしてください。
4. 認可とトークン: まずユーザーの同意を求め、次に MusicKit にトークンを管理させます。
(09:56) Apple は、どのアプリが Apple Music データにアクセスできるかをユーザーが制御する必要があると強調しています。アプリは、ユーザーの視聴履歴や音楽ライブラリにアクセスする前に、ユーザーの同意を求める必要があります。この認証はデバイスとアプリごとに分離されています。
認証ポップアップ ウィンドウに、アプリが認証されていることが表示されます。Info.plistApple Music の使用説明は で設定されています。このコピーには、アプリが Apple Music にアクセスする必要がある理由が説明されています。
(10:49) 使用許可のリクエストMusicAuthorization.request()。
// 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.
}
}
}
キーポイント:
@State var isAuthorizedForMusicKit = falseSwiftUI 状態を使用して認証結果を記録します。requestMusicAuthorization()認証プロセスをトリガーするメソッドです。detach { ... }非同期実行ブロックを作成します。await MusicAuthorization.request()Apple Music の認証をリクエストします。authorizationStatus == .authorizedユーザーが許可されていることを示します。isAuthorizedForMusicKit = trueMusicKit に依存する機能を利用できるようにします。elseユーザーが認可を拒否した場合は支店が対応します。
(11:21) トークンの処理も簡単になりました。以前は、開発者トークンには秘密キー、サーバー、アプリからサーバーへのリクエスト リンクが必要でした。 MusicKit for Swift は開発者トークンを自動的に生成できます。開発者は、App ID を登録するページで App Services に入り、MusicKit チェックボックスを有効にするだけで済みます。
パーソナライゼーション エンドポイントにはユーザー トークンも必要です。スピーチでは、ユーザートークンもMusicKitによって自動的に生成されると述べています。
let authorizationStatus = await MusicAuthorization.request()
// Developer token: enable MusicKit in App Services for the App ID.
// User token: MusicKit generates it for personalized endpoints.
キーポイント:
MusicAuthorization.request()これは、ユーザーの Apple Music データにアクセスする前の許可された入り口です。- 開発者トークンの生成は MusicKit に委ねられますが、App ID で MusicKit サービスを有効にする必要があります。
- ユーザー トークンはパーソナライズされたエンドポイントに使用されます。
- 開発者は、トークンを生成するために MusicKit 秘密キーを自分のサーバーに置く必要はありません。
5. サブスクリプション ステータス: アビリティを使用して再生ボタンを制御します
(12:23) アプリは、ユーザーが Apple Music のサブスクリプションを持っているかどうかを知る必要があります。 MusicKit は、サブスクリプション情報を 3 つの機能に分類します。ユーザーが Apple Music カタログ コンテンツを再生できるかどうか、iCloud ミュージック ライブラリが有効かどうか、およびユーザーがサブスクライバーになれるかどうかです。
再生ボタンだけが重要ですcanPlayCatalogContent。ユーザーがカタログ コンテンツを再生できない場合は、ボタンを無効にする必要があります。
(12:54) 例MusicSubscription.subscriptionUpdatesサブスクリプションの変更を継続的に受信します。
// 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
}
}
}
キーポイント:
@State var musicSubscription: MusicSubscription?現在のサブスクリプションステータスを保存します。Button(action: handlePlayButtonSelected)再生ボタンを定義します。Image(systemName: "play.fill")システムの再生アイコンを使用します。.disabled(...)サブスクリプション機能に基づいてボタンをクリックできるかどうかを制御します。musicSubscription?.canPlayCatalogContent ?? falseデフォルトでは、サブスクリプション情報がないとディレクトリ コンテンツを再生できません。.task { ... }SwiftUI ビューで非同期タスクを開始します。for await subscription in MusicSubscription.subscriptionUpdatesサブスクリプション ステータス ストリームを聞きます。musicSubscription = subscription最新の状態を SwiftUI 状態に書き戻すと、それに応じてインターフェイスが更新されます。
6. プレーヤーの選択: システム プレーヤーとアプリ プレーヤー
(13:28) MusicKit には 2 つのプレーヤーが用意されています。SystemMusicPlayerそしてApplicationMusicPlayer。
ソーシャルアプリも利用可能SystemMusicPlayerシステムのミュージック アプリが再生しているものを制御します。フィットネスアプリの方が適しているApplicationMusicPlayer、再生状態をシステムの音楽アプリとは別に保ちます。
プレゼンテーションで言及されている主要な API 機能は次のとおりです。
// MusicKit playback concepts from the session
SystemMusicPlayer
ApplicationMusicPlayer
// Both players:
// - set the queue with one or more items
// - add an item to play next
// - add an item to play later
// - report now playing information
// - handle remote commands
// ApplicationMusicPlayer also owns a separate queue:
// - insert items in the middle
// - remove previously added items
キーポイント:
SystemMusicPlayerリモコンシステムミュージックアプリ。- 使用
SystemMusicPlayerの場合、システムはミュージック アプリを現在再生中のアプリとして報告します。 ApplicationMusicPlayer現在のアプリに独立した再生キューを持たせます。- 使用
ApplicationMusicPlayer、システムはあなたのアプリを再生中のアプリとして報告します。 - 両方のプレーヤーが現在再生中の情報を報告し、ロック画面などのシステム メディア コントロールを処理します。
- 両方のプレーヤーがキューを設定し、次の曲を追加し、後で再生するように追加できます。
- のみ
ApplicationMusicPlayer中間位置の挿入や追加された項目の削除など、よりきめ細かいキュー制御を提供します。
7. サブスクリプションの割引: アプリ内にコンテキストに応じたサブスクリプションの入り口を表示します
(14:50) Apple Musicに登録していないユーザーは、アプリの音楽機能を使用できない場合があります。 MusicKit はアプリ内に定期購入のオファーを表示できます。このオファーは、特定の曲、アルバム、またはプレイリストに関連付けることができます。
(15:34) 例は、現在のアルバムの ID を書き込みますMusicSubscriptionOffer.Options.itemID、SwiftUI を使用しますmusicSubscriptionOfferモディファイア表示シート。
// 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
}
キーポイント:
musicSubscriptionユーザーの現在のサブスクリプション ステータスを保存します。isShowingOfferサブスクリプション割引シートを表示するかどうかを制御します。MusicSubscriptionOffer.Options()サブスクリプション オファー構成を作成します。offerOptions.itemID = album.idオファーを現在のアルバムにバインドします。Button("Show Subscription Offers", ...)サブスクリプション エントリを表示するボタンを提供します。.disabled(!(musicSubscription?.canBecomeSubscriber ?? false))このボタンは、ユーザーが購読者になれる場合にのみ有効になります。.musicSubscriptionOffer(isPresented: $isShowingOffer, options: offerOptions)SwiftUI シートをビューにアタッチします。showSubscriptionOffer()バンドルisShowingOfferに設定true、印象を引き起こします。
重要ポイント
1. 物理レコードをスキャンし、デジタル アルバムを開きます
- やるべきこと: CD またはレコードのコレクション管理機能を作成し、バーコードをスキャンして同じアルバムを Apple Music に表示します。
- 実行する価値がある理由: プレゼンテーションが表示されました
MusicCatalogResourceRequest<Album>によるとAlbum.upcクエリ プロセスを通じて、物理的なコレクションをデジタル再生に直接接続できます。 - 開始方法: まずカメラまたはビジョンを使用してバーコードを識別し、
detectedBarcode、次に使用しますMusicCatalogResourceRequest<Album>(matching: \Album.upc, equalTo: detectedBarcode)アルバムをリクエストし、最後にアルバムの詳細ページにプッシュします。
2. フィットネス アプリに独立した音楽キューを追加する
- 対処方法: トレーニング プランごとに異なる Apple Music アルバムまたはプレイリストを設定し、トレーニング開始時に独立した再生キューを開始します。
- 実行する価値がある理由: スピーチメモ
ApplicationMusicPlayer再生ステータスはシステムの音楽アプリから独立しており、フィットネス シナリオに適しています。 - 開始方法: トレーニングを開始する前に確認してください
musicSubscription?.canPlayCatalogContent、MusicKit を通じてトラックまたはプレイリストを見つけて、選択しますApplicationMusicPlayer再生キューを管理します。
3. サブスクリプション ステータスを使用してインターフェイスを駆動する
- やるべきこと: 再生ボタン、ライブラリ追加ボタン、購読ボタンをステートマシンに作成し、Apple Music 購読機能に自動的に切り替えます。
- 実行する価値がある理由:
MusicSubscription.subscriptionUpdatesサブスクリプションの変更は継続的に発生し、インターフェイスはユーザーのログイン、ログアウト、またはサブスクリプション ステータスの変更にリアルタイムで応答できます。 - 開始方法: SwiftUI ビューの場合
.task真ん中for awaitモニターMusicSubscription.subscriptionUpdates、使用canPlayCatalogContent再生ボタンを制御するには、次を使用しますcanBecomeSubscriberサブスクリプションのエントリを制御します。
4. Apple Music ジャンルブラウザを作成する
- 操作方法: 現在の国または地域で上位の音楽ジャンルを表示し、各ジャンルのアルバムまたは曲のリストを入力します。
- 実行する価値がある理由:
MusicDataRequest任意の Apple Music API URL にアクセスできます。Genre直接参加することもできますDecodableデコード中。 - 開始方法: を使用します
MusicDataRequest.currentCountryCode綴る/v1/catalog/{countryCode}/genres、合格MusicDataRequestデータをリクエストして使用するJSONDecoderデコードされて含まれる[Genre]応答構造。
5. コンテンツ ページに状況に応じたサブスクリプション オファーを表示する
- 内容: ユーザーがアルバムを開いたものの再生できない場合、「Apple Music に参加」ボタンを表示し、サブスクリプションのオファーでアルバムを強調表示します。
- 実行する価値がある理由:
MusicSubscriptionOffer.Options.itemID特定のアルバムをバインドでき、サブスクリプション エントリはユーザーが現在閲覧しているコンテンツに関連付けられます。 - 開始方法: 保存
album.id、構造MusicSubscriptionOffer.Options、ボタンを追加します.musicSubscriptionOffer(isPresented:options:)、そして使用しますcanBecomeSubscriberコントロールボタンの状態。
関連セッション
- Apple Music API を使用してカタログを探索する — Apple Music API のカタログ検索、提案、メタデータ リクエストについて引き続き詳しく説明します。
- ShazamKit を探索する — ShazamKit を使用して曲を識別し、音楽認識結果をアプリに統合する方法を学びます。
- SwiftUI の同時実行性を発見する — MusicKit の例を理解する
await、.taskSwiftUI 状態更新の基本。 - AsyncSequence について — さらに詳しく見る
for awaitパターン、理解MusicSubscription.subscriptionUpdatesこのタイプの非同期フロー。 - Swift での async/await について — MusicKit ネットワーク リクエストで使用されるマスター Swift 同時実行構文。
コメント
GitHub Issues · utterances