Peter-Schorn / SpotifyAPIExampleApp

An Example App that demonstrates the usage of SpotifyAPI.
23 stars 8 forks source link

SpotifyAPIExampleApp

An Example App that demonstrates the usage of SpotifyAPI, a Swift library for the Spotify web API.

Requires Xcode 12 and iOS 14.

The following was written for the main branch; differences between it and the other branches may not be reflected here.

Setup

To compile and run this application, go to https://developer.spotify.com/dashboard/login and create an app. Take note of the client id and client secret. Then click on "edit settings" and add the following redirect URI:

spotify-api-example-app://login-callback

Next, set the CLIENT_ID and CLIENT_SECRET environment variables in the scheme:

Screen Shot 2021-06-10 at 8 36 45 PM

To expirement with this app, add your own views to the List in ExamplesListView.swift.

How the Authorization Process Works

This app uses the Authorization Code Flow to authorize with the Spotify web API.

The first step in setting up the authorization process for an app like this is to register a URL scheme for your app. To do this, navigate to the Info tab of the target inside your project and add a URL scheme to the URL Types section. For this app, the scheme spotify-api-example-app is used.

Screen-Shot-2020-10-20-at-3-38-06-AM

When another app, such as the web broswer, opens a URL containing this scheme (e.g., spotify-api-example-app://login-callback), the URL is delivered to this app to handle it. This is how your app receives redirects from Spotify.

The next step is to create the authorization URL using AuthorizationCodeFlowManager.makeAuthorizationURL(redirectURI:showDialog:state:scopes:) and then open it in a browser or web view so that the user can login and grant your app access to their Spotify account. In this app, this step is performed by Spotify.authorize(), which is called when the user taps the login button in LoginView.swift:

IMG-67-DE87-F2410-C-1

When the user presses "agree" or "cancel", the system redirects back to this app and calls the onOpenURL(perform:) view modifier in Rootview.swift, which calls through to the handleURL(_:) method directly below. After validating the URL scheme, this method requests the access and refresh tokens using AuthorizationCodeFlowManager.requestAccessAndRefreshTokens(redirectURIWithQuery:state:), the final step in the authorization process.

When the access and refresh tokens are successfully retrieved, the SpotifyAPI.authorizationManagerDidChange PassthroughSubject emits a signal. This subject is subscribed to in the init method of Spotify. The subscription calls Spotify.authorizationManagerDidChange() everytime this subject emits. This method saves the authorization information to persistent storage in the keychain and sets the @Published var isAuthorized property of Spotify to true, which dismisses LoginView and allows the user to interact with the rest of the app.

A subscription is also made to SpotifyAPI.authorizationManagerDidDeauthorize, which emits every time AuthorizationCodeFlowManagerBase.deauthorize() is called.

Every time the authorization information changes (e.g., when the access token, which expires after an hour, gets refreshed), Spotify.authorizationManagerDidChange() is called so that the authorization information in the keychain can be updated. When the user taps the logoutButton in Rootview.swift, AuthorizationCodeFlowManagerBase.deauthorize() is called, which causes SpotifyAPI.authorizationManagerDidDeauthorize to emit a signal, which, in turn, causes Spotify.authorizationManagerDidDeauthorize() to be called.

See Saving authorization information to persistent storage.

The next time the app is quit and relaunched, the authorization information will be retrieved from the keychain in the init method of Spotify, which prevents the user from having to login again.