ios-sdk icon indicating copy to clipboard operation
ios-sdk copied to clipboard

Authorization does not work properly in Scene Delegate

Open harmankang opened this issue 4 years ago • 5 comments

I use Scene Delegate in my app, which means the AppDelegate method application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) does not get called.

So as recommended in #138, I used the openURLContexts delegate method to retrieve the URL:

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 error_description = parameters?[SPTAppRemoteErrorDescriptionKey] {
    // Show the error
  }
}

A quick side note, I ran into the issue where neither if condition above was true. So I had to retrieve the token like this:

if let access_token = parameters?["code"] {
  appRemote.connectionParameters.accessToken = access_token
}

Upon calling initiateSession, retrieving the token from the Spotify app, and returning to my application, I kept seeing the following error (as reported in #125):

AppRemote: Failed to establish a sesssion with error: Error Domain=com.spotify.app-remote.wamp-client Code=-1001 "wamp.error.not_authorized" UserInfo={details={
message = "Token not valid.";
}, NSLocalizedFailureReason=wamp.error.not_authorized}

To double check, I logged the token, and did a manual post request to my server's /swap endpoint, and the response returned the expected results (e.g. access code, refresh token, etc).

My Workaround

I have found this solves my problems:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
  guard let url = URLContexts.first?.url else {
    return
  }
  
  SpotifyClient.sessionManager.application(UIApplication.shared, open: url, options: [:])
}

The openURLContexts doesn't pass compatible options, so I just passed an empty dictionary and that did the trick. Note that this is exactly the same solution as needed in the App Delegate, except you have to provide the UIApplication and options values.

harmankang avatar Mar 31 '20 23:03 harmankang

I've reached the same problem, thanks! It's a shame that Spotify keeps us like this

olmedocr avatar Apr 08 '20 08:04 olmedocr

I am having this problem but couldn't get the fix to work. My url = {}. What should it be?

hethcox avatar May 14 '20 01:05 hethcox

@hethcox

It needs to be a URL, which you can unwrap from the URLContexts parameter like I've done in my original post.

harmankang avatar May 14 '20 02:05 harmankang

Thanks for the reply. I'm running your code as presented. It passes the guard check because url equal to {}. I assume SpotifyClient is the object holding your sessionmanager, right?

hethcox avatar May 14 '20 14:05 hethcox

Yes that’s correct.

The URL shouldn’t be empty. I’d suggest filing a new issue.

harmankang avatar May 14 '20 17:05 harmankang