iOS 14 StoreKit - SKCloudServiceController 的 requestusertoken 未被正确调用

iOS 14 StoreKit - SKCloudServiceController's requestusertoken not being called properly

我正在尝试使用 Apple Music API 在 iOS 14 上播放歌曲。 我有开发者的token,我申请了访问用户apple music的权限

然而,当我调用 requestusertoken api 时,它的闭包永远不会被调用,所以显然我没有从请求中收到任何东西——甚至没有错误。这让我发疯。

这是我的代码。我做错了什么?

func getUserToken() -> String {
var userToken = String()

let lock = DispatchSemaphore(value: 0)

SKCloudServiceController().requestUserToken(forDeveloperToken: developerToken) { (receivedToken, error) in
    guard error == nil else { return }
    if let token = receivedToken {
        userToken = token
        lock.signal()
    }
}

lock.wait()
return userToken }

您是否从 developerToken 中删除了 Bearer

好的,所以我知道发生了什么事——DispatchSemaphore 在创建 之后被锁定——所以它永远不会执行该代码。一旦我将信号量值设置为 1 而不是 0,它就会开始执行——但是由于事件的顺序,我对其余代码产生了问题。

看起来您使用的教程可能与我在 Apple Music SDK 集成方面的教程相同——如果是这样的话,我基本上将代码调整为:

  1. 将用户令牌下载到局部变量,然后其他方法开始在它们的请求中引用它。
  2. 仅在getuserToken()方法中移除信号量锁
  3. 其余部分重新开始工作,无需更改任何其他 DispatchSemaphore 值。

我绝不是 DispatchSemaphore 的工作原理和 Apple Music 用户令牌最佳实践方面的专家,但我想至少让您知道为什么您 运行 和我在同一堵墙上——根本没有代码被执行。

我试过代码,有两个主要问题。

首先,DispatchSemaphore 使 return 行执行得太早。其次,由于最新的 iOS 14.3 问题,原始开发人员令牌无法使用。

所以,我首先删除了 DispatchSemaphore。

func getUserToken() {
    var userToken = String()
    
    SKCloudServiceController().requestUserToken(forDeveloperToken: developerToken) { (receivedToken, error) in
        guard error == nil else { return }
        
        if let token = receivedToken {
            userToken = token
            print(userToken)
        }
    }
}

然后在 repository 之后调整开发人员令牌。

现在,它正在正确打印用户令牌。希望对您有所帮助。

我想我们都陷入了同一个 tutorial。为了修复,我把它放在不同的线程上,因为锁阻塞了主线程,因此阻止了完成处理程序。

DispatchQueue.global(qos: .background).async {
   print(AppleMusicAPI().fetchStorefrontID())
}

如果是同一个教程,这会将 fetchStorefrontID() 和 getUserToken() 方法(由前者调用)放在后台线程上,并允许完成处理程序和 lock.signal()发生。

如果不是,那么这就足以回答:

DispatchQueue.global(qos: .background).async {
   getUserToken()
}