SpotifyAPI

一个用于 Spotify Web API 的 Swift 库

特性

阅读完整的文档,并查看此示例 iOS 应用和此示例命令行应用

赞助商

目录

支持的平台

安装

  1. 在 Xcode 中,打开要将此软件包添加到其中的项目。
  2. 从菜单栏中,选择“File (文件)” > “Swift Packages (Swift 包)” > “Add Package Dependency... (添加包依赖项...)”。
  3. 将此仓库的 URL 粘贴到搜索字段中。
  4. 选择 SpotifyAPI 库。
  5. 按照提示添加软件包。

快速入门

首先,前往 Spotify 开发者仪表板 并创建一个应用程序。 你将收到一个客户端 ID 和客户端密钥。 然后,单击“编辑设置”并添加重定向 URI。 通常,这应该是一个自定义 URL 方案,它重定向到你应用程序中的某个位置。 不要在重定向 URI 的末尾添加斜杠 (/)

下一步是授权你的应用程序。 所有 对 Spotify Web API 的请求——无论它们是否需要 授权范围——都需要授权。此库支持三种授权方法。

另请参阅 其他授权方法

在创建使用此库的应用程序时,你可能需要将授权信息保存到持久存储,这样用户就不必每次退出并重新启动应用程序时都再次登录。 请参阅 将授权信息保存到持久存储 了解如何执行此操作的指南。

使用带有代码交换证明密钥的授权码流程进行授权

创建 SpotifyAPI 的实例,并将 AuthorizationCodeFlowPKCEManager 的实例分配给 authorizationManager 属性。

import SpotifyWebAPI

let spotify = SpotifyAPI(
    authorizationManager: AuthorizationCodeFlowPKCEManager(
        clientId: "Your Client Id"
    )
)

在每次身份验证请求之前,你的应用程序应生成一个代码验证器和一个代码挑战。代码验证器是一个长度介于 43 到 128 个字符之间的加密随机字符串。 它可以包含字母、数字、下划线、句点、连字符和波浪号。

为了生成代码挑战,你的应用程序应使用 SHA256 算法对代码验证器进行哈希处理。 然后,base64url 编码你生成的哈希值。 不要包含任何 = 填充字符(百分比编码与否)。

你可以使用 String.randomURLSafe(length:using:)String.randomURLSafe(length:) 来生成代码验证器。 你可以使用 String.makeCodeChallenge(codeVerifier:) 实例方法从代码验证器创建代码挑战。

例如:

let codeVerifier = String.randomURLSafe(length: 128)
let codeChallenge = String.makeCodeChallenge(codeVerifier: codeVerifier)

// optional, but strongly recommended
let state = String.randomURLSafe(length: 128)

如果你使用自己的方法创建这些值,你可以使用此 PKCE 生成器工具对其进行验证。 另请参阅 Data.base64URLEncodedString()String.urlSafeCharacters

接下来,创建将在浏览器(或 Web 视图)中打开的授权 URL。 打开时,它会向用户显示一个权限对话框。 然后,用户可以选择授权或拒绝你的应用程序的授权。

let authorizationURL = spotify.authorizationManager.makeAuthorizationURL(
    redirectURI: URL(string: "Your Redirect URI")!,
    codeChallenge: codeChallenge,
    state: state,
    scopes: [
        .playlistModifyPrivate,
        .userModifyPlaybackState,
        .playlistReadCollaborative,
        .userReadPlaybackPosition
    ]
)!

请参阅 makeAuthorizationURL(redirectURI:showDialog:codeChallenge:state:scopes:) 的完整文档。

重定向 URI 需要已在你使用 Spotify 开发者仪表板 注册你的应用程序时指定的重定向 URI 白名单中输入。 不要在重定向 URI 的末尾添加斜杠 (/)。

每个接口的文档都列出了所需的 授权范围。 如果需要,你可以随时为不同的范围再次授权你的应用程序。 但是,这不是一个累加的过程。 每次创建授权 URL 时,都必须指定你需要的所有范围。

你可以决定如何打开 URL。 如果你正在创建一个 iOS 应用程序,最简单的方法是使用 UIApplication.shared.open(authorizationURL) 在浏览器中打开 URL。

在用户批准或拒绝你的应用程序的授权后,Spotify 将重定向到你在生成授权 URL 时指定的重定向 URI,并将查询参数附加到该 URI。 将此 URL 传递到 requestAccessAndRefreshTokens(redirectURIWithQuery:codeVerifier:state:) 以请求访问和刷新令牌。

spotify.authorizationManager.requestAccessAndRefreshTokens(
    redirectURIWithQuery: url,
    // Must match the code verifier that was used to generate the 
    // code challenge when creating the authorization URL.
    codeVerifier: codeVerifier,
    // Must match the value used when creating the authorization URL.
    state: state
)
.sink(receiveCompletion: { completion in
    switch completion {
        case .finished:
            print("successfully authorized")
        case .failure(let error):
            if let authError = error as? SpotifyAuthorizationError, authError.accessWasDenied {
                print("The user denied the authorization request")
            }
            else {
                print("couldn't authorize application: \(error)")
            }
    }
})
.store(in: &cancellables)

一旦此发布者成功完成,你的应用程序就已授权,你可以开始向 Spotify Web API 发出请求。 在发出另一个授权请求之前,请确保为状态参数、代码验证器和代码挑战生成一个新值。 访问令牌将在必要时自动刷新。 例如:

import SpotifyExampleContent

let playbackRequest = PlaybackRequest(
    context: .uris(
        URIs.Tracks.array(.faces, .illWind, .fearless)
    ),
    offset: .uri(URIs.Tracks.fearless),
    positionMS: 50_000
)

spotify.play(playbackRequest)
    .sink(receiveCompletion: { completion in
        print(completion)
    })
    .store(in: &cancellables)

所有接口的完整文档可以在 这里 找到。 还建议阅读 Spotify Web API 参考文档

使用授权码流程进行授权

创建 SpotifyAPI 的实例,并将 AuthorizationCodeFlowManager 的实例分配给 authorizationManager 属性。

import SpotifyWebAPI

let spotify = SpotifyAPI(
    authorizationManager: AuthorizationCodeFlowManager(
        clientId: "Your Client Id", clientSecret: "Your Client Secret"
    )
)

接下来,创建将在浏览器(或 Web 视图)中打开的授权 URL。 打开时,它会向用户显示一个权限对话框。 然后,用户可以选择授权或拒绝你的应用程序的授权。

let authorizationURL = spotify.authorizationManager.makeAuthorizationURL(
    redirectURI: URL(string: "Your Redirect URI")!,
    showDialog: false,
    scopes: [
        .playlistModifyPrivate,
        .userModifyPlaybackState,
        .playlistReadCollaborative,
        .userReadPlaybackPosition
    ]
)!

请参阅 makeAuthorizationURL(redirectURI:showDialog:state:scopes:) 的完整文档。

重定向 URI 需要已在你使用 Spotify 开发者仪表板 注册你的应用程序时指定的重定向 URI 白名单中输入。 不要在重定向 URI 的末尾添加斜杠 (/)。

每个接口的文档都列出了所需的 授权范围。 如果需要,你可以随时为不同的范围再次授权你的应用程序。 但是,这不是一个累加的过程。 每次创建授权 URL 时,都必须指定你需要的所有范围。

你可以决定如何打开 URL。 如果你正在创建一个 iOS 应用程序,最简单的方法是使用 UIApplication.shared.open(authorizationURL) 在浏览器中打开 URL。

在用户批准或拒绝你的应用程序的授权后,Spotify 将重定向到你在生成授权 URL 时指定的重定向 URI,并将查询参数附加到该 URI。 将此 URL 传递到 requestAccessAndRefreshTokens(redirectURIWithQuery:state:) 以请求访问和刷新令牌。

spotify.authorizationManager.requestAccessAndRefreshTokens(
    redirectURIWithQuery: url
)
.sink(receiveCompletion: { completion in
    switch completion {
        case .finished:
            print("successfully authorized")
        case .failure(let error):
            if let authError = error as? SpotifyAuthorizationError, authError.accessWasDenied {
                print("The user denied the authorization request")
            }
            else {
                print("couldn't authorize application: \(error)")
            }
    }
})
.store(in: &cancellables)

一旦此发布者成功完成,你的应用程序就已授权,你可以开始向 Spotify Web API 发出请求。 在发出另一个授权请求之前,请确保为状态参数生成一个新值。 访问令牌将在必要时自动刷新。 例如:

spotify.currentUserPlaylists()
    .extendPages(spotify)
    .sink(
        receiveCompletion: { completion in
            print(completion)
        },
        receiveValue: { results in
            print(results)
        }
    )
    .store(in: &cancellables)

此授权过程已在此示例应用中完全实现。 所有接口的完整文档可以在 这里 找到。 还建议阅读 Spotify Web API 参考文档

使用客户端凭据流程进行授权

创建 SpotifyAPI 的实例,并将 ClientCredentialsFlowManager 的实例分配给 authorizationManager 属性。

import SpotifyWebAPI

let spotify = SpotifyAPI(
    authorizationManager: ClientCredentialsFlowManager(
        clientId: "Your Client Id", clientSecret: "Your Client Secret"
    )
)

要授权你的应用程序,请调用 authorize()

spotify.authorizationManager.authorize()
    .sink(receiveCompletion: { completion in
        switch completion {
            case .finished:
                print("successfully authorized application")
            case .failure(let error):
                print("could not authorize application: \(error)")
        }
    })
    .store(in: &cancellables)

请参阅 authorize 的完整文档。

一旦此发布者成功完成,你的应用程序就已授权,你可以开始向 Spotify Web API 发出请求。 访问令牌将在必要时自动刷新。 例如:

spotify.search(query: "Pink Floyd", categories: [.track])
    .sink(
        receiveCompletion: { completion in
            print(completion)
        },
        receiveValue: { results in
            print(results)
        }
    )
    .store(in: &cancellables)

此授权过程已在此示例命令行应用中实现。 所有接口的完整文档可以在 这里 找到。 还建议阅读 Spotify Web API 参考文档