Open Sapta14 opened 6 years ago
@Sapta14 can you provide some more information so we can try and debug?
Spotify App Version: iOS Device & Version: Xcode Version:
1) Does the NowPlaying sample app work for you?
2) I assume you are setting the returned token on the appRemote's connection params like this?
3) Do other commands work?
4) What's the URI you are trying to play? Have you tried albums or playlists too? Where are you getting the URI from?
@jackfreeman here are the informations you asked for Spotify App Version: 8.4.71 (latest as per AppStore) iOS Device & Version: iPhone 6, 11.0.3 Xcode Version: 9.4.1
Does the NowPlaying sample app work for you? sample app working, started playing song on Spotify app while initiating.
I assume you are setting the returned token on the appRemote's connection params like this? Yes, here is my code
func sessionManager(manager: SPTSessionManager, didInitiate session: SPTSession) {
appRemoteObj.connectionParameters.accessToken = session.accessToken
appRemoteObj.connect()
}
Do other commands work? Since app disconnected, appRemote.playerAPI returns nil. So unable to check other functionalities.
What's the URI you are trying to play? Have you tried albums or playlists too? Where are you getting the URI from? URI :: spotify:track:3PURovRKyJaBmgzPfmMJ4O This track belongs to the playlist "Texas Music Now" (featured playlists) Fetching the playlists from web API "https://api.spotify.com/v1/browse/featured-playlists"
One more scenario I wants to share with you that, if I use this API
appRemoteObj.authorizeAndPlayURI(uri)
song started playing each time.
Thanks in advance.
@Sapta14 Do you get the App Remote delegate callback for a successful connection after calling connect()
?
func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote)
Since it looks like you are using the SPTSessionManager
for auth and attempting to use App Remote, are you also setting playURI
on SPTConfiguration
to either an empty string or a specific URI? See here
For App Remote to connect the Spotify app must be alive in the background. This requires the Spotify app to play music. authorizeAndPlayURI
will trigger playback as it assumes that by using this API you are trying to connect App Remote. SPTSessionManager
can be used with and without App Remote so if you intend to use it with App Remote you must set playURI
on SPTConfiguration
to initiate playback after auth. You also have to request the app-remote-control
scope.
If your intention is to auth the user, pull info from the Web API, and then start playback I recommend the following approach:
1) Auth the user using SPTSessionManager
with app-remote-control
scope (and any other scopes you need)
2)
Option 1 - Using SPTSessionManager
- Once you have the uri to play set it on SPTConfiguration
and call initiateSession
again. This will start playback in Spotify and allow you to connect with App Remote. After App Remote is connected you can then use the playerAPI.play(uri)
function for playing other items.
Option 2- Using authorizeAndPlayURI
- Once you have the uri to play call appRemoteObj.authorizeAndPlayURI(uri)
. This will trigger playback in the Spotify app and allow you to connect App Remote. You can ignore the token returned from this auth process. After App Remote is connected you can then use the playerAPI.play(uri)
function for playing other items.
The main thing is that music needs to be playing the first time you call connect()
on App Remote.
@jackfreeman Here are the steps I following
sessionManagerObj.initiateSession(with: scope, options: .default)
To get the session manager Object need a configuration object and it looks like
fileprivate lazy var configuration: SPTConfiguration = {
let configuration = SPTConfiguration(clientID: clinet_id, redirectURL: URL(string: redirect_url)!)
configuration.playURI = ""
configuration.tokenSwapURL = URL(string: token_swap_url)
configuration.tokenRefreshURL = URL(string: token_refresh_url)
return configuration
}()
On initiate this delegate is called
func sessionManager(manager: SPTSessionManager, didInitiate session: SPTSession) {
appRemoteObj.connectionParameters.accessToken = session.accessToken
appRemoteObj.connect()
}
On successfull Remote connection
func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote) {
appRemoteObj.playerAPI?.delegate = self
appRemoteObj.playerAPI?.subscribe(toPlayerState: { (result, error) in
if let error = error {
//error in subscription
}
})
}
Then Spotify app starts playing the last track. To get the session access token for fetching playlists needs to call initiateSession method and to get session object, configuration object is required and as per documentation playURI needs to pass a valid string else player will not initialise. At this point if I try to play another song that issue is happening that I mentioned first.
Here are the scopes I am requesting
[.appRemoteControl, .playlistReadPrivate, .streaming, .userReadPlaybackState, .userModifyPlaybackState, .userReadCurrentlyPlaying, .userReadRecentlyPlayed, .userReadPrivate, .userTopRead, .userReadPrivate, .userReadEmail, .userLibraryRead]
@Sapta14 since you are trying to play a track are you doing so on a premium account?
Also does the call to playerAPI?.subscribe
succeed?
@jackfreeman after successful remote connection establishment by calling
func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote)
I am checking the user is premium user or not by calling
SPTUser.requestCurrentUser(withAccessToken: "access_token") { [weak self] (error, user) in
if let localUser = user as? SPTUser, localUser.product == .premium {
debugPrint("Premium")
} else {
debugPrint("Not Premium")
}
}
and it is returns the user as a premium user. While called
appRemoteObj.playerAPI?.subscribe(toPlayerState: { (result, error) in
})
on success this delegate is called
func playerStateDidChange(_ playerState: SPTAppRemotePlayerState)
Can you try a few of these steps to attempt to play a URI:
1) Only request appRemoteControl
scope
2) Don't subscribe to player state
Lastly, can you possibly provide a sample application in which you can reproduce this behavior so I can take a closer look at what might be occurring?
*As a side not you should use SPTAppRemoteuserCapabilities from SPTAppRemoteUserAPI's fetchCapabilitiesWithCallback instead of the old streaming SDK to determine if a user canPlayOnDemand
(is premium). Additionally, you do not need the .streaming
scope to use App Remote.
@jackfreeman ok I will try with your suggested steps, once completed let you know the outcomes.
@Sapta14 any update on this?
I experienced a similar issue:
1) sessionDidInitiate successful (requestedScope: appRemoteControl) 2) appRemoteDidEstablishConnection successful (don't subscribe playerAPI to playerState) 3) then, executing appRemote.playerAPI?.play with a spotify track ID triggers didDisconnectWithError (Code=-2001 "End of stream.")
Happy to share any more app info.
Session initiated successfully with SPTConfiguration where playURI is mentioned as blank string, with the function
sessionManager.initiateSession(with: scope, options: .default)
after that Spotify app started playing last played track. Problem happens when we are trying to play another song throughappRemote.playerAPI!.play(uri, callback: nil)
player failed to play new song each time rather in debug we are getting some logs likeAppRemote: Sending request: <SPTAppRemoteCallRequest: 0x129ea3a10; id: 2, method: com.spotify.play_uri>
AppRemote: Disconnected with error: Error Domain=com.spotify.app-remote.transport Code=-2001 "End of stream." UserInfo={NSLocalizedRecoverySuggestion=Reconnect to the Spotify app., NSLocalizedDescription=End of stream., NSLocalizedFailureReason=One of the streams has reached the end.}
and after that delegate function
appRemote(_ appRemote: SPTAppRemote, didDisconnectWithError error: Error?)
is invoked.Any idea? Thanks in advance