Spotify iOS SDK Documentation

repository·master·Indexed 18 days ago

https://github.com/spotify/ios-sdk

A lightweight framework for iOS applications to control the Spotify app. It provides APIs for playback control, metadata retrieval, and user capability checks via components like SPTAppRemote, SPTAppRemotePlayerAPI, SPTAppRemoteImagesAPI, SPTAppRemoteUserAPI, and SPTAppRemoteContentAPI. Supports iOS 12 or higher on arm64 and x86_64 architectures.

Tokens
5.9K
Snippets
13
Records
22
Agent score
73%

What's inside Spotify iOS SDK

  1. Overview of the Spotify iOS SDK

    master

    The Spotify iOS SDK is a lightweight framework that allows your application to interact with the Spotify app running on a user's device. Instead of handling playback, networking, or caching yourself, the SDK offloads these tasks to the Spotify app, ensuring that playback and metadata remain in sync between your app and Spotify.

    Key capabilities include:

    • Authorization: Users can authenticate through the Spotify app without re-entering credentials.
    • Metadata: Retrieve information about the currently playing track and context.
    • Playback Control: Issue commands like play, pause, skip, and seek.
    • Offline Support: Works both online and offline without requiring Web API calls for player state metadata.
  2. Explore Spotify iOS SDK Sample Projects

    master

    The repository includes three distinct sample projects designed to demonstrate different integration patterns with the Spotify iOS SDK:

    1. NowPlayingView (Swift): Demonstrates playback control, subscribing to player state changes, and fetching content. This project interacts with the Spotify app on a device but does not require a token swap server.
    2. SPTLoginSampleAppObjc (Objective-C): Focuses exclusively on the authentication flow. Use this to learn how to request specific OAuth scopes and obtain access tokens for the Web API. It does not require a token swap server.
    3. SPTLoginSampleAppSwift (Swift): A comprehensive example combining authentication and remote control. This is the recommended starting point if you need to control playback while also requiring additional scopes for the Web API. Note: This project requires a token swap service to function.
  3. Core Components of the Spotify iOS SDK

    master

    The SDK is organized into several functional components accessed through the main entry point:

    • SPTAppRemote: The primary entry point used to establish, monitor, and terminate the connection to the Spotify app. It provides access to the specialized APIs below.
    • SPTAppRemotePlayerAPI: Used for playback commands (e.g., play track by URI, resume/pause, skip, seek, shuffle, and subscribing to player state).
    • SPTAppRemoteImagesAPI: Used to fetch images for objects conforming to SPTAppRemoteImageRepresentable.
    • SPTAppRemoteUserAPI: Used to manage user-related data, such as checking user capabilities (Premium vs. Free) and managing the user's library.
    • SPTAppRemoteContentAPI: Used to fetch recommended content for the user.
  4. PKCE vs Token Swap for authentication

    master

    The SDK provides two ways to exchange an authorization code for access and refresh tokens:

    • PKCE Method: The default flow. The SDK implements Proof Key for Code Exchange (PKCE) and sends a request directly to the Spotify token exchange endpoint.
    • Token Swap URL: A more secure method for mobile apps. Instead of the mobile app holding the client_secret, you host two endpoints on your backend: one for token exchange and one for token refresh. The SDK sends the authorization code to your backend, and your backend communicates with Spotify using the client_secret. This prevents exposing your secret within the mobile application code.
  5. How App Remote calls work

    master

    All App Remote API calls are asynchronous. When you invoke a method, you must provide an SPTAppRemoteCallback block. This block is executed after the command is received by the Spotify app. The block returns either the expected result or an NSError if the operation failed.

    Example of skipping to the next track using SPTAppRemotePlayerAPI:

    appRemote.playerAPI?.skipToNext { result, error in
        if let error = error {
            // Operation failed
        } else {
            // Operation succeeded
        }
    }
  6. SDK Requirements and Supported Architectures

    master

    To use the Spotify iOS SDK, ensure your project meets the following requirements:

    • Deployment Target: iOS 12 or higher.
    • Supported Architectures:
      • Device: arm64
      • Simulator: arm64, x86_64
  7. Implement the SPTSessionManager authorization flow

    master

    Use SPTSessionManager to authenticate users and obtain access tokens. The SDK automatically handles the flow by attempting to open the Spotify app via a custom URL scheme, falling back to ASWebAuthentication if the app is not installed.

    Setup Steps

    1. Configure Info.plist: Add the spotify scheme to LSApplicationQueriesSchemes to allow the SDK to detect the Spotify app.

    2. Initialize Configuration: Create an SPTConfiguration with your clientID and redirectURL. You can optionally set playURI to start playback during authorization.

    3. Set Token Swap URLs (Optional): If using the Token Swap method (see PKCE vs Token Swap), provide your backend's tokenSwapURL and tokenRefreshURL in the configuration.

    4. Initialize Session Manager: Create the SPTSessionManager using your configuration and a delegate conforming to SPTSessionManagerDelegate.

    5. Handle Redirects: Implement the appropriate URL handling in your SceneDelegate or AppDelegate to pass the returned token back to the sessionManager.

    6. Implement Delegate: Handle success (didInitiate), renewal (didRenew), or failure (didFailWith) in your SPTSessionManagerDelegate implementation.

    7. Start Authorization: Call initiateSession(with:options:campaign:) with the required SPTScope.

    // 1. Info.plist
    // <key>LSApplicationQueriesSchemes</key>
    // <array><string>spotify</string></array>
    
    // 2. Configuration
    let configuration = SPTConfiguration(
        clientID: "your_client_id",
        redirectURL: URL(string: "your_redirect_uri")!
    )
    
    // 3. (Optional) Token Swap
    configuration.tokenSwapURL = URL(string: "http://[your_server]/swap")
    configuration.tokenRefreshURL = URL(string: "http://[your_server]/refresh")
    
    // 4. Session Manager
    self.sessionManager = SPTSessionManager(configuration: configuration, delegate: self)
    
    // 5. Handle Redirects (SceneDelegate example)
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let url = URLContexts.first?.url else { return }
        sessionManager.application(UIApplication.shared, open: url, options: [:])
    }
    
    // 6. Delegate
    func sessionManager(manager: SPTSessionManager, didInitiate session: SPTSession) {
        // Success
        print("Access Token: \(session.accessToken)")
    }
    
    // 7. Initiate
    let scope: SPTScope = [.userFollowRead, .appRemoteControl]
    sessionManager.initiateSession(with: scope, options: .default, campaign: nil)
  8. Setup the SPTLoginSampleAppObjc demo project

    master

    To run the SPTLoginSampleAppObjc demo project, which demonstrates the authentication capabilities of the Spotify iOS SDK, follow these steps:

    1. Install XcodeGen: Use Homebrew to install the project generator.
    2. Generate Project: Run xcodegen within the demo project directory to create the .xcodeproj file.
    3. Open Project: Open SPTLoginSampleAppObjc.xcodeproj in Xcode.
    4. Configure Spotify Dashboard:
      • Create a new app at https://developer.spotify.com/dashboard.
      • Set a name and description.
      • Crucial: Add the redirect URI: spotify-login-sdk-test-app-objc://spotify-login-callback.
      • Ensure the iOS SDK checkbox is selected.
    5. Configure Xcode Settings: Edit your project settings to use the bundle identifier com.spotify.SPTLoginSampleAppObjc.
    6. Link Client ID: Copy your clientID from the Spotify Dashboard and paste it into ViewController.m.
    # Install XcodeGen
    brew install xcodegen
    
    # Generate the Xcode project
    xcodegen
  9. Setup the Now Playing View demo project

    master

    To run the NowPlayingView demo project, you must generate the Xcode project using XcodeGen and configure your Spotify Developer credentials.

    1. Install XcodeGen using Homebrew: brew install xcodegen.
    2. Run xcodegen from within the demo project directory to generate the .xcodeproj file.
    3. Open NowPlayingView.xcodeproj in Xcode.
    4. Configure your Spotify App in the Spotify Developer Dashboard:
      • Create a new app with a name and description.
      • Add the redirect URI: spotify-ios-test-app://spotify-login-callback.
      • Enable the iOS SDK checkbox.
    5. In the demo project, edit the Settings to include the bundle identifier com.spotify.SpotifyAppRemoteDemo.
    6. Copy your clientID from the Spotify Dashboard and paste it into SceneDelegate.swift.
    # Install XcodeGen
    brew install xcodegen
    
    # Generate the Xcode project
    xcodegen
  10. Configure URL handling for redirects

    master

    Depending on whether you use a Custom URL Scheme or Universal Links, and whether you use the modern SceneDelegate or legacy AppDelegate pattern, you must implement the following methods to pass the authorization response to SPTSessionManager.

    SceneDelegate (iOS 13+)

    Custom URL Schemes (myapp://callback):

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

    Universal Links (https://myapp.com/callback):

    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
            sessionManager.application(UIApplication.shared, continue: userActivity, restorationHandler: nil)
        }
    }

    AppDelegate (Legacy/iOS 12 and below)

    Custom URL Schemes:

    func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        return sessionManager.application(application, open: url, options: options)
    }

    Universal Links:

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        return sessionManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
    }
  11. Set up the SPTLoginSampleAppSwift demo project

    master

    To run the SPTLoginSampleAppSwift demo project, which demonstrates the integration of authentication and remote control, follow these steps:

    1. Install XcodeGen: Use Homebrew to install the project generator: brew install xcodegen.
    2. Generate Project: Run xcodegen within the demo project directory.
    3. Open Project: Open the generated SPTLoginSampleAppSwift.xcodeproj in Xcode.
    4. Configure Spotify Dashboard:
    5. Configure App Settings: Edit the project settings to add the bundle ID com.spotify.SPTLoginSampleAppSwift.
    6. Add Client ID: Copy your clientID from the Spotify Dashboard into ViewController.swift.
    brew install xcodegen
    xcodegen
  12. Connect to SPTAppRemote and Subscribe to Player State

    master

    After authorization, you must connect to the App Remote and set a delegate to listen for connection events. To react to music changes, use the playerAPI to subscribe to player state changes.

    // 1. Connect
    self.appRemote.delegate = self
    self.appRemote.connect()
    
    // MARK: AppRemoteDelegate
    func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote) {
        // Connection successful
    }
    func appRemote(_ appRemote: SPTAppRemote, didFailConnectionAttemptWithError error: Error?) {}
    func appRemote(_ appRemote: SPTAppRemote, didDisconnectWithError error: Error?) {}
    
    // 2. Subscribe to Player State
    self.appRemote.playerAPI?.delegate = self
    self.appRemote.playerAPI?.subscribe(toPlayerState: { result, error in
        // Handle Errors
    })
    
    // MARK: SPTAppRemotePlayerStateDelegate
    func playerStateDidChange(_ playerState: SPTAppRemotePlayerState) {
        print("track name \(playerState.track.name)")
    }