Spotify iOS SDK

概述

Spotify iOS 框架允许您的应用程序与用户设备后台运行的 Spotify 应用程序进行交互。功能包括授权、获取当前播放曲目和上下文的元数据,以及发出播放命令。

请注意: 通过使用 Spotify 开发者工具,您即表示接受我们的 开发者使用条款

Spotify iOS SDK 是一组轻量级对象,它们与 Spotify 应用程序连接,让您在将所有繁重的播放工作卸载到 Spotify 应用程序本身的同时控制它。Spotify 应用程序负责处理播放、网络、离线缓存和操作系统音乐集成,让您专注于用户体验。从您的应用程序移动到 Spotify 应用程序以及反之亦然是一个简化的体验,其中播放和元数据始终保持同步。

主要功能

提交错误报告

组件

App Remote 调用如何工作?

使用条款

教程

常见问题解答

主要功能

提交错误报告

我们欢迎来自开发者社区的反馈,所以请随时在我们的 问题跟踪器 上提交缺失的功能或错误。在创建新问题之前,请务必搜索现有问题。

打开错误工单 | 打开功能请求

要求

Spotify iOS 框架需要 iOS 12 或更高的部署目标。SDK 中支持以下架构

组件

模型

SPTAppRemote

连接到 Spotify 应用程序并检索 API 组件的主要入口点。使用它来建立、监控和终止连接。

SPTAppRemotePlayerAPI

发送与播放相关的命令,例如

SPTAppRemoteImagesAPI

SPTAppRemoteImageRepresentable 获取图像

SPTAppRemoteUserAPI

获取/订阅/设置用户相关数据,例如

SPTAppRemoteContentAPI

为用户获取推荐内容。

App Remote 调用如何工作

当您与任何 App Remote API 交互时,您传入一个 SPTAppRemoteCallback 代码块,该代码块将在 Spotify 应用程序收到命令后(或者如果无法建立连接)使用预期的结果项或 NSError 调用。

这是一个使用 SPTRemotePlayerAPI 跳过歌曲的示例

[appRemote.playerAPI skipToNext:^(id  _Nullable result, NSError * _Nullable error) {
    if (error) {
        // Operation failed
    } else {
        // Operation succeeded
    }
}];

教程和示例

我们提供了一些示例项目,以帮助您开始使用 DemoProjects 文件夹中的 iOS 框架。有关每个示例作用的更多信息,请参阅 DemoProjects 文件夹中的 Readme

身份验证和授权

为了与 Spotify 应用程序通信,您的应用程序需要先获得用户的许可才能使用 App Remote 的内置授权来控制播放。为此,您需要在连接到 Spotify 时请求授权视图。如果用户尚未同意,该框架将自动请求 app-remote-control 范围并显示授权视图。

使用条款

请注意,通过使用 Spotify 开发者工具,您即表示接受我们的 开发者使用条款

包含的开源库

教程

本教程将引导您逐步创建一个简单的应用程序,该应用程序使用 Spotify iOS SDK 播放音轨并订阅播放器状态。它将引导您完成授权流程。

准备您的环境

按照以下步骤确保您已准备好开始编码。

添加依赖项

  1. 将 SpotifyiOS 包添加到您的项目。您可以通过 Swift Package Manager (SPM) 执行此操作,或者直接将 SpotifyiOS.xcframework 添加到您的 Xcode 项目。

    Import SpotifyiOS.framework

  2. 在您的 info.plist 中,添加您在 My Applications 注册的重定向 URI。您需要在“URL types”和“URL Schemes”下添加您的重定向 URI。请务必也设置唯一的“URL identifier”。

    Info.plist

  3. 将库添加到您的源文件。

    Swift

    import SpotifyiOS

    Objective-c

    #import <SpotifyiOS/SpotifyiOS.h>

授权您的应用程序

为了能够使用 SDK 的播放控制部分,用户需要授权您的应用程序。如果他们没有授权,连接将失败并显示 No token provided 错误。为了允许用户授权您的应用程序,您可以使用内置的授权流程。

  1. 使用您的客户端 ID 和重定向 URI 初始化 SPTConfiguration

    Swift

    let configuration = SPTConfiguration(
        clientID: "YOUR_CLIENT_ID",
        redirectURL: URL(string: "your_redirect_uri")!
        )

    Objective-c

    SPTConfiguration *configuration = [[SPTConfiguration alloc] initWithClientID:@"your_client_id" 
                                                                     redirectURL:[NSURL URLWithString:@"your_redirect_uri"]];
  2. 使用您的 SPTConfiguration 初始化 SPTAppRemote

    Swift

    self.appRemote = SPTAppRemote(configuration: configuration, logLevel: .debug)

    Objective-c

    self.appRemote = [[SPTAppRemote alloc] initWithConfiguration:configuration logLevel:SPTAppRemoteLogLevelDebug];
  3. 启动身份验证流程(有关检测 Spotify 是否已安装以及归因安装的其他方法,请参阅我们的 内容链接指南)。

    Swift

    // Note: A blank string will play the user's last song or pick a random one.
    self.appRemote.authorizeAndPlayURI("spotify:track:69bp2EbF7Q2rqc5N3ylezZ") { spotifyInstalled in
        if !spotifyInstalled {
            /*
             * The Spotify app is not installed.
             * Use SKStoreProductViewController with [SPTAppRemote spotifyItunesItemIdentifier] to present the user
             * with a way to install the Spotify app.
             */
        }
    }

    Objective-c

    // Note: A blank string will play the user's last song or pick a random one.
    [self.appRemote authorizeAndPlayURI:@"spotify:track:69bp2EbF7Q2rqc5N3ylezZ" completionHandler:^(BOOL spotifyInstalled) {
        if (!spotifyInstalled) {
            /*
            * The Spotify app is not installed.
            * Use SKStoreProductViewController with [SPTAppRemote spotifyItunesItemIdentifier] to present the user
            * with a way to install the Spotify app.
            */
        }
    }];
  4. 配置您的 AppDelegate 以解析 application:openURL:options: 中的 accessToken,并在 SPTAppRemote connectionParameters 上设置它。

    Objective-c

    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
    {
        NSDictionary *params = [self.appRemote authorizationParametersFromURL:url];
        NSString *token = params[SPTAppRemoteAccessTokenKey];
        if (token) {
            self.appRemote.connectionParameters.accessToken = token;
        } else if (params[SPTAppRemoteErrorDescriptionKey]) {
            NSLog(@"%@", params[SPTAppRemoteErrorDescriptionKey]);
        }
        return YES;
    }

    如果您使用 UIScene,则需要在您的场景委托中使用适当的方法。

    Swift

    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
        }
    }

连接并订阅播放器状态

  1. 设置您的连接委托并尝试连接。

    Swift

    self.appRemote.delegate = self
    self.appRemote.connect()
    // MARK: AppRemoteDelegate
    func appRemoteDidEstablishConnection(_ appRemote: SPTAppRemote) {
        // Connection was successful, you can begin issuing commands
    }
    func appRemote(_ appRemote: SPTAppRemote, didFailConnectionAttemptWithError error: Error?) {
        // Connection failed
    }
    func appRemote(_ appRemote: SPTAppRemote, didDisconnectWithError error: Error?) { 
        // Connection disconnected
    }

    Objective-c

    self.appRemote.delegate = self;
    [self.appRemote connect];
    - (void)appRemoteDidEstablishConnection:(SPTAppRemote *)appRemote
    {
        // Connection was successful, you can begin issuing commands
    }
    
    - (void)appRemote:(SPTAppRemote *)appRemote didFailConnectionAttemptWithError:(NSError *)error
    {
        // Connection failed
    }
    
    - (void)appRemote:(SPTAppRemote *)appRemote didDisconnectWithError:(nullable NSError *)error
    {
        // Connection disconnected
    }
  2. 设置委托并订阅播放器状态

    Swift

    self.appRemote.playerAPI?.delegate = self
    appRemote.playerAPI?.subscribe(toPlayerState: { result, error in
        // Handle Errors
    })
    // MARK: SPTAppRemotePlayerStateDelegate
    func playerStateDidChange(_ playerState: SPTAppRemotePlayerState) {
        print("track name \(playerState.track.name)")
    }

    Objective-c

    appRemote.playerAPI.delegate = self;
    
    [appRemote.playerAPI subscribeToPlayerState:^(id  _Nullable result, NSError * _Nullable error) {
        // Handle Errors
    }];
    - (void)playerStateDidChange:(id<SPTAppRemotePlayerState>)playerState
    {
        NSLog(@"Track name: %@", playerState.track.name);
    }

连接处理

作为一项礼貌措施,当您的应用程序进入后台状态时,您应始终断开 App Remote 的连接。这告诉 Spotify 可以安全地禁用活动流。如果您的应用程序未正确调用断开连接,Spotify 将无法知道它不应保持连接,这可能会导致未来的连接问题。

如果您希望您的应用程序在中断事件(如来电或 Siri 交互)后自动重新连接,您可以使用 willResignActivedidBecomeActive 回调安全地断开和重新连接。如果您不希望直接重新连接,通常在 didEnterBackground 回调中关闭连接就足够了。

Swift

func sceneWillResignActive(_ scene: UIScene) {
    self.appRemote.disconnect()
}
func sceneDidBecomeActive(_ scene: UIScene) {
    self.appRemote.connect()
}

Objective-c

- (void)applicationWillResignActive:(UIApplication *)application
{
    [self.appRemote disconnect];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [self.appRemote connect];
}

// If you're using UIWindowSceneDelegate

- (void)sceneDidBecomeActive:(UIScene *)scene
{
    [self.appRemote connect];
}
- (void)sceneWillResignActive:(UIScene *)scene
{
    [self.appRemote disconnect];
}

常见问题解答

为什么必须在音乐播放时才能连接 SPTAppRemote

当您连接 SPTAppRemote 时,必须正在播放音乐,以确保 Spotify 应用程序不会在后台挂起。除非 iOS 应用程序正在积极执行某些操作(如导航或播放音乐),否则它们只能在后台保持活动状态几秒钟。

SpotifyiOS.framework 是线程安全的吗?

否,该框架目前希望从主线程调用。它将在内部将其大部分工作卸载到后台线程,但对您代码的回调也将在主线程上发生。

如果我需要在不启动播放的情况下进行授权怎么办?

还有另一种授权方法。您可以在 此处 找到有关该方法的更多信息。