Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate,
SPTAppRemoteDelegate {
static private let kAccessTokenKey = "access-token-key"
private let redirectUri = URL(string:"comspotifytestsdk://")!
private let clientIdentifier = "089d841ccc194c10a77afad9e1c11d54"
var window: UIWindow?
lazy var appRemote: SPTAppRemote = {
let configuration = SPTConfiguration(clientID: self.clientIdentifier, redirectURL: self.redirectUri)
let appRemote = SPTAppRemote(configuration: configuration, logLevel: .debug)
appRemote.connectionParameters.accessToken = self.accessToken
appRemote.delegate = self
return appRemote
}()
var accessToken = UserDefaults.standard.string(forKey: kAccessTokenKey) {
didSet {
let defaults = UserDefaults.standard
defaults.set(accessToken, forKey: SceneDelegate.kAccessTokenKey)
}
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else {
return
}
let parameters = appRemote.authorizationParameters(from: url);
if let access_token = parameters?[SPTAppRemoteAccessTokenKey] {
appRemote.connectionParameters.accessToken = access_token
self.accessToken = access_token
} else if let _ = parameters?[SPTAppRemoteErrorDescriptionKey] {
// Show the error
}
}
func sceneDidBecomeActive(_ scene: UIScene) {
connect();
}
func sceneWillResignActive(_ scene: UIScene) {
playerViewController.appRemoteDisconnect()
appRemote.disconnect()
}
func connect() {
playerViewController.appRemoteConnecting()
appRemote.connect()
}
// MARK: AppRemoteDelegate
func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote) {
self.appRemote = appRemote
playerViewController.appRemoteConnected()
}
func appRemote(_ appRemote: SPTAppRemote, didFailConnectionAttemptWithError error: Error?) {
print("didFailConnectionAttemptWithError")
playerViewController.appRemoteDisconnect()
}
func appRemote(_ appRemote: SPTAppRemote, didDisconnectWithError error: Error?) {
print("didDisconnectWithError")
playerViewController.appRemoteDisconnect()
}
var playerViewController: ViewController {
get {
let navController = self.window?.rootViewController?.children[0] as! UINavigationController
return navController.topViewController as! ViewController
}
}
}
@rnagda

This comment has been minimized.

Copy link

rnagda commented Jan 20, 2020

From a previous thread I saw that I need to use UIScene to get this to work on iOS13. I am using this code for my SceneDelegate but seem to get the error that ViewController has no appRemoteDisconnect method. If I comment those lines out, it fails Spotify authentication (goes into Spotify gets an X and returns to my app). Could you try to help?

@bhartyrs

This comment has been minimized.

Copy link

bhartyrs commented Jan 29, 2020

From a previous thread I saw that I need to use UIScene to get this to work on iOS13. I am using this code for my SceneDelegate but seem to get the error that ViewController has no appRemoteDisconnect method. If I comment those lines out, it fails Spotify authentication (goes into Spotify gets an X and returns to my app). Could you try to help?

I am having the same issue... Any help?

@jstn455

This comment has been minimized.

Copy link

jstn455 commented Feb 22, 2020

How do I call sessionManager.application(app, open: url, options: options) from SceneDelegate?

@sean-williams24

This comment has been minimized.

Copy link

sean-williams24 commented Feb 24, 2020

Hey. I'm trying to setup my app using the iOS quick start guide, implementing the methods in my view controller and not the App Delegate or scene Delegate: when calling the appRemote.authorizeAndPlayURI(self.playURI) method, it switches to Spotify, attempts to authorise - but gives me a big fat X every time and then that's that.... is someone able to let me know what I might be missing please?

@bhartyrs

This comment has been minimized.

Copy link

bhartyrs commented Feb 24, 2020

Hey. I'm trying to setup my app using the iOS quick start guide, implementing the methods in my view controller and not the App Delegate or scene Delegate: when calling the appRemote.authorizeAndPlayURI(self.playURI) method, it switches to Spotify, attempts to authorise - but gives me a big fat X every time and then that's that.... is someone able to let me know what I might be missing please?

You might want to make sure that your client ID, URL types, and bundle IDs all match. That is what failed it for me. Client ID

@sean-williams24

This comment has been minimized.

Copy link

sean-williams24 commented Feb 26, 2020

They are all the same just double checked. The play URI might have been what's was deucing it up, I changed to an empty string - it now switches to Spotify, authorises successfully and plays my last playing song. But, that's it, it won't switch back to my app with a lovely, much needed access token. 😩

@bhartyrs

This comment has been minimized.

Copy link

bhartyrs commented Feb 26, 2020

Awesome. I am also stuck with you at the same point. No token and switchback.......

@Bradysm

This comment has been minimized.

Copy link

Bradysm commented Mar 21, 2020

If you're using SwiftUI, move the connect function to the line windowScene is instantiated. This will ensure that connect is only called once and will make it so the applications do not keep switchback

@Samuel-IH

This comment has been minimized.

Copy link

Samuel-IH commented Apr 27, 2020

I had a similar problem.
Calling appRemote.connect() would open Spotify but would not return a valid access token.
I was able to get Spotify to generate an access token by using appRemote.authorizeAndPlayURI("") however I still had to call appRemote.connect() afterward to connect the session.

Lastly, I removed appRemote.disconnect() from sceneWillResignActive(...) as this was causing an endless loop where connecting swaps over to Spotify, and swapping over causes us to disconnect... and then swapping back tries to reconnect.. you get the point.

I'll have to dig into the API a bit more, and maybe make a gist. But for now, here's the corrected working code:

    func sceneWillResignActive(_ scene: UIScene) {
        //Stop the never-ending loop!
        //"connecting" will cause us to call this very function when it changes over to Spotify, therefore we need a better way to decide when to disconnect
        //appRemote.disconnect()
    }

    func connect() {
        //attempt a connection
        appRemote.connect()
        
        //if it failed, aka we dont have a valid access token
        if (!appRemote.isConnected) {//ultimately access token issues aren't the only thing that will cause this the connection to fail
            //make spotify authorize and create an access token for us
            appRemote.authorizeAndPlayURI("")
        }
    }

My best guess is that perhaps in a previous version of the API, calling connect() didn't switch over to Spotify.
¯\_(ツ)_/¯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.