musickit について
MusicKit は、Apple プラットフォームの開発者向けに、Apple Music カタログの検索、アプリ内再生、サブスクリプション確認、再生情報の設定を解説する Swift スキルガイドです。認証、キュー、ロック画面表示、リモート操作も扱います。
主な機能
- 01Apple Music カタログの検索
- 02音楽の認証とサブスクリプション確認
- 03アプリ内再生とキューの管理
- 04再生中のトラック情報の公開
- 05リモート再生操作への対応
活用シーン
- 01アプリ内で曲やアルバムを検索
- 02サブスクリプションに応じたカタログ再生
- 03再生キューの作成と更新
- 04ロック画面での曲情報表示と操作対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dpearson2699/ swift-ios-skills --skill musickitインストール後、Claude Code で/musickitを入力して読み込まれたか確認します。
同梱ファイルevals/evals.jsonreferences/musickit-patterns.md
詳細
MusicKit
Apple Music カタログを検索し、ApplicationMusicPlayer で再生を管理し、サブスクリプションを確認し、MPNowPlayingInfoCenter
と MPRemoteCommandCenter を介して「再生中」のメタデータを公開します。
目次
- セットアップ
- ワークフロー
- 認証
- カタログ検索
- サブスクリプションの確認
- ApplicationMusicPlayer での再生
- キューの管理
- 再生中の情報
- リモートコマンドセンター
- よくある間違い
- 確認チェックリスト
- 参考資料
ワークフロー
- コードをデバッグする前に、MusicKit App Service、バンドル識別子、目的を説明する文字列、バックグラウンドオーディオモードを確認します。
- 認証をリクエストし、認証済みでないすべての状態を明示的にモデル化します。
- 再生をキューに追加する前に、カタログコンテンツを検索または読み込み、
MusicSubscription.currentを確認します。 - アプリにスコープされた再生には
ApplicationMusicPlayerを選び、アプリがそれらの領域を所有する場合にのみ、「再生中」の情報とリモートコマンドを設定します。 - 認証済み、拒否済み、未サブスクリプション、オフライン、キュー追加失敗、中断、トラック変更の各状態をテストします。最小の失敗レイヤーを修正し、テスト用状態を元に戻して、同じ状態の組み合わせを再実行します。
セットアップ
プロジェクトの設定
- MusicKit が開発者トークンを自動生成できるよう、Apple Developer ポータルでアプリの明示的なバンドル ID に対して MusicKit App Service を有効にします。
- アプリがユーザーのメディアライブラリにアクセスする理由を説明する
NSAppleMusicUsageDescriptionを Info.plist に追加します。 - バックグラウンド再生を行うには、
UIBackgroundModesにaudioバックグラウンドモードを追加します。
インポート
import MusicKit // Catalog, auth, playback
import MediaPlayer // MPRemoteCommandCenter, MPNowPlayingInfoCenter
認証
ユーザーのミュージックデータへのアクセスや Apple Music コンテンツの再生を行う前に、許可をリクエストします。必要に応じて request() が Apple の同意ダイアログを表示します。プロンプトを表示せずに現在の設定を読み取るには、currentStatus を使用します。
func requestMusicAccess() async -> MusicAuthorization.Status {
let status = await MusicAuthorization.request()
switch status {
case .authorized:
// Full access to MusicKit APIs
break
case .denied, .restricted:
// Show guidance to enable in Settings
break
case .notDetermined:
break
@unknown default:
break
}
return status
}
// Check current status without prompting
let current = MusicAuthorization.currentStatus
カタログ検索
MusicCatalogSearchRequest を使用して Apple Music カタログを検索します。カタログ検索では Apple Music のリソースを取得できますが、サブスクリプション対象のカタログコンテンツの再生は、引き続き MusicSubscription.current.canPlayCatalogContent で制御する必要があります。
func searchCatalog(term: String) async throws -> MusicItemCollection<Song> {
var request = MusicCatalogSearchRequest(term: term, types: [Song.self])
request.limit = 25
let response = try await request.response()
return response.songs
}
検索結果の表示
for song in songs {
print("\(song.title) by \(song.artistName)")
if let artwork = song.artwork {
let url = artwork.url(width: 300, height: 300)
// Load artwork from url
}
}
サブスクリプションの確認
再生機能を提供する前に、ユーザーが有効な Apple Music サブスクリプションに登録しているか確認します。
func checkSubscription() async throws -> Bool {
let subscription = try await MusicSubscription.current
return subscription.canPlayCatalogContent
}
// Observe subscription changes
func observeSubscription() async {
for await subscription in MusicSubscription.subscriptionUpdates {
if subscription.canPlayCatalogContent {
// Enable full playback UI
} else {
// Show subscription offer
}
}
}
Apple Music の提供
ユーザーがサブスクリプションに登録していない場合は、Apple Music のサブスクリプション案内シートを表示します。まず canBecomeSubscriber を確認し、シートにコンテキストに応じたメタデータや読み込みエラーの処理が必要な場合は、MusicSubscriptionOffer.Options または onLoadCompletion を渡します。
import MusicKit
import SwiftUI
struct MusicOfferView: View {
@State private var showOffer = false
var body: some View {
Button("Subscribe to Apple Music") {
Task {
let subscription = try? await MusicSubscription.current
showOffer = subscription?.canBecomeSubscriber == true
}
}
.musicSubscriptionOffer(
isPresented: $showOffer,
options: .default,
onLoadCompletion: { error in
if let error {
// Surface loading errors in app UI or diagnostics.
print(error)
}
}
)
}
}
ApplicationMusicPlayer での再生
ApplicationMusicPlayer は Music アプリとは独立して Apple Music コンテンツを再生します。システムプレーヤーの状態には影響しません。
let player = ApplicationMusicPlayer.shared
func playSong(_ song: Song) async throws {
player.queue = [song]
try await player.play()
}
func pause() {
player.pause()
}
func skipToNext() async throws {
try await player.skipToNextEntry()
}
再生状態の監視
func observePlayback() {
// player.state is an @Observable property
let state = player.state
switch state.playbackStatus {
case .playing:
break
case .paused:
break
case .stopped, .interrupted, .seekingForward, .seekingBackward:
break
@unknown default:
break
}
}
キューの管理
ApplicationMusicPlayer.Queue を使用して再生キューを構築、操作します。
// Initialize with multiple items
func playAlbum(_ album: Album) async throws {
player.queue = [album]
try await player.play()
}
// Append songs to the existing queue
func appendToQueue(_ songs: [Song]) async throws {
try await player.queue.insert(songs, position: .tail)
}
// Insert song to play next
func playNext(_ song: Song) async throws {
try await player.queue.insert(song, position: .afterCurrentEntry)
}
再生中の情報
MPNowPlayingInfoCenter を更新して、ロック画面、コントロールセンター、CarPlay に現在のトラックのメタデータを表示します。これはカスタムオーディオ(MusicKit 以外のソース)を再生する場合に不可欠です。Apple Music コンテンツについては、ApplicationMusicPlayer が自動的に処理します。
import MediaPlayer
func updateNowPlaying(title: String, artist: String, duration: TimeInterval, elapsed: TimeInterval) {
var info = [String: Any]()
info[MPMediaItemPropertyTitle] = title
info[MPMediaItemPropertyArtist] = artist
info[MPMediaItemPropertyPlaybackDuration] = duration
info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = elapsed
info[MPNowPlayingInfoPropertyPlaybackRate] = 1.0
info[MPNowPlayingInfoPropertyMediaType] = MPNowPlayingInfoMediaType.audio.rawValue
MPNowPlayingInfoCenter.default().nowPlayingInfo = info
}
func clearNowPlaying() {
MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
}
アートワークの追加
func setArtwork(_ image: UIImage) {
let artwork = MPMediaItemArtwork(boundsSize: image.size) { _ in image }
var info = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:]
info[MPMediaItemPropertyArtwork] = artwork
MPNowPlayingInfoCenter.default().nowPlayingInfo = info
}
リモートコマンドセンター
MPRemoteCommandCenter のハンドラーを登録し、ロック画面のコントロール、AirPods のタップ操作、CarPlay のボタンに応答します。
func setupRemoteCommands() {
let center = MPRemoteCommandCenter.shared()
center.playCommand.addTarget { _ in
resumePlayback()
return .success
}
center.pauseCommand.addTarget { _ in
pausePlayback()
return .success
}
center.nextTrackCommand.addTarget { _ in
skipToNext()
return .success
}
center.previousTrackCommand.addTarget { _ in
skipToPrevious()
return .success
}
// Disable commands you do not support
center.seekForwardCommand.isEnabled = false
center.seekBackwardCommand.isEnabled = false
}
スクラブ操作のサポート
func enableScrubbing() {
let center = MPRemoteCommandCenter.shared()
center.changePlaybackPositionCommand.addTarget { event in
guard let positionEvent = event as? MPChangePlaybackPositionCommandEvent else {
return .commandFailed
}
seek(to: positionEvent.positionTime)
return .success
}
}
よくある間違い
| 間違い | 修正方法 |
|---|---|
| App Service と目的を示す文字列を設定する前に、認証のデバッグを行う | まずサービス、バンドル ID、NSAppleMusicUsageDescription を確認します。 |
| サブスクリプションの確認をせずにカタログのコンテンツをキューに追加する | canPlayCatalogContent を確認し、canBecomeSubscriber が true の場合にのみサブスクリプションを案内します。 |
アプリが所有する再生に SystemMusicPlayer を使う | ApplicationMusicPlayer を使います。システムプレーヤーを使うと、Music アプリのグローバルキューが変更されます。 |
| 「再生中」メタデータを一度だけ公開する | トラック、再生時間、再生レート、経過時間が変わるたびに更新します。 |
| サポートされていないリモートコマンドを登録する | 無効にします。サポート対象のハンドラーは、処理を実行して .success を返す必要があります。 |
レビューチェックリスト
- アプリの明示的なバンドル ID に対して MusicKit App Service が有効になっている
-
NSAppleMusicUsageDescriptionが Info.plist に追加されている - MusicKit にアクセスする前に
MusicAuthorization.request()が呼び出されている - カタログ再生を試みる前にサブスクリプションを確認している
- サブスクリプションの案内を表示する前に
canBecomeSubscriberを確認している - ライブラリに書き込む前に
hasCloudLibraryEnabledを確認している - アプリ内の再生には
SystemMusicPlayerではなくApplicationMusicPlayerを使用している - 音楽をバックグラウンドで再生する場合、バックグラウンドオーディオモードが有効になっている
- カスタムオーディオの場合、トラックが変わるたびに「再生中」情報を更新している
- サポート対象のコマンドに対して、リモートコマンドハンドラーが
.successを返している - サポートされていないリモートコマンドが
isEnabled = falseで無効になっている - ロック画面に表示するアートワークが「再生中」情報に設定されている
- スクラバーの精度を保つため、再生経過時間が定期的に更新されている
- ユーザーが Apple Music サブスクリプションに加入していない場合、サブスクリプションを案内している
参考資料
- 拡張パターン(SwiftUI との統合、ジャンルの閲覧、プレイリスト管理):references/musickit-patterns.md
- MusicKit フレームワーク
- Apple Music API の自動デベロッパートークン生成の使用
- MusicAuthorization
- ApplicationMusicPlayer
- MusicCatalogSearchRequest
- MusicSubscription
- canPlayCatalogContent
- canBecomeSubscriber
- hasCloudLibraryEnabled
- MusicCatalogChartsRequest initializer
- musicSubscriptionOffer(isPresented:options:onLoadCompletion:)
- MPRemoteCommandCenter
- MPNowPlayingInfoCenter
- NSAppleMusicUsageDescription