SPTSessionManager 未初始化或失败
当我尝试调用 sessionManager.initialize()
时,既没有 func sessionManager(manager: SPTSessionManager, didFailWith error: Error)
也没有 func sessionManager(manager: SPTSessionManager, didInitiate session: SPTSession)
被调用.
When I try to call sessionManager.initialize()
neither func sessionManager(manager: SPTSessionManager, didFailWith error: Error)
nor func sessionManager(manager: SPTSessionManager, didInitiate session: SPTSession)
are called.
我有一个在 AWS 上运行的 nodeJS 服务器用于令牌访问和刷新,我还尝试运行本地 Ruby 服务器来获取令牌.无论如何,调用 initialize()
什么都不做.它确实失败或成功,并且没有任何输出到控制台.我试过运行 XCode 调试器,似乎程序只是跳过了 initialize
.这是我删除了不相关/私有部分的完整 ViewController.swift 文件:
I have a nodeJS server running on AWS for token access and refresh and I have also tried running a local Ruby server to get the token. No matter what, calling initialize()
does nothing. It does fail or succeed and nothing is output to console. I have tried running the XCode debugger and it seems as if the program just skips past initialize
. Here is my complete ViewController.swift file with the unrelated/private parts deleted:
import UIKit
import Firebase
class LobbyAdminViewController: UIViewController, SPTSessionManagerDelegate, SPTAppRemoteDelegate, SPTAppRemotePlayerStateDelegate {
fileprivate let SpotifyClientID = "client_id"
fileprivate let SpotifyRedirectURI = URL(string: "redirect_url")!
fileprivate var lastPlayerState: SPTAppRemotePlayerState?
var refreshAPI = "token_server/refresh_token"
var tokenAPI = "token_server/token"
lazy var configuration: SPTConfiguration = {
let configuration = SPTConfiguration(clientID: SpotifyClientID, redirectURL: SpotifyRedirectURI)
configuration.playURI = ""
configuration.tokenSwapURL = URL(string: tokenAPI)
configuration.tokenRefreshURL = URL(string: refreshAPI)
return configuration
}()
lazy var sessionManager: SPTSessionManager = {
let manager = SPTSessionManager(configuration: configuration, delegate: self)
return manager
}()
lazy var appRemote: SPTAppRemote = {
let appRemote = SPTAppRemote(configuration: configuration, logLevel: .debug)
appRemote.delegate = self
return appRemote
}()
override func viewDidLoad() {
super.viewDidLoad()
let random = Int(arc4random_uniform(900000) + 100000)
lobbyCode = String(random)
lobbyCodeLabel.text = lobbyCode
var ref: DatabaseReference!
ref = Database.database().reference()
ref.child(lobbyCode).child("null").setValue("null")
let scope: SPTScope = [.appRemoteControl]
if #available(iOS 11, *) {
print("ios 11+")
sessionManager.initiateSession(with: scope, options: .clientOnly)
} else {
print("ios 11-")
sessionManager.initiateSession(with: scope, options: .clientOnly, presenting: self)
}
}
func update(playerState: SPTAppRemotePlayerState) {
print("Updating")
lastPlayerState = playerState
currentSongLabel.text = playerState.track.name
currentArtistLabel.text = playerState.track.artist.name
if playerState.isPaused {
pausePlayButton.setBackgroundImage(UIImage(named: "play"), for: .normal)
} else {
pausePlayButton.setBackgroundImage(UIImage(named: "pause"), for: .normal)
}
}
func fetchPlayerState() {
print("Getting player state")
appRemote.playerAPI?.getPlayerState({ [weak self] (playerState, error) in
if let error = error {
print("Error getting player state:" + error.localizedDescription)
} else if let playerState = playerState as? SPTAppRemotePlayerState {
self?.update(playerState: playerState)
}
})
}
@IBAction func onTap_pausePlayButton(_ sender: UIButton) {
print("tapped")
if let lastPlayerState = lastPlayerState, lastPlayerState.isPaused {
appRemote.playerAPI?.resume(nil)
print("Resuming")
} else {
appRemote.playerAPI?.pause(nil)
print("Pausing")
}
}
func sessionManager(manager: SPTSessionManager, didFailWith error: Error) {
print("Bad init")
print(error.localizedDescription)
}
func sessionManager(manager: SPTSessionManager, didRenew session: SPTSession) {
print("Renewed")
}
func sessionManager(manager: SPTSessionManager, didInitiate session: SPTSession) {
print("Trying to connect")
appRemote.connectionParameters.accessToken = session.accessToken
print(session.accessToken)
appRemote.connect()
}
// MARK: - SPTAppRemoteDelegate
func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote) {
print("App Remote Connected")
appRemote.playerAPI?.delegate = self
appRemote.playerAPI?.subscribe(toPlayerState: { (success, error) in
if let error = error {
print("Error subscribing to player state:" + error.localizedDescription)
}
})
fetchPlayerState()
}
func appRemote(_ appRemote: SPTAppRemote, didDisconnectWithError error: Error?) {
lastPlayerState = nil
print("Error connecting to app remote")
}
func appRemote(_ appRemote: SPTAppRemote, didFailConnectionAttemptWithError error: Error?) {
lastPlayerState = nil
print("Another error connectiong to app remote")
}
// MARK: - SPTAppRemotePlayerAPIDelegate
func playerStateDidChange(_ playerState: SPTAppRemotePlayerState) {
print("Player state changed")
update(playerState: playerState)
}
// MARK: - Private Helpers
fileprivate func presentAlertController(title: String, message: String, buttonTitle: String) {
let controller = UIAlertController(title: title, message: message, preferredStyle: .alert)
let action = UIAlertAction(title: buttonTitle, style: .default, handler: nil)
controller.addAction(action)
present(controller, animated: true)
}
}
唯一触发的 print()
语句是 viewDidLoad()
中的ios 11"我已经在互联网上搜索了任何有同样问题的人,结果都是空的.我能想到的唯一可能导致此问题的是 iOS 13 的已知运行时问题.此错误:
The only print()
statement that fires is "ios 11" in viewDidLoad()
I have scoured the internet for anyone with the same issue and have come up empty.
The only thing I can think of that could be causing this issue is a known runtime issue with iOS 13. This error:
无法结束BackgroundTask:不存在标识符为8 (0x8) 的后台任务,或者它可能已经结束.中断 UIApplicationEndBackgroundTaskError() 进行调试.
每次将应用程序发送到后台时触发(即当应用程序重定向到 Spotify 进行身份验证时).但是,即使 XCode 中的空白应用程序也存在此问题,并且不会停止执行.
fires every time the app is sent to the background (ie when the app redirects to spotify to authenticate). However, this issue exists with even a blank app in XCode and does not halt execution.
我现在才明白.在场景委托类中,您必须实现
I just figured that out now. In the scene delegate class you have to implement the
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
}
方法,您必须访问 LobbyAdminViewController 中的 sessionManager 并创建它的实例并将这些代码行添加到方法中
method and you have to access the sessionManager that you have in your LobbyAdminViewController and create an instance of it and add these lines of code into the method
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
print("Opened url")
guard let url = URLContexts.first?.url else {
return
}
lobbyAdminVC.sessionManager.application(UIApplication.shared, open: url, options: [:])
}
执行此操作后,应用程序远程连接并打印了所有打印语句并表示应用程序远程已连接.
After doing this, the app remote connected and all the print statements printed and said app remote was connected.