如何检查用户设备上是否安装了Apple Music?


9

我正在快速制作音乐应用。该应用程序允许用户通过其Apple Music应用程序通过其Apple Music订阅播放音乐。我可以通过以下方式检查用户是否有Apple Music订阅:

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 Music,但没有在设备上下载Apple Music应用。如果用户拥有订阅但没有设备,那么我想实质上将这种情况视为他们根本没有订阅,即我们无法通过Apple Music播放音乐。

因此,我一直在寻找添加检查Apple Music是否在用户设备上的方法。我找到了这个答案:检查是否使用Swift结合此资源安装了应用程序以查找Apple Music的url方案,并得出结论,我可以通过以下方式检查用户是否同时在其设备上安装了Apple Music订阅 Apple Music应用程序:

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 Music,第一种情况(即打印的user has Apple Music subscription and has the apple music app installed情况)仍然被调用。我相信我有正确的网址方案,因为更改"music://""musi://",对于第二种情况,即一个打印user does not have subscription or doesn't have apple music installed被调用。

尝试打开URL(string: "music://")通过删除的Apple Music时UIApplication.shared.open(URL(string: "music://")!),我收到以下警告:

在此处输入图片说明

那么,为什么该设备说URL(string: "music://")即使删除Apple Music后也可以打开?是否URL可以打开,但结果只是上述警报的提示?这是确认用户设备上已安装Apple Music的正确方法吗?甚至还可以确认用户在其设备上安装了Apple Music吗?如果Apple为用户提供了删除Apple Music应用程序的选项,则他们还应该使开发人员能够检查该应用程序是否已安装。


我本人从未与Apple Music一起工作过,但我相信Apple会以一种特殊的方式对待这个url方案,因为它是他们自己的产品,因此,每当您点击该url方案时,他们最好向用户建议下载该应用程序,而不是返回假。您是否尝试确定有效的网址方案,该方案实际上会在Apple Music中打开真实专辑或播放真实歌曲?例如:URL(string: "music://trackID=3214534")。可能会以通常的方式处理此显式url方案,但不会触发app restore警报。
Starsky,

我已经尝试了一些使用有效的Apple音乐曲目和艺术家编号可能似乎并不深层链接与苹果音乐网址:URL(string: "music://trackId=1377813289")!URL(string: "music://track=1377813289")URL(string: "music://artist=562555")!URL(string: "music://artistId=562555")!。我能够进行深度链接的唯一方法是通过,例如URL(string: "https://music.apple.com/us/artist/562555")!,但这显然无济于事,因为这是HTTP。
大卫·肖邦

您是否在LSApplicationQueriesSchemes的info.plist中将“ music://”列入白名单?如果不是,则canOpenUrl应该会发生错误行为。
卡西克·拉梅什

1
不幸的是,在我的info.plist中将该方案列入白名单根本不会改变其行为。我的问题是,即使Apple Music应用被删除,它也一直在UIApplication.shared.canOpenURL(URL(string: "music://")!)返回truefalse删除应用程序后,我需要它返回。将网址方案列入白名单无法解决此问题(我尝试了)。
大卫·肖邦

您是否为此找到了更好的解决方案?
Martin Mlostek '19

Answers:


3

尽管我希望那里有更好的解决方案,但我得到的最好的解决方案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 Music播放曲目以外的任何内容的人,但是当您要演奏支票时,这似乎绝对可以用作支票。每当遇到该错误时,我都会简单地创建一个警报,告诉个人他们已订阅Apple Music,但未安装该应用程序。

尽管如此,如果没有一些完成处理程序就可以进行检查将是一件很棒的事,因为这样可以将布尔检查集成到条件语句中(通过if capability.contains(SKCloudServiceCapability.musicCatalogPlayback) && hasAppleMusicAppInstalled { //do something })。


好的,此解决方案通过检查错误来起作用,但是有点笨拙,需要在完成处理程序中执行以下代码。最好有一种简单的检查方法,不管它是否是MusicKit框架的一部分,是否已安装应用程序本身。
大卫·肖邦

但是是的,这个答案是一种解决方法,可以在准备播放曲目时利用错误。开发人员可能需要知道是否安装了Apple Music而没有播放曲目。
大卫·肖邦

1
这仍然是您找到的最佳解决方案吗?
Martin Mlostek

不幸的是,是的
大卫·肖邦

0

幸运的是,Apple为您提供了一种方法,如果未注册设备上安装的任何应用程序来处理URL的方案,或者尚未在Info.plist文件中声明URL的方案,则该方法返回false。否则,是真的。

func canOpenURL(_ url: URL) -> Bool

在我发布网址方案之后

Open = music://
Open = musics://
Open = audio-player-event://

将您将进一步使用的文件添加到info.plist文件中。

此后,使用“ canOpenURL”检查更多信息,请检查Apple文档

https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl


Apple Music的url方案true通过时总是返回canOpenUrl。这是我要解决的主要问题。
大卫·肖邦

您是否在LSApplicationQueriesSchemes中指定了“音乐应用”?
Zeeshan Ahmed

再次检查答案,我已经更新了。
Zeeshan Ahmed

Per Karthick Ramesh的评论,我以前曾尝试将URL方案列入白名单,而没有改变行为
David Chopin

0

一种可能的解决方案是执行以下操作:通过Apple Music API设置开发者令牌(已使用,因此您可以查询Apple Music REST端点)。向以下StoreKit函数(文档)提交请求:

requestUserToken(forDeveloperToken:completionHandler:)

如果您的开发人员令牌有效,并且返回的用户令牌值仍为nil / null,则设备用户不是Apple Music服务的订户。HTTP状态代码生成的错误是401(未授权)。这仍然需要您检查错误,但是不需要尝试播放特定的曲目(特别是由于某些原因,如果您检查的内容曲目ID无效或已更改)。

对于已登录设备且已订阅但未下载音乐应用程序的帐户的问题:尝试播放特定内容时处理错误,并向用户提供信息或使用不需要Apple Music订阅的内容作为替代当发生错误时。


1
是的,所以我已经知道如何检查用户是否有订阅。上面提供的我的答案解决了实际的错误处理。我正在寻找的解决方案严格来说是,您是否可以无需尝试播放曲目就能知道用户是否已将Apple Music应用安装到设备上。
大卫·肖邦

0

是的,我们可以按照以下步骤检查大多数应用程序:

  1. 对要打开的特定应用程序使用深层URLURL方案,然后将其添加到 info.plist
  2. 使用相同的URL并调用此方法
    func canOpenURL(_ url: URL) -> Bool
    let url = URL(string: "music://")

    UIApplication.shared.open(url!) { (result) in
       if result {
          // The URL was delivered successfully!
       }
    }

这不是问题,概述的问题UIApplication.shared.canOpenUrl(URL(string: “music://”)!)总是返回true,即使未安装该应用程序也是如此。
大卫·肖邦
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.