用 Swift 4.2 编写
Spartan 是一个轻量级、优雅且易于使用的 Spotify Web API 包装库,用于 iOS 和 macOS,用 Swift 3 编写。在底层,Spartan 会对 Spotify Web API 发送请求。这些请求随后被转换为干净、友好且易于使用的对象。
本库允许您做什么
✅ 执行 Spotify Web API 允许的任何请求。
本库无法做什么
❌ 授权流程,该流程可帮助您获取授权令牌。您可以使用 Spotify iOS SDK 来处理这一点。
需求
- iOS 9.0+ / macOS 10.11+
- xCode 9.0+
安装
CocoaPods
要使用CocoaPods将Spartan集成到您的xCode项目中,请在您的Podfile
中指定它。
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0' # If you targeting iOS
platform :osx, '10.11' # If you targeting macOS
use_frameworks!
pod 'Spartan'
然后,请运行以下命令
$ pod install
这将下载您项目中尚未包含的任何库依赖项。
用法
Spartan属性
授权令牌
public static var authorizationToken: String?
这是每个需要OAuth认证的请求中包含的令牌。如果您发出的请求需要OAuth,而这个令牌是null、无效或已过期,则请求将失败。如果您不打算发出需要OAuth认证的请求,则可以将此留为nil
。
每次刷新令牌时,只需更新它即可
Spartan.authorizationToken = newToken
日志记录
public static var loggingEnabled: Bool = true
启用后,在请求开始之前和在请求完成后,将在控制台打印出有用的语句。
一个成功的请求将类似于以下内容
🔵 [SpartanRequestLogger] GET https://api.spotify.com/v1/me
⚪️ [SpartanRequestLogger] GET https://api.spotify.com/v1/me (200 OK) 0.140969038009644 seconds
失败的/无效的请求可能看起来是这样的
🔵 [SpartanRequestLogger] GET https://api.spotify.com/v1/me
🔴 [SpartanRequestLogger] GET https://api.spotify.com/v1/me (401 Unauthorized) 0.81086003780365 seconds
您可以在代码中的任何位置、任何时间简单地通过以下方式启用/禁用此功能
Spartan.loggingEnabled = true/false
核心
有关每个请求的更多信息,请点击与之关联的链接。Spotify为它们支持的每个api请求提供了出色的文档。Spartan几乎支持Spotify允许的所有查询参数字段。
分页对象
相当多的请求会返回一个分页对象
。这是一个基于偏移量的分页对象,用作一组对象的容器。它包含一个名为items的键,其值是请求的对象的数组。它可以用来获取未来调用中之前的一组项目或下一组项目。
例如
_ = Spartan.search(query: "Five for Fighting", type: .track, success: { (pagingObject: PagingObject<Track>) in
self.pagingObject = pagingObject
}, failure: { (error) in
print(error)
})
稍后,如果您需要加载数据(滚动到UITableView/UICollectionView的底部等),则可以使用这两种方法加载数据/重新加载数据
获取下一个
if pagingObject.canMakeNextRequest {
pagingObject.getNext(success: { (pagingObject) in
// Update the paging object
self.pagingObject = pagingObject
}, failure: { (error) in
print(error)
})
}
获取上一个
if pagingObject.canMakePreviousRequest {
pagingObject.getPrevious(success: { (pagingObject) in
// Update the paging object
self.pagingObject = pagingObject
}, failure: { (error) in
print(error)
})
}
请求
获取专辑
_ = Spartan.getAlbum(id: albumId, market: .us, success: { (album) in
// Do something with the album
}, failure: { (error) in
print(error)
})
获取多个专辑
_ = Spartan.getAlbums(ids: albumIds, market: .us, success: { (albums) in
// Do something with the albums
}, failure: { (error) in
print(error)
})
获取一个专辑的曲目
_ = Spartan.getTracks(albumId: albumId, limit: 20, offset: 0, market: .us, success: { (pagingObject) in
// Get the tracks via pagingObject.items
}, failure: { (error) in
print(error)
})
获取一个艺术家
_ = Spartan.getArtist(id: artistId, success: { (artist) in
// Do something with the artist
}, failure: { (error) in
print(error)
})
获取多个艺术家
_ = Spartan.getArtists(ids: artistIds, success: { (artists) in
// Do something with the artists
}, failure: { (error) in
print(error)
})
获取一个曲目
_ = Spartan.getTrack(id: track, market: .us, success: { (track) in
// Do something with the track
}, failure: { (error) in
print(error)
})
获取多个曲目
_ = Spartan.getTracks(ids: trackIds, market: .us, success: { (tracks) in
// Do something with the tracks
}, failure: { (error) in
print(error)
})
获取一个艺术家的专辑
_ = Spartan.getArtistAlbums(artistId: artistId, limit: 20, offset: 0, albumTypes: [.album, .single, .appearsOn, .compilation], market: .us, success: { (pagingObject) in
// Get the albums via pagingObject.items
}, failure: { (error) in
print(error)
})
获取艺术家的热门曲目
_ = Spartan.getArtistsTopTracks(artistId: artistId, country: .us, success: { (tracks) in
// Do something with the tracks
}, failure: { (error) in
print(error)
})
获取艺术家的相关艺术家
_ = Spartan.getArtistsRelatedArtists(artistId: artistId, success: { (artists) in
// Do something with the artists
}, failure: { (error) in
print(error)
})
搜索专辑
_ = Spartan.search(query: query, type: .album, success: { (pagingObject: PagingObject<SimplifiedAlbum>) in
// Get the albums via pagingObject.items
}, failure: { (error) in
print(error)
})
搜索艺术家
_ = Spartan.search(query: query, type: .artist, success: { (pagingObject: PagingObject<SimplifiedArtist>) in
// Get the artists via pagingObject.items
}, failure: { (error) in
print(error)
})
搜索播放列表
_ = Spartan.search(query: query, type: .playlist, success: { (pagingObject: PagingObject<SimplifiedPlaylist>) in
// Get the playlists via pagingObject.items
}, failure: { (error) in
print(error)
})
搜索曲目
_ = Spartan.search(query: query, type: .track, success: { (pagingObject: PagingObject<SimplifiedTrack>) in
// Get the tracks via pagingObject.items
}, failure: { (error) in
print(error)
})
获取用户资料
_ = Spartan.getUser(id: userId, success: { (user) in
// Do something with the user
}, failure: { (error) in
print(error)
})
获取某轨的音频分析
_ = Spartan.getAudioAnaylsis(trackId: trackId, success: { (audiAnalysis) in
// Do something with the audio analysis
}, failure: { (error) in
print(error)
})
获取某轨的音频特征
_ = Spartan.getAudioFeatures(trackId: trackId, success: { (audioFeaturesObject) in
// Do something with the audio features object
}, failure: { (error) in
print(error)
})
获取某轨的音频特征
_ = Spartan.getAudioFeatures(trackId: trackId, success: { (audioFeaturesObject) in
// Do something with the audio features object
}, failure: { (error) in
print(error)
})
获取多个音频特征
_ = Spartan.getAudioFeatures(trackIds: trackIds, success: { (audioFeaturesObject) in
// Do something with the audio features objects
}, failure: { (error) in
print(error)
})
获取精选播放列表列表
_ = Spartan.getFeaturedPlaylists(locale: locale, country: .us, timestamp: timestamp, limit: 20, offset: 0, success: { (featuredPlaylistsObject) in
// Do something with the featured playlists object
}, failure: { (error) in
print(error)
})
获取新发行列表
_ = Spartan.getNewReleases(country: .us, limit: 20, offset: 0, success: { (pagingObject) in
// Get the albums via pagingObject.items
}, failure: { (error) in
print(error)
})
获取分类列表
_ = Spartan.getCategories(success: { (pagingObject) in
// Get the categories via pagingObject.items
}, failure: { (error) in
print(error)
})
获取某一分类的播放列表
_ = Spartan.getCategorysPlaylists(categoryId: categoryId, locale: locale, country: .us, limit: 20, offset: 0, success: { (pagingObject) in
// Get the playlists via pagingObject.items
}, failure: { (error) in
print(error)
})
获取当前用户的信息
_ = Spartan.getMe(success: { (user) in
// Do something with the user object
}, failure: { (error) in
print(error)
})
获取用户关注的艺术家
_ = Spartan.getMyFollowedArtists(success: { (pagingObject) in
// Get artists via pagingObject.items
}, failure: { (error) in
print(error)
})
关注艺术家
_ = Spartan.follow(ids: artistIds, type: .artist, success: {
// Artists are now followed
}, failure: { (error) in
print(error)
})
关注用户
_ = Spartan.follow(ids: userIds, type: .user, success: {
// Users are now followed
}, failure: { (error) in
print(error)
})
取消关注艺术家
_ = Spartan.unfollow(ids: artistIds, type: .artist, success: {
// Artists are now unfollowed
}, failure: { (error) in
print(error)
})
取消关注用户
_ = Spartan.unfollow(ids: userIds, type: .user, success: {
// Users are now unfollowed
}, failure: { (error) in
print(error)
})
检查当前用户是否关注艺术家
_ = Spartan.getIsFollowing(ids: artistIds, type: .artist, success: { (followingBools) in
// Do something with the followingBools
}, failure: { (error) in
print(error)
})
检查当前用户是否关注用户
_ = Spartan.getIsFollowing(ids: userIds, type: .user, success: { (followingBools) in
// Do something with the followingBools
}, failure: { (error) in
print(error)
})
关注播放列表
_ = Spartan.followPlaylist(ownerId: ownerId, playlistId: playlistId, isPublic: true, success: {
// Playlist is now followed
}, failure: { (error) in
print(error)
})
取消关注播放列表
_ = Spartan.unfollowPlaylist(ownerId: ownerId, playlistId: playlistId, success: {
// Playlist is now unfollowed
}, failure: { (error) in
print(error)
})
获取用户保存的歌曲
_ = Spartan.getSavedTracks(limit: 20, offset: 0, market: .us, success: { (pagingObject) in
// Get the saved tracks via pagingObject.items
}, failure: { (error) in
print(error)
})
保存用户收藏的曲目
_ = Spartan.saveTracks(trackIds: trackIds, success: {
// Tracks are now saved
}, failure: { (error) in
print(error)
})
删除用户的收藏曲目
_ = Spartan.removeSavedTracks(trackIds: trackIds, success: {
// Tracks are now removed
}, failure: { (error) in
print(error)
})
检查用户的收藏曲目
_ = Spartan.tracksAreSaved(trackIds: trackIds, success: { (savedBools) in
// Do something with the savedBools
}, failure: { (error) in
print(error)
})
获取当前用户收藏的专辑
_ = Spartan.getSavedAlbums(limit: 20, offset: 0, market: .us, success: { (pagingObject) in
// Get the saved albums via pagingObject.items
}, failure: { (error) in
print(error)
})
保存专辑给用户
_ = Spartan.saveAlbums(albumIds: albumIds, success: {
// Albums are now saved
}, failure: { (error) in
print(error)
})
删除用户收藏的专辑
_ = Spartan.removeSavedAlbums(albumIds: albumIds, success: {
// Albums are now removed
}, failure: { (error) in
print(error)
})
检查用户收藏的专辑
_ = Spartan.albumsAreSaved(albumIds: albumIds, success: { (savedBools) in
// Do something with the savedBools
}, failure: { (error) in
print(error)
})
获取用户的顶级艺术家和歌曲
_ = Spartan.albumsAreSaved(albumIds: albumIds, success: { (savedBools) in
// Do something with the savedBools
}, failure: { (error) in
print(error)
})
检查用户的已保存专辑
_ = Spartan.albumsAreSaved(albumIds: albumIds, success: { (savedBools) in
// Do something with the savedBools
}, failure: { (error) in
print(error)
})
获取用户的顶级艺术家
_ = Spartan.getMyTopArtists(limit: 20, offset: 0, timeRange: .mediumTerm, success: { (pagingObject) in
// Get the artists via pagingObject.items
}, failure: { (error) in
print(error)
})
获取用户的顶级歌曲
_ = Spartan.getMyTopTracks(limit: 20, offset: 0, timeRange: .mediumTerm, success: { (pagingObject) in
// Get the tracks via pagingObject.items
}, failure: { (error) in
print(error)
})
获取用户播放列表列表
_ = Spartan.getUsersPlaylists(userId: userId, limit: 20, offset: 0, success: { (pagingObject) in
// Get the playlists via pagingObject.playlists
}, failure: { (error) in
print(error)
})
获取当前用户播放列表列表
_ = Spartan.getMyPlaylists(limit: 20, offset: 0, success: { (pagingObject) in
// Get the playlists via pagingObject.items
}, failure: { (error) in
print(error)
})
获取播放列表
_ = Spartan.getUsersPlaylist(userId: userId, playlistId: playlistId, fields: fields, market: .us, success: { (playlist) in
// Do something with the playlist
}, failure: { (error) in
print(error)
})
获取播放列表中的歌曲
_ = Spartan.getPlaylistTracks(userId: userId, playlistId: playlistId, limit: 20, offset: 0, fields: fields, market: .us, success: { (pagingObject) in
// Get the playlist tracks via pagingObject.items
}, failure: { (error) in
print(error)
})
创建播放列表
_ = Spartan.createPlaylist(userId: userId, name: name, isPublic: true, isCollaborative: true, success: { (playlist) in
// Do something with the playlist
}, failure: { (error) in
print(error)
})
更改播放列表的详细信息
_ = Spartan.changePlaylistDetails(userId: userId, playlistId: playlistId, name: name, isPublic: false, isCollaborative: false, success: {
// The playlist details are now changed
}, failure: { (error) in
print(error)
})
向播放列表添加歌曲
_ = Spartan.addTracksToPlaylist(userId: userId, playlistId: playlistId, trackUris: trackUris, success: { (snapshot) in
// Do something with the snapshot
}, failure: { (error) in
print(error)
})
从播放列表中删除歌曲
_ = Spartan.removeTracksFromPlaylist(userId: userId, playlistId: playlistId, trackUris: trackUris, success: { (snapshot) in
// Do something with the snapshot
}, failure: { (error) in
print(error)
})
重新排列播放列表中的歌曲
_ = Spartan.reorderPlaylistsTracks(userId: userId, playlistId: playlistId, rangeStart: rangeStart, rangeLength: rangeLength, insertBefore: insertBefore, snapshotId: snapshotId, success: { (snapshot) in
// Tracks are now reordered
}, failure: { (error) in
print(error)
})
替换播放列表中的歌曲
_ = Spartan.replacePlaylistsTracks(userId: userId, playlistId: playlistId, trackUris: trackUris, success: {
// Tracks are now replaced in playlist
}, failure: { (error) in
print(error)
})
检查用户是否 关注 播放列表
_ = Spartan.getUsersAreFollowingPlaylists(ownerId: ownerId, playlistId: playlistId, userIds: userIds, success: { (followings) in
// Do something with the followings
}) { (error) in
print(error)
}
处理错误
SpartanError对象包含一个类型和错误信息,以帮助确定发生了何种错误。
public class SpartanError: NSObject, Mappable {
private(set) open var type: SpartanErrorType!
private(set) open var errorMessage:String!
}
如果请求成功但无效,errorMessage将是从Spotify直接返回的错误信息。
例如,如果Spotify的错误响应是
{
"error": {
"status": 401,
"message": "Invalid access token"
}
}
失败回调中的SpartanError对象将是
_ = Spartan.getMe(success: { (user) in
}, failure: { (error) in
print(error.errorType) // .unauthorized
print(error.errorMessage) // "Invalid access token"
})
所以,如果你的访问令牌已过期,你可以这样做
_ = Spartan.getMe(success: { (user) in
}, failure: { (error) in
if error.errorType == .unauthorized {
// Refresh your access token and try again
}
})
库依赖
- Alamofire:Swift中的优雅HTTP网络连接
- AlamofireObjectMapper:Alamofire的扩展,可以将JSON转换为Swift对象
使用信息及限制
由于Spartan建立在Spotify Web API之上,点击此处获取更多信息
作者
Dalton Hinterscher,[email protected]
许可证
Spartan受MIT许可证保护。有关更多信息,请参阅LICENSE文件。