### Configure Initial Music Playback URI
Source: https://developer.spotify.com/documentation/ios/tutorials/advanced-auth
Set the playURI to either resume the last track or start a specific Spotify URI.
```swift
self.configuration.playURI = ""
```
```swift
self.configuration.playURI = "spotify:track:20I6sIOMTCkB6w7ryavxtO"
```
--------------------------------
### Trigger Spotify App Store Install via Branch
Source: https://developer.spotify.com/documentation/ios/tutorials/content-linking
Direct users to the Spotify App Store page for installation. This uses a Branch tracker URL, optionally including a canonical URL for deferred deep linking.
```objective-c
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
NSString *canonicalURL = @"https://open.spotify.com/album/0sNOF9WDwhWunNAHPD3Baj";
NSString *branchLink = [NSString stringWithFormat:@"https://spotify.link/content_linking?~campaign=%@&$canonical_url=%@", bundleId, canonicalURL];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:branchLink]];
[[[NSURLSession sharedSession] dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}] resume];
```
--------------------------------
### Setup Token Swap and Refresh
Source: https://developer.spotify.com/documentation/ios/tutorials/advanced-auth
Configure the session manager with token swap and refresh URLs to securely obtain access tokens.
```swift
lazy var sessionManager: SPTSessionManager = {
if let tokenSwapURL = URL(string: "https://[my token swap app domain]/api/token"),
let tokenRefreshURL = URL(string: "https://[my token swap app domain]/api/refresh_token") {
self.configuration.tokenSwapURL = tokenSwapURL
self.configuration.tokenRefreshURL = tokenRefreshURL
self.configuration.playURI = ""
}
let manager = SPTSessionManager(configuration: self.configuration, delegate: self)
return manager
}()
```
--------------------------------
### Configure Info.plist: Add spotify to LSApplicationQueriesSchemes
Source: https://developer.spotify.com/documentation/ios/getting-started
Add the 'spotify' scheme to `LSApplicationQueriesSchemes` in your `Info.plist` to enable checking if the Spotify main application is installed.
```xml
LSApplicationQueriesSchemes
spotify
```
--------------------------------
### Detect Spotify Installation
Source: https://developer.spotify.com/documentation/ios/tutorials/content-linking
Check if the Spotify app is installed on the device by attempting to open the 'spotify:' URL scheme.
```objective-c
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"spotify:"]]
```
--------------------------------
### Instantiate SPTConfiguration
Source: https://developer.spotify.com/documentation/ios/tutorials/advanced-auth
Define client credentials and initialize the SDK configuration at the class level.
```swift
let SpotifyClientID = "[your spotify client id here]"
let SpotifyRedirectURL = URL(string: "spotify-ios-quick-start://spotify-login-callback")!
lazy var configuration = SPTConfiguration(
clientID: SpotifyClientID,
redirectURL: SpotifyRedirectURL
)
```
--------------------------------
### Instantiate SPTConfiguration
Source: https://developer.spotify.com/documentation/ios/getting-started
Define your Client ID and Redirect URI to initialize the SDK configuration.
```swift
let SpotifyClientID = "[your spotify client id here]"
let SpotifyRedirectURL = URL(string: "spotify-ios-quick-start://spotify-login-callback")!
lazy var configuration = SPTConfiguration(
clientID: SpotifyClientID,
redirectURL: SpotifyRedirectURL
)
```
--------------------------------
### Configure Initial Music Playback URI
Source: https://developer.spotify.com/documentation/ios/getting-started
Set the playURI property to either an empty string to resume playback or a specific Spotify track URI.
```swift
self.playURI = ""
```
```swift
self.playURI = "spotify:track:20I6sIOMTCkB6w7ryavxtO"
```
--------------------------------
### Configure Info.plist: Add URI Scheme in CFBundleURLTypes
Source: https://developer.spotify.com/documentation/ios/getting-started
Set up a URI scheme in `Info.plist` by adding your Bundle ID to `CFBundleURLName` and your Redirect URI protocol to `CFBundleURLSchemes` to allow Spotify to send users back to your application.
```xml
CFBundleURLTypes
CFBundleURLName
com.spotify.iOS-SDK-Quick-Start
CFBundleURLSchemes
spotify-ios-quick-start
```
--------------------------------
### Initialize App Remote
Source: https://developer.spotify.com/documentation/ios/getting-started
Initialize the App Remote instance using the previously defined configuration.
```swift
lazy var appRemote: SPTAppRemote = {
let appRemote = SPTAppRemote(configuration: self.configuration, logLevel: .debug)
appRemote.connectionParameters.accessToken = self.accessToken
appRemote.delegate = self
return appRemote
}()
```
--------------------------------
### Handle Session Delegate Methods
Source: https://developer.spotify.com/documentation/ios/tutorials/advanced-auth
Implement the required delegate methods to handle session initiation, failure, and renewal.
```swift
func sessionManager(manager: SPTSessionManager, didInitiate session: SPTSession) {
print("success", session)
}
func sessionManager(manager: SPTSessionManager, didFailWith error: Error) {
print("fail", error)
}
func sessionManager(manager: SPTSessionManager, didRenew session: SPTSession) {
print("renewed", session)
}
```
--------------------------------
### Authorize and Connect to Spotify
Source: https://developer.spotify.com/documentation/ios/getting-started
Initiate the authorization flow and connect to the Spotify App Remote using the configured URI.
```swift
func connect()) {
self.appRemote.authorizeAndPlayURI(self.playURI)
}
```
--------------------------------
### Configure Auth Callback
Source: https://developer.spotify.com/documentation/ios/getting-started
Handle the authorization callback to assign the access token to the app remote connection parameters.
```swift
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
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
}
return true
}
```
```swift
func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
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
}
}
```
--------------------------------
### Open Spotify App Store URL
Source: https://developer.spotify.com/documentation/ios/tutorials/content-linking
Open the Spotify app in the App Store. This is a direct link to the application's page.
```objective-c
NSString *url = @"https://itunes.apple.com/app/spotify-music/id324684580?mt=8";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
```
--------------------------------
### Handle Player State Changes
Source: https://developer.spotify.com/documentation/ios/getting-started
Implement the delegate method to react to player state changes, such as logging the current track name.
```swift
func playerStateDidChange(_ playerState: SPTAppRemotePlayerState) {
debugPrint("Track name: %@", playerState.track.name)
}
```
--------------------------------
### Subscribe to Player State Updates
Source: https://developer.spotify.com/documentation/ios/getting-started
Register the player delegate and subscribe to state updates upon successful connection.
```swift
func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote) {
// Connection was successful, you can begin issuing commands
self.appRemote.playerAPI?.delegate = self
self.appRemote.playerAPI?.subscribe(toPlayerState: { (result, error) in
if let error = error {
debugPrint(error.localizedDescription)
}
})
}
```
--------------------------------
### Add Spotify Scheme to Info.plist
Source: https://developer.spotify.com/documentation/ios/tutorials/content-linking
Declare your app's intent to query the Spotify URL scheme by adding 'spotify' to the LSApplicationQueriesSchemes key in your Info.plist file.
```xml
...
LSApplicationQueriesSchemes
spotify
...
...
```
--------------------------------
### Configure Auth Callback in AppDelegate
Source: https://developer.spotify.com/documentation/ios/tutorials/advanced-auth
Notify the session manager when the user returns to the application after authorization.
```swift
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
self.sessionManager.application(app, open: url, options: options)
return true
}
```
--------------------------------
### Open Spotify Content in App
Source: https://developer.spotify.com/documentation/ios/tutorials/content-linking
Open specific Spotify content (e.g., an album) within the Spotify app using a web link. This method is preferred over a direct 'spotify:' URI to avoid confirmation prompts and leverage Universal Links.
```objective-c
NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
NSString *canonicalURL = @"https://open.spotify.com/album/0sNOF9WDwhWunNAHPD3Baj";
NSString *branchLink = [NSString stringWithFormat:@"https://spotify.link/content_linking?~campaign=%@&$canonical_url=%@", bundleId, canonicalURL];
NSURL *url = [NSURL URLWithString:branchLink];
[[UIApplication sharedApplication] openURL:url];
```
--------------------------------
### Skip to next track using SPTRemotePlayerAPI
Source: https://developer.spotify.com/documentation/ios/tutorials/making-remote-calls
Uses the skipToNext method to advance the player, providing a callback block to handle success or failure.
```objective-c
[appRemote.playerAPI skipToNext:^(id _Nullable result, NSError * _Nullable error) {
2
if (error) {
3
// Operation failed
4
} else {
5
// Operation succeeded
6
}
7
}];
```
--------------------------------
### Implement Remote Delegates
Source: https://developer.spotify.com/documentation/ios/getting-started
Implement the required delegate protocols in your AppDelegate or SceneDelegate.
```swift
class AppDelegate: UIResponder, UIApplicationDelegate, SPTAppRemoteDelegate, SPTAppRemotePlayerStateDelegate {
...
```
```swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate, SPTAppRemoteDelegate, SPTAppRemotePlayerStateDelegate
...
```
```swift
func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote) {
print("connected")
}
func appRemote(_ appRemote: SPTAppRemote, didDisconnectWithError error: Error?) {
print("disconnected")
}
func appRemote(_ appRemote: SPTAppRemote, didFailConnectionAttemptWithError error: Error?) {
print("failed")
}
func playerStateDidChange(_ playerState: SPTAppRemotePlayerState) {
print("player state changed")
}
```
--------------------------------
### Invoke Authorization Modal
Source: https://developer.spotify.com/documentation/ios/tutorials/advanced-auth
Trigger the authentication screen with requested scopes and optional campaign tracking.
```swift
let requestedScopes: SPTScope = [.appRemoteControl]
self.sessionManager.initiateSession(with: requestedScopes, options: .default, campaign: "utm-campaign")
```
--------------------------------
### Token Swap Response - JSON
Source: https://developer.spotify.com/documentation/ios/concepts/token-swap-and-refresh
This is the expected JSON response when successfully swapping a code for tokens. It includes the access token, its expiration time in seconds, and a refresh token.
```json
{
"access_token" : "NgAagA...Um_SHo",
"expires_in" : "3600",
"refresh_token" : "NgCXRK...MzYjw"
}
```
--------------------------------
### Manage Connection Lifecycle in UIScene
Source: https://developer.spotify.com/documentation/ios/getting-started
Handle App Remote connection and disconnection within the UIScene lifecycle methods.
```swift
func sceneDidBecomeActive(_ scene: UIScene) {
if let _ = self.appRemote.connectionParameters.accessToken {
self.appRemote.connect()
}
}
func sceneWillResignActive(_ scene: UIScene) {
if self.appRemote.isConnected {
self.appRemote.disconnect()
}
}
```
--------------------------------
### Swap Code for Tokens Request - cURL
Source: https://developer.spotify.com/documentation/ios/concepts/token-swap-and-refresh
Use this cURL command to swap an authorization code for an access token and a refresh token. Ensure the Content-Type header is set to application/x-www-form-urlencoded.
```bash
curl -X POST "https://example.com/v1/swap” -H "Content-Type: application/x-www-form-urlencoded" --data “code=AQDy8...xMhKNA”
```
--------------------------------
### Add Bridging Header
Source: https://developer.spotify.com/documentation/ios/getting-started
Include the Spotify iOS SDK header in your project's bridging header file.
```objective-c
#import
```
--------------------------------
### Manage Connection Lifecycle in AppDelegate
Source: https://developer.spotify.com/documentation/ios/getting-started
Disconnect from App Remote when the app resigns active and reconnect when it becomes active.
```swift
func applicationWillResignActive(_ application: UIApplication) {
if self.appRemote.isConnected {
self.appRemote.disconnect()
}
}
func applicationDidBecomeActive(_ application: UIApplication) {
if let _ = self.appRemote.connectionParameters.accessToken {
self.appRemote.connect()
}
}
```
--------------------------------
### POST /v1/swap - Token Swap
Source: https://developer.spotify.com/documentation/ios/concepts/token-swap-and-refresh
Swaps a code obtained from the Spotify account service for an access token and a refresh token.
```APIDOC
## POST /v1/swap
### Description
Swaps a code for an access token and a refresh token.
### Method
POST
### Endpoint
https://example.com/v1/swap
### Parameters
#### Request Headers
- **Content-Type** (string) - Required - application/x-www-form-urlencoded
#### Request Body
- **code** (string) - Required - The code returned from Spotify account service to be used in the token request.
### Request Example
```
curl -X POST "https://example.com/v1/swap" -H "Content-Type: application/x-www-form-urlencoded" --data "code=AQDy8...xMhKNA"
```
### Response
#### Success Response (200)
- **access_token** (string) - Access token received from Spotify account service.
- **expires_in** (string) - The time period (in seconds) for which the access token is valid. Returned from the Spotify account service.
- **refresh_token** (string) - The refresh token returned from the Spotify account service. It should not return the actual refresh token but a reference to the token or an encrypted version of the token. Encryption solution is shown in the ruby example.
#### Response Example
```json
{
"access_token" : "NgAagA...Um_SHo",
"expires_in" : "3600",
"refresh_token" : "NgCXRK...MzYjw"
}
```
```
--------------------------------
### Refresh Access Token Request - cURL
Source: https://developer.spotify.com/documentation/ios/concepts/token-swap-and-refresh
Use this cURL command to obtain a new access token using a previously obtained refresh token. The Content-Type header must be application/x-www-form-urlencoded.
```bash
curl -X POST "https://example.com/v1/refresh" -H "Content-Type: application/x-www-form-urlencoded" --data "refresh_token=NgCXRK...MzYjw"
```
--------------------------------
### Implement SPTSessionManagerDelegate in AppDelegate
Source: https://developer.spotify.com/documentation/ios/tutorials/advanced-auth
Add the delegate protocol to your AppDelegate class definition.
```swift
class AppDelegate: UIResponder, UIApplicationDelegate, SPTSessionManagerDelegate {
...
```
--------------------------------
### Set -ObjC Linker Flag
Source: https://developer.spotify.com/documentation/ios/getting-started
Add the `-ObjC` linker flag in Xcode's Build Settings under 'Other Linker Flags' to enable compilation of Objective-C code within the iOS SDK.
```bash
-ObjC
```
--------------------------------
### Manage App Remote Lifecycle in AppDelegate
Source: https://developer.spotify.com/documentation/ios/concepts/application-lifecycle
Disconnect the App Remote when the application resigns active status and reconnect when it becomes active, provided an access token exists.
```Objective-C
- (void)applicationWillResignActive:(UIApplication *)application {
if (self.appRemote.isConnected) {
[self.appRemote disconnect];
}
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if (self.appRemote.connectionParameters.accessToken) {
[self.appRemote connect];
}
}
```
--------------------------------
### POST /v1/refresh - Token Refresh
Source: https://developer.spotify.com/documentation/ios/concepts/token-swap-and-refresh
Uses a refresh token to obtain a new access token when the current one expires.
```APIDOC
## POST /v1/refresh
### Description
Uses the refresh token to get a new access token.
### Method
POST
### Endpoint
https://example.com/v1/refresh
### Parameters
#### Request Headers
- **Content-Type** (string) - Required - application/x-www-form-urlencoded
#### Request Body
- **refresh_token** (string) - Required - The refresh_token value previously returned from the token swap endpoint.
### Request Example
```
curl -X POST "https://example.com/v1/refresh" -H "Content-Type: application/x-www-form-urlencoded" --data "refresh_token=NgCXRK...MzYjw"
```
### Response
#### Success Response (200)
- **access_token** (string) - Access token received from Spotify account service.
- **expires_in** (string) - The time period (in seconds) for which the access token is valid. Returned from the Spotify account service.
#### Response Example
```json
{
"access_token" : "NgAagA...Um_SHo",
"expires_in" : "3600"
}
```
```
--------------------------------
### Token Refresh Response - JSON
Source: https://developer.spotify.com/documentation/ios/concepts/token-swap-and-refresh
This is the expected JSON response when a refresh token is used to obtain a new access token. It contains the new access token and its expiration time in seconds.
```json
{
"access_token" : "NgAagA...Um_SHo",
"expires_in" : "3600"
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.