Swiftで音楽アプリを作っています。このアプリを使用すると、ユーザーはAppleミュージックアプリからAppleミュージックサブスクリプションを介して音楽を再生できます。ユーザーがAppleの音楽サブスクリプションを持っているかどうかを確認できます。
_SKCloudServiceController().requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in
guard err == nil else {
print("error in capability check is \(err!)")
return
}
if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) {
print("user has Apple Music subscription")
}
if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) {
print("user does not have subscription")
}
}
_
ただし:誰かが何らかの理由でApple音楽サブスクリプションを持っているが、Appleデバイスにダウンロードされた音楽アプリ。ユーザーが定期購入を持っているがデバイスは持っていない場合は、基本的にそのケースを、定期購入をまったく持っていないかのように扱います。つまり、Apple Music経由で音楽を再生できません。
だから、私はApple音楽がユーザーのデバイスにあるかどうかのチェックを追加する方法を探しに行きます。私はこの答えを見つけます: アプリがSwiftを使用してインストールされているかどうかを確認しますこのリソースを見つけるためのリソースApple MusicのURLスキーム と組み合わせて、ユーザーが両方Apple音楽サブスクリプションとの両方を持っているApple音楽アプリは、次の方法でデバイスにインストールされます。
_SKCloudServiceController()requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in
guard err == nil else {
print("error in capability check is \(err!)")
return
}
if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && UIApplication.shared.canOpenURL(URL(string: "music://")!) {
print("user has Apple Music subscription and has the Apple music app installed")
}
if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) || !UIApplication.shared.canOpenURL(URL(string: "music://")!) {
print("user does not have subscription or doesn't have Apple music installed")
}
}
_
問題は、デバイスからApple音楽を削除した後でも、最初のケース、つまり_user has Apple Music subscription and has the Apple music app installed
_を出力するケースがまだ呼び出されていることです。 _"music://"
_を_"musi://"
_に変更すると、2番目のケース、つまり_user does not have subscription or doesn't have Apple music installed
_を出力するケースが呼び出されるため、正しいURLスキームを持っていると思います。
AppleでURL(string: "music://")
を開こうとすると、UIApplication.shared.open(URL(string: "music://")!)
で音楽が削除され、次のアラートが表示されます。
では、デバイスがApple音楽を削除した後でもURL(string: "music://")
を開くことができると言っているのはなぜですか? URL
を開くことはできますが、結果は上記のアラートの提示にすぎませんか?これは、ユーザーがデバイスにApple Musicをインストールしていることを確認する正しい方法ですか?ユーザーがデバイスにApple音楽をインストールしていることを確認する方法さえありますか? AppleがユーザーにApple音楽アプリを削除するオプションを提供する場合、アプリがインストールされているかどうかを確認する機能も開発者に提供する必要があります。
私が得た最善の解決策は、もっと良いものがあると思いますが、MPMusicPlayer.prepareToPlay(completionHandler:)
を使用して、トラックを再生しようとしたときにエラーがないかどうかを確認することです。
_SKCloudServiceController().requestCapabilities { (capability:SKCloudServiceCapability, err:Error?) in
guard err == nil else {
print("error in capability check is \(err!)")
return
}
if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) {
print("user has Apple Music subscription")
MPMusicPlayerController.systemMusicPlayer.setQueue(with: ["1108845248"])
systemMusicPlayer.prepareToPlay { (error) in
if error != nil && error!.localizedDescription == "The operation couldn’t be completed. (MPCPlayerRequestErrorDomain error 1.)" {
//It would appear that the user does not have the Apple Music App installed
}
}
}
if capability.contains(SKCloudServiceCapability.musicCatalogSubscriptionEligible) {
print("user does not have subscription")
}
}
_
これがApple音楽をアプリ内でトラックの再生以外の目的で使用している人にどのように適用できるかはわかりませんが、これは、チェックを再生しようとしているときに間違いなくチェックとして機能するようです。そのエラーに遭遇したときはいつでも、Apple音楽サブスクリプションを持っているがアプリがインストールされていないことを個人に知らせるアラートを作成します。
それでも、ブール値のチェックを(if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && hasAppleMusicAppInstalled { //do something }
を介して)条件付きステートメントに統合できるようにするため、完了ハンドラーなしでチェックできるのは素晴らしいことです。
可能な解決策は次のとおりです。Apple Music APIを使用して開発者トークンをセットアップします(Apple Music REST endpoints)。次のStoreKit関数( Documentation )にリクエストを送信します。
requestUserToken(forDeveloperToken:completionHandler:)
開発者トークンが有効で、返されたユーザートークンの値がまだnil/nullの場合、デバイスユーザーはApple音楽サービスのサブスクライバーではありません。HTTPステータスコードで生成されるエラーは401(無許可)です。これでもエラーをチェックする必要がありますが、特定のトラックを試して再生する必要はありません(特に、チェック対象のコンテンツトラックIDが無効になるか変更された場合は、何らかの理由で)。
デバイスにサインインし、サブスクリプションはあるがミュージックアプリはダウンロードされていないアカウントの問題の場合:特定のコンテンツを再生しようとしたときにエラーを処理し、ユーザーに情報を提供するか、Appleエラーが発生した場合の代替手段としての音楽サブスクリプション。
幸いにもAppleは、デバイスにインストールされているアプリがURLのスキームを処理するように登録されていない場合、またはInfo.plistファイルでURLのスキームを宣言していない場合にfalseを返すメソッドを提供します。それ以外の場合、本当です。
func canOpenURL(_ url: URL) -> Bool
私はURLスキームを投稿しています
Open = music://
Open = musics://
Open = audio-player-event://
さらに使用するものをinfo.plistファイルに追加します。
この後、 'canOpenURL'を使用して詳細を確認しますApple docs
https://developer.Apple.com/documentation/uikit/uiapplication/1622952-canopenurl
はい、次の手順でほとんどのアプリケーションを確認できます。
func canOpenURL(_ url: URL) -> Bool
let url = URL(string: "music://")
UIApplication.shared.open(url!) { (result) in
if result {
// The URL was delivered successfully!
}
}