All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Fixed a bug in which certain characters, such as the
+
character, were not being properly percent-encoded inDictionary.formURLEncoded()
. See #70.
- Added
SpotifyAPI.audiobookChapters(_:market:limit:offset:)
. SpotifyAPI.currentUserSavedAudiobooks(limit:offset:)
now returns the correct type:PagingObject<Audiobook>
instead ofPagingObject<SavedAudiobook>
.- Removed
SpotifyAPI.removeSpecificOccurrencesFromPlaylist(_:of:)
because it is no longer possible to remove items at specific indices from a playlist. ClientCredentialsFlowBackendManager
now actually conforms toHashable
(it already implemented the required methods, but never explicitly declared the conformance)- Removed market parameter from
SpotifyAPI.removeSavedAudiobooksForCurrentUser
- Removed market parameter from
SpotifyAPI.currentUserSavedShows
- Changed type of
PlaylistItem.name
fromString
toString?
- Removed "Currently, there is a bug in the web API in which the market parameter must be provided, or a 500 server error will be returned. It must be set to "US"." doc comment for
SpotifyAPI.chapter
andSpotifyAPI.chapters
. - The following endpoints are now deprecated for new web API applications (see this article):
SpotifyAPI.relatedArtists
SpotifyAPI.recommendations
SpotifyAPI.trackAudioFeatures
SpotifyAPI.tracksAudioFeatures
SpotifyAPI.trackAudioAnalysis
SpotifyAPI.featuredPlaylists
SpotifyAPI.categoryPlaylists
- Made all properties in
Show
andEpisode
optional (except for those with default values). Show
andEpisode
no longer conform toSpotifyURIConvertible
.- Replaced
SpotifyAPI.usersFollowPlaylist(_:userURIs:)
withSpotifyAPI.currentUserFollowsPlaylist(_:)
because this endpoint now only works with the current user. - Fixed bug in
SpotifyAPI.extendPagesConcurrently(_:maxExtraPages:)
in which no extra pages would be retrieved ifmaxExtraPages
was set to1
. - Changed type of
releaseDate
for all objects in object model fromDate?
toString?
- Removed "Audiobooks are only available for the US market" from the following methods:
SpotifyAPI.audiobook
SpotifyAPI.audiobooks
SpotifyAPI.chapter
SpotifyAPI.chapters
- Fixed a bug where the Spotify ids were not being sent in the correct format in the following methods (see #66):
SpotifyAPI.saveAlbumsForCurrentUser
SpotifyAPI.removeSavedAlbumsForCurrentUser
SpotifyAPI.saveEpisodesForCurrentUser
SpotifyAPI.removeSavedEpisodesForCurrentUser
SpotifyAPI.saveShowsForCurrentUser
SpotifyAPI.removeSavedShowsForCurrentUser
SpotifyAPI.saveTracksForCurrentUser
SpotifyAPI.removeSavedTracksForCurrentUser
- Made all TrackLink properties
nil
. Will never fail to decode TrackLink again.
- Fixed a bug that caused
extendPagesConcurrently
to only return the initial page of results
- Fixed a bug that causes a runtime crash in
extendPagesConcurrently
when the "limit" property of the Paginig Object is 0.
- Moved
SpotifyExampleContent
target to a new library with the same name. This will reduce the size of the resource bundle for clients who do not need this library. - Fixed a bug that caused a decoding error when decoding Playlists with a value of null for the image key in the JSON payload.
- Added a
maxRetryDelay
property toSpotifyAPI
that defines the total accumulated retry delay before the library will fail with an error (default: 3 minutes).
- PagingObject now supports an "items" payload will null values.
SpotifyUser.uri
is now percent-decoded, which prevents this value from being double percent-encoded when passed in to otherSpotifyAPI
methods. See here for more details.
- Decoding of
PagingObject
from JSON data is now more lenient.
- Fixed bug with URI parsing in which underscores were not allowed in ids. See #42 for more details.
-
Added new endpoints for retrieving audiobooks and audiobook chapters:
-
SpotifyAPI.audiobook(_:market:)
-
SpotifyAPI.audiobooks(_:market:)
-
SpotifyAPI.chapter(_:market:)
-
SpotifyAPI.chapters(_:market:)
-
-
Added a new endpoint for retrieving the user's queue:
SpotifyAPI.queue()
. -
Added new types to the object model:
Audiobook
,AudiobookChapter
,AudiobookAuthor
, andSpotifyQueue
. -
The
SpotifyAPI.search(query:categories:market:limit:offset:includeExternal:)
method now supports audiobooks. Addedaudiobooks
property toSearchResult
, which is returned by this method. Also, removednext
property fromSearchResult
. -
SpotifyAPI.categoryPlaylists(_:country:limit:offset:)
now returnsAnyPublisher<PagingObject<Playlist<PlaylistItemsReference>?>, Error>
instead ofAnyPublisher<PagingObject<Playlist<PlaylistItemsReference>>, Error>
(thePlaylist<PlaylistItemsReference>
is now optional). This fixes decoding errors. -
Added
totalTracks
toAlbum
. -
Added
htmlDescription
andrestrictions
toEpisode
. -
Added
htmlDescription
toShow
. -
Removed support for Swift 5.1 and 5.2 by deleting the
swift-5-1
branch, which had not been maintained for a long time. -
Added
Audiobooks
andChapters
toURIs
inSpotifyExampleContent
. -
Added the following sample data to
SpotifyExampleContent
:-
Audiobook.harryPotterAndTheSorcerersStone
-
Audiobook.enlightenmentNow
-
Audiobook.freeWill
-
AudiobookChapter.freeWillChapter1
-
AudiobookChapter.steveJobsChapter1
-
AudiobookChapter.enlightenmentNowChapter3
-
SpotifyQueue.sampleQueue
-
-
Added
audiobook
andchapter
toIDCategory
.
- Fixed bugs with retrieving additional pages of results when using
SpotifyAPI.currentUserFollowedArtists
,SpotifyAPI.categories
, andSpotifyAPI.categoryPlaylists
.
- Fixed Bug with decoding playback when context is saved tracks ("liked songs")
- Added
collection
toIDCategory
. SpotifyContext.type
is decoded tounknown
if the string in the JSON payload does not match any of theIDCategory
raw values.- Updated URLs
- When decoding calendar dates for
Album.releaseDate
orEpisode.releaseDate
, if the format of the date-string is invalid, then these properties will be set tonil
instead of the decoder throwing an error.
- Added support for docc documentation.
- Added
ad
toIDCategory
. This can be returned forCurrentlyPlayingContext.itemType
, which indicates the user is currently listening to an ad.
- Three new authorization managers have been added:
AuthorizationCodeFlowBackendManager
,AuthorizationCodeFlowPKCEBackendManager
, andClientCredentialsFlowBackendManager
.AuthorizationCodeFlowManager
,AuthorizationCodeFlowPKCEManager
, andClientCredentialsFlowManager
have been refactored to inherit from these classes, respectively. The former three classes are generic over a backend. This backend can handle the process of retrieving the authorization information either directly from Spotify or via a custom backend server that makes requests to Spotify on behalf of your frontend app. This allows you to store sensitive credentials, such as your client id and client secret securely on your backend server, thereby preventing them from being exposed directly in your frontend app. - Three new protocols have been added:
AuthorizationCodeFlowBackend
. Conforming types:AuthorizationCodeFlowClientBackend
andAuthorizationCodeFlowProxyBackend
.AuthorizationCodeFlowPKCEBackend
. Conforming types:AuthorizationCodeFlowPKCEClientBackend
andAuthorizationCodeFlowPKCEProxyBackend
.ClientCredentialsFlowBackend
. Conforming types:ClientCredentialsFlowClientBackend
andClientCredentialsFlowProxyBackend
.
- Removed the
networkAdaptor
property from the authorization managers. If you need to use a custom networking client, then create a type that conforms to one of the backend protocols inSources/SpotifyWebAPI/Authorization/Backends/AuthorizationBackends.swift
based on which authorization method you are using.
SpotifyAPILogHandler
is no longer automatically bootstrapped when an instance ofSpotifyAPI
is created. You now must call itsbootstrap
method manually. This allows you to select a different logging backend, if needed.- Removed
clientSecret
fromAuthorizationCodeFlowPKCEManager
because it is not needed. SpotifyAuthenticationError.errorDescription
is now optional because it can be missing in the JSON payload in rare cases.- Removed all deprecated symbols.
- Publisher extensions where the output is
URLResponse
are now extensions where the output isHTTPURLResponse
. Other methods that returnedURLResponse
, such asSpotifyAPI.filteredPlaylist(_:filters:additionalTypes:market:)
, now also returnHTTPURLResponse
. - Refactored
ContextOption
andOffsetOption
as nested types underPlaybackRequest
(Context
andOffset
). - Added
type
property toPlaylist
. - Changed the type of properties in the object model that represent URLs from String to URL.
SpotifyAPI.getFromHref(_:responseType)
now accepts a URL as well instead of a string. String.makeCodeChallenge()
is now a static method that accepts the coder verifier as a parameter:String.makeCodeChallenge(codeVerifier:)
.- Removed the + and += operators from
Dictionary
. - The custom
URLComponents
andURL
initializers are now internal. - The
scopes
properties ofAuthInfo
and the authorization managers are non-optional. Instead, the lack of scopes is represented by an empty set. - Renamed
SpotifyLocalError
toSpotifyGeneralError
. - Renamed
SpotifyLocalError.httpError(HTTPURLResponse:Data)
toSpotifyLocalError.httpError(Data:HTTPURLResponse)
- Renamed
SpotifyAPI.removeAllOccurencesFromPlaylist(_:of:snapshotId:)
toSpotifyAPI.removeAllOccurrencesFromPlaylist(_:of:snapshotId:)
. - Renamed
SpotifyAPI.removeSpecificOccurencesFromPlaylist(_:of:)
toSpotifyAPI.removeSpecificOccurrencesFromPlaylist(_:of:)
. - Renamed
SpotifyDecodingError.dataDumpfolder
todataDumpFolder
.
- Fixed a bug that caused a compilation error in Swift 5.4. See here.
- Added
SpotifyLocalError.httpError(HTTPURLResponse, Data)
. This error is returned when the status code of the response from the server is in the 4xx or 5xx range and the response body could not be decoded into any of the other errors types (SpotifyAuthenticationError
,SpotifyError
,SpotifyPlayerError
).
- A request will be automatically retried up to three times if it returns a
SpotifyLocalError.httpError
with a status code of 500, 502, 503, or 504. - When decoding the data from a request into a Swift type, the data will first be decoded into an error object if the status code is in the 4xx or 5xx range.
- Added
SpotifyAPI.currentUserFollowedArtists(after:limit:)
. - Added documentation for each authorization scope that specifies which endpoints the scope is required for.
- Added a
makeCopy
method toClientCredentialsFlowManager
,AuthorizationCodeFlowManager
, andAuthorizationCodeFlowPKCEManager
.
-
Requests will now be automatically retried up to three times depending on the error received:
Retries upon receiving a
RateLimitedError
. If aSpotifyError
orSpotifyPlayerError
is received, then retries if the status code is 500, 502, 503, or 504. -
Added the following endpoints:
SpotifyAPI.currentUserSavedEpisodes(limit:offset:market:)
SpotifyAPI.currentUserSavedEpisodesContains(_:)
SpotifyAPI.saveEpisodesForCurrentUser(_:)
SpotifyAPI.removeSavedEpisodesForCurrentUser(_:)
SpotifyAPI.availableMarkets()
-
Added methods for retrieving additional pages of results concurrently:
SpotifyAPI.extendPagesConcurrently(_:maxExtraPages:)
Publisher.extendPagesConcurrently(_:maxExtraPages:)
-
Added
Publisher.collectAndSortByOffset()
-
SpotifyUser
how has the following additional properties:allowsExplicitContent
andexplicitContentSettingIsLocked
.
- The
before
andafter
cases ofTimeReference
now accept a timestamp string instead of aDate
.TimeReference
has the static methodsbefore(_:)
andafter(_:)
which accept Dates instead and return an instance of self. - Renamed
PlaylistsItemsReference
toPlaylistItemsReference
.
- Fixed a bug where a request to refresh the access token (
refreshTokens(onlyIfExpired:tolerance:
) usingAuthorizationCodeFlowManager
orAuthorizationCodeFlowPKCEManager
failed if the access token was authorized for zero scopes. Compare with 1.4.1.
- Fixed a bug where requesting access and refresh tokens using
AuthorizationCodeFlowManager
orAuthorizationCodeFlowPKCEManager
failed if no authorization scopes where requested.
- Fixed a bug in
AuthorizationCodeFlowManager.==
andAuthorizationCodeFlowPKCEManager.==
: The access tokens were being compared twice and the refresh tokens weren't being compared.
- Added Method for disabling the bootstrapping of
SpotifyAPILogHandler
:SpotifyAPILogHandler.disable
. - Added a new protocol,
ApproximatelyEquatable
, which is conformed to by all types in the object model that have Date or floating point properties or that contain other types with those properties.
SpotifyAPI.search
now throws an error ifcategories
is empty.- When comparing the authorization managers for equality, an absolute tolerance of 1 second (instead of three seconds) is used when comparing the expiration dates.
- Added a network adaptor property to
SpotifyAPI
and the authorization managers. This property allows you to use your own network client for all network requests.
- Fixed a bug in which the value for the "retry-after" header was not retrieved because the library was expecting it to be in uppercase ("Retry-After"), but the Spotify web API returned it in lowercase. The header is now retrieved in a case-insensitive manner.
- Linux is now officially supported (tested on Ubuntu 20.04.1)!
- Fixed a bug in which the port, username, and password components of a URL were removed by the
URL.removingQueryItems()
method, when it should've only removed the query items and fragment. This caused the methods for requesting access and refresh tokens to fail when the redirect URI had these components. The initializers forURL
andURLComponents
now accept a port.
- Removed the
showDialog
parameter fromAuthorizationCodeFlowPKCEManager.makeAuthorizationURL(redirectURI:codeChallenge:state:scopes:)
because it is not actually supported by the Authorization Code Flow with Proof Key for Code Exchange. It is only supported by the Authorization Code Flow. - Removed the period and tilde characters from
String.urlSafeCharacters
because they are reserved in certain components of a URL (although not in the query string, where they will most likely be used).
- Added
RepeatMode.cycled()
- Added public initializers for
CurrentlyPlayingContext
,Device
,PlayHistory
, andSpotifyContext
. - Added CaseIterable conformance to
DeviceType
,SpotifyPlayerError.ErrorReason
, andTimeRange
. Also addedHashable
conformance toTimeRange
.
- Changed the order of the cases in the
RepeatMode
enum fromoff
,track
,context
tooff
,context
,track
, which matches the order that they are cycled through in Spotify clients and inRepeatMode.cycle()
andRepeatMode.cycled()
.
RepeatMode.cycle()
- Cycles between the different repeat modes.
- Fixed typo in
DeviceType.castAudio.rawValue
.
- The refresh token is now optional in the initializers
AuthorizationCodeFlowManager.init(clientId:clientSecret:accessToken:expirationDate:refreshToken:scopes:)
andAuthorizationCodeFlowPKCEManager.init(clientId:clientSecret:accessToken:expirationDate:refreshToken:scopes:)
- Made
Endpoints
enum Public.
- Removed
Publisher.assignToOptional(_:on:)
.
- Added
localizedDescription
toSpotifyLocalError.other
with a default value of "An unexpected error occurred.".
- Added
URIsWithPositionsContainer.init(snapshotId:urisWithSinglePosition:)
andURIsWithPositionsContainer.chunked(urisWithSinglePosition:)
. These methods will aid in removing more than 100 duplicate items from a playlist.
URIsDictWithInsertionIndex
is now publicURIsContainer.init(_:snapshotId:)
andURIsWithPositionsContainer.init(snapshotId:urisWithPositions:)
now have a default value ofnil
for the snapshot id.
- Deprecated
URIsWithPositionsContainer
initializer that accepted an array of tuples.
- Changed docs for
SpotifyAPI.play(_:deviceId:)
to mention that you can provide the id of a non-active device, which will cause the given content to be played on that device. Added a new wiki article: Using the Player Endpoints.
- The URL query parameters for all requests are now sorted. This may improve caching.
SpotifyAPI is out of beta!
- Small documentation changes
- Changed the type of
SpotifyPlayerError.reason
fromString
to an enum:ErrorReason
. This provides additional type safety.
Fixed bugs in which the following methods called the wrong endpoints:
SpotifyAPI.currentUserSavedTracks(limit:offset:market:)
SpotifyAPI.currentUserSavedShowsContains(_:)
All of the methods in SpotifyAPI
are now covered by unit tests!
- Added
SpotifyAPI.authorizationManagerDidDeauthorize
. This publisher emits when thedeauthorize()
method of the authorization manager is called;SpotifyAPI.authorizationManagerDidChange
no longer emits whendeauthorize()
is called.
- Fixed bug in which creating an instance of
SpotifyAPI
usinginit(from:)
did not properly setup the subscription toauthorizationManager.didChange
.
- Fixed a bug with the JSON data being in the incorrect format for the endpoints for following and unfollowing artists and users.
- Fixed a typo in the raw value of
TimeRange.shortTerm
, which caused an "invalid request" error from Spotify.
- Added the following initializers to the authorization managers:
AuthorizationCodeFlowPKCEManager.init(clientId:clientSecret:accessToken:expirationDate:refreshToken:scopes:)
AuthorizationCodeFlowManager.init(clientId:clientSecret:accessToken:expirationDate:refreshToken:scopes:)
ClientCredentialsFlowManager.init(clientId:clientSecret:accessToken:expirationDate:)
These initializers should rarely be needed. They should only be used if the authorization information was retrieved from an external source outside this library. In cases where you simply need to save the authorization information to persistent storage, encode the entire authorization manager instance to data using a JSONEncoder
and then decode the data from storage later. See Saving authorization information to persistent storage for more information.
- Added the prefix "sample" to some of the properties in the
SpotifyExampleContent
module to prevent potential confusion.
- Fixed a bug with the JSON data not being decoded from the
SpotifyAPI.recommendations(_:limit:market:)
endpoint because some of the values were in all uppercase.
- Minor bug fixes and small changes to documentation
- Updated documentation for playing content to mention that shows can be used for
contextURI
. - Simplified the
localizedDescription
for the error objects. The descriptions are now more suitable for the end user. Always use the string representation of the error objects for debugging purposes; only uselocalizedDescription
to display the error to the end user.
- Fixed a bug where the values passed into
SpotifyLocalError.invalidState
were transposed. Edit: Due to a source-control issue, this change was not released in this version. It was released in the next version.
- Fixed bugs for the
SpotifyAPI.showEpisodes(_:market:offset:limit:)
endpoint, which was trying to decode the wrong response type and did not add the id of the show to the query string correctly.
- Added
totalEpisodes
property toShow
, which should've already been added. - Added example
PlaylistItem
s to theSpotifyExampleContent
module.
- The type of
SearchResult.episodes
has been changed fromPagingObject<Episode>?
toPagingObject<Episode?>?
and The type ofSearchResult.shows
has been changed fromPagingObject<Show>?
toPagingObject<Show?>?
. This change was necessary because Spotify can return nil for these properties if the shows and/or episodes are not available in the specified markets.
- Added the
market
parameter toSpotifyAPI.currentPlayback(market:)
and fixed a bug that caused episodes to not be returned. - Renamed
CurrentlyPlayingContext.activeDevice
todevice
because this device is not necessarily active. - Renamed
CurrentlyPlayingContext.currentlyPlayingType
toitemType
because this item is not necessarily currently playing. UseCurrentlyPlayingContext.currentlyPlayingType.isPlaying
to determine if the content is currently playing.
- Added documentation about how omitting the market parameter when using the client credentials flow causes episodes and shows to not be returned.
- Added
SpotifyAPI.filteredPlaylistItems(_:filters:additionalTypes:limit:offset:market:)
. - Added
snapshotId
parameter toSpotifyAPI.removeAllOccurencesFromPlaylist(_:of:snapshotId:)
. - Added
SpotifyPlayerError
; this error object is returned by Spotify when there are errors related to the player endpoints.
- Renamed
SpotifyAPI.filteredPlaylistRequest(_:filters:additionalTypes:market:)
toSpotifyAPI.filteredPlaylist(_:filters:additionalTypes:market:)
. - Renamed
SpotifyAPI.getPlaylistImage(_:)
toSpotifyAPI.playlistImage(_:)
. - Renamed
AlbumGroup
toAlbumType
. - The generic
Item
type ofPlaylistItemContainer
is now optional because the episodes in a playlist will benil
If they were retrieved using the client credentials flow manager and a value for themarket
parameter was not provided or if they are not available in the specifed market.
- Fixed issues with additional types parameter for the playlist endpoints and added clearer documentation to
filteredPlaylist
andfilteredPlaylistItems
. - Fixed bug with decoding of
Album
where both thealbumGroup
andalbumType
properties were being decoded from thealbumGroup
JSON key. - Fixed bug where the incorrect coding key was being used for the
trackNumber
andpreviewURL
properties ofTrack
, causing them to never be decoded from the data and always set tonil
. - Fixed bug where
externalURLs
property ofSpotifyContext
was not being decoded because the JSON key name was incorrect.
- Added support for the Authorization Code Flow with Proof Key for Code Exchange! This is the best option for mobile and desktop applications where it is unsafe to store your client secret. See
AuthorizationCodeFlowPKCEManager
.
- Added
AuthorizationCodeFlowManagerBase
and refactoredAuthorizationCodeFlowManager
to inherit from it.AuthorizationCodeFlowPKCEManager
also inherits from this class. - The methods for retrieving and refreshing tokens now return an error if the expected properties weren't returned from Spotify. This would've caused an error at a later point anyway.
-
Renamed the following symbols
CurrentlyPlayingContext.device
->activeDevice
CurrentlyPlayingContext.item
->currentlyPlayingItem
PlaylistDetails.collaborative
->isCollaborative
SpotifyAPI.getPlaylistCoverImage(_:)
->getPlaylistImage(_:)
SpotifyAPI.search(query:types:market:limit:offset:includeExternal:)
->search(query:categories:market:limit:offset:includeExternal:)
-
The
refreshTokens
method ofClientCredentialsFlowManager
andAuthorizationCodeFlowManager
is now fully synchronized, meaning it is thread-safe. Calling it multiple times concurrently will always result in a single network request being made. Additional calls while a request is still in progress will return a reference to the same publisher as a class instance. -
The
accessToken
,refreshToken
,expirationDate
, andscopes
properties ofAuthorizationCodeFlowManager
and theaccessToken
andexpirationDate
properties ofClientCredentialsFlowManager
are now synchronized, meaning that they are thread-safe.
- Added a wealth of sample data to the
SpotifyExampleContent
module. It includes URIs and various sample objects from the object model. This is particularly useful for SwiftUI Previews. You are highly encouraged to browse the source code for this module to see all of the available sample data.
- Fixed bug in which calling
SpotifyAPI.currentPlayback()
when there were no available devices returned an error because Spotify returned no data. Now,nil
is returned when Spotify returns no data. - Bumped the swift tools version to 5.3 so that resources can be used by this package.
- Changed the name of the "SpotifyURIs" module to "SpotifyExampleContent".
- Added public initializers for all public objects in the object model. This allows clients to create their own examples for testing purposes.
- Renamed the
types
parameter of SpotifyAPI.search tocategories
.
SpotifyAPI.currentPlayback()
now returns an optionalCurrentlyPlayingContext
, which will benil
if no available device was found.
All of the Spotify web API endpoints are now supported!
- Added the following endpoints:
category(_:country:locale:)
- Get a Spotify Categorycategories(country:locale:limit:offset:)
- Get a list of categories used to tag items in Spotify (on, for example, the Spotify player’s “Browse” tab).categoryPlaylists(_:country:limit:offset:)
- Get a list of Spotify playlists tagged with a particular category.featuredPlaylists(locale:country:timestamp:limit:offset:)
- Get a list of featured playlists (shown, for example, on a Spotify player’s “Browse” tab).newAlbumReleases(country:limit:offset:)
- Get a list of new album releases featured in Spotify (shown, for example, on a Spotify player’s “Browse” tab).recommendations(_:limit:market:)
- Get Recommendations Based on Seeds.recommendationGenres()
- Retrieve a list of available genres seeds for recommendations.
- Added
genre
toIDCategory
- Made all the properties of all public objects used in post/put requests (as opposed to objects returned by Spotify) mutable. These objects are:
AttributeRange
TrackAttributes
PlaybackRequest
PlaylistDetails
ReorderPlaylistItems
URIsWithPositionsContainer
URIWithPositions
SpotifyIdentifier
has much more descriptive error messages when identifiers cannot be parsed and improved documentation.
- Refactored SpotifyAPI methods that require either authorization scopes or an access token that was retrieved for a user into conditional extensions where AuthorizationManager conforms SpotifyScopeAuthorizationManager. This new protocol extends SpotifyAuthorizationManager and requires that conforming types support authorization scopes. Currently, only
AuthorizationCodeFlowManager
conforms to this protocol, but a future version of this library will support the Authorization Code Flow with Proof Key for Code Exchange, which will also conform to this protocol.ClientCredentialsFlowManager
is not a conforming type because it does not support authorization scopes. This change provides a compile-time guarantee that you can not call methods that require authorization scopes when using theClientCredentialsFlowManager
. - Refactored
resumePlayback
into two separate methods:resumePlayback(deviceId:)
only resumes the user's current playback.play(_:deviceId:)
(added) plays specific content for the current user. - When multiple asyncronous requests are made to refresh the access token, only one network request will be made. While this request is in progress, additional requests to refresh the access token will receive the same publisher as a class instance.
- If you try to make a request to the Spotify web API before your application is authorized, then a more informative error indicating that you haven't retrieved an access token is returned, instead of one indicating that you haven't retrieved a refresh token.