Spotify App Using Api Swift
If you are looking to become an iOS developer, there are some fundamental skills worth knowing. First, it's important to be familiar with creating table views. Second, you should know how to populate those table views with data. Third, it's great if you can fetch data from an API and use this data in your table view.
The third point is what we'll cover in this article. Since the introduction of Codable
in Swift 4, making API calls is much easier. Previously most people used pods like Alamofire and SwiftyJson (you can read about how to do that here). Now the Swift way is much nicer out of the box, so there's no reason to download a pod.
Let's go through some building blocks that are often used to make an API call. We'll cover these concepts first, as they are important parts to understanding how to make an API call.
Request for using the spotify web api for a commer. Turn on suggestions. Auto-suggest helps you quickly narrow down your search results by suggesting. Aug 27, 2019 Creating a Spotify API project. First, we need to create a Spotify API project to allow us to authenticate with it. To do that, we head to and login with our Spotify account. Now we have to execute the following steps: On the right top corner clicking on “create a client ID”.
- Completion handlers
URLSession
DispatchQueue
- Retain cycles
Finally we'll put it all together. I'll be using the open source Star Wars API to build this project. You can see my full project code on GitHub.
Disclaimer alert: I am new to coding and am largely self-taught. Apologies if I misrepresent some concepts.
Completion handlers
Remember the episode of Friends where Pheobe is glued to the phone for days waiting to speak with customer service? Imagine if at the very start of that phone call, a lovely person called Pip said: 'Thanks for calling. I have no idea how long you'll need to wait on hold, but I'll call you back when we're ready for you.' It wouldn't have been as funny, but Pip is offering to be a completion handler for Pheobe.
You use a completion handler in a function when you know that function will take a while to complete. You don't know how long, and you don't want to pause your life waiting for it to finish. So you ask Pip to tap you on the shoulder when she's ready to give you the answer. That way you can go about your life, run some errands, read a book, and watch TV. When Pip taps on you on the shoulder with the answer, you can take her answer and use it.
This is what happens with API calls. You send a URL request to a server, asking it for some data. You hope the server returns the data quickly, but you don't know how long it will take. Instead of making your user wait patiently for the server to give you the data, you use a completion handler. This means you can tell your app to go off and do other things, such as loading the rest of the page.
You tell the completion handler to tap your app on the shoulder once it has the information you want. You can specify what that information is. That way, when your app gets tapped on the shoulder, it can take the information from the completion handler and do something with it. Usually what you'll do is reload the table view so the data appears to the user.
Here's an example of what a completion handler looks like. The first example is setting up the API call itself:
Now we want to call the function fetchFilms
. Some things to note:
- You don't need to reference
completionHandler
when you call the function. The only time you referencecompletionHandler
is inside the function declaration. - The completion handler will give us back some data to use. Based on the function we've written above, we know to expect data which is of type
[Film]
. We need to name the data so that we can refer to it. Below I'm using the namefilms
, but it could berandomData
, or any other variable name I'd like.
The code will look something like this:
URLSession
URLSession
is like the manager of a team. The manager doesn't do anything on her own. Her job is to share the work with the people in her team, and they'll get the job done. Her team are dataTasks
. Every time you need some data, write to the boss and use URLSession.shared.dataTask
.
You can give the dataTask
different types of information to help you achieve your goal. Giving information to dataTask
is called initialization. I initialism my dataTasks
with URLs. dataTasks
also use completion handlers as part of their initialization. Here's an example:
dataTasks
use completion handlers, and they always return the same types of information: data
, response
and error
. You can give these data types different names, like (data, res, err)
or (someData, someResponse, someError)
. For the sake of convention, it's best to stick to something obvious rather than go rogue with new variable names.
Let's start with error
. If the dataTask
returns an error
, you'll want to know that upfront. It means you can direct your code to handle the error gracefully. It also means you won't bother trying to read the data and do something with it as there is an error in returning the data.
Below I am handling the error really simply by printing an error to the console and exiting the function. There are many other ways you could handle the error if you wanted to. Think about how fundamental this data is to your app. For example, if you have a banking app and this API call shows users their balance, then you may want to handle the error by presenting a modal to the user that says, 'Sorry, we're experiencing a problem right now. Please try again later.'
Next we look at the response. You can cast the response to be an httpResponse
. That way you can look at the status codes and make some decisions based on the code. For example, if the status code is 404, then you know the page was not found.
The code below uses a guard
to check that two things exist. If both exist, then it allows the code to continue to the next statement after the guard
clause. If either of the statements fail, then we exit the function. This is a typical use case of a guard
clause. You expect the code after a guard clause to be the happy days flow (i.e. the easy flow with no errors).
Finally you handle the data itself. Notice that we haven't used the completion handler for the error
or the response
. That's because the completion handler is waiting for data from the API. If it doesn't get to the data part of the code, there's no need to invoke the handler.
For the data, we are using the JSONDecoder
to parse the data in a nice way. This is pretty nifty, but requires that you have established a model. Our model is called FilmSummary
. If JSONDecoder
is new to you, then have a look online for how to use it and how to use Codable
. It's really simple in Swift 4 and above compared to the Swift 3 days.
In the code below, we are first checking that the data exists. We are pretty sure it should exist, because there are no errors and no strange HTTP responses. Second, we check that we can parse the data we receive in the way we expect. If we can, then we return the film summary to the completion handler. Just in case there is no data to return from the API, we have a fall back plan of the empty array.
So the full code for API call looks like this:
Retain cycles
NB: I am extremely new to understanding retain cycles! Here's the gist of what I researched online.
Retain cycles are important to understand for memory management. Basically you want your app to clean up bits of memory that it doesn't need anymore. I assume this makes the app more performant.
There are lots of ways that Swift helps you do this automatically. However there are many ways that you can accidentally code retain cycles into your app. A retain cycle means that your app will always hold on to the memory for a certain piece of code. Generally it happens when you have two things that have strong pointers to each other.
To get around this, people often use weak
. When one side of the code is weak
, you don't have a retain cycle and your app will be able to release the memory.
For our purpose, a common pattern is to use [weak self]
when calling the API. This ensures that once the completion handler returns some code, the app can release the memory.
DispatchQueue
Xcode uses different threads to execute code in parallel. The advantage of multiple threads means you aren't stuck waiting on one thing to finish before you can move on to the next. Hopefully you can start to see the links to completion handlers here.
These threads seem to be also called dispatch queues. API calls are handled on one queue, typically a queue in the background. Once you have the data from your API call, most likely you'll want to show that data to the user. That means you'll want to refresh your table view.
Table views are part of the UI, and all UI manipulations should be done in the main dispatch queue. This means somewhere in your view controller file, usually as part of the viewDidLoad
function, you should have a bit of code that tells your table view to refresh.
We only want the table view to refresh once it has some new data from the API. This means we'll use a completion handler to tap us on the shoulder and tell us when that API call is finished. We'll wait until that tap before we refresh the table.
Spotify Api Swift
The code will look something like:
viewDidLoad vs viewDidAppear
Finally you need to decide where to call your fetchfilms
function. It will be inside a view controller that will use the data from the API. There are two obvious places you could make this API call. One is inside viewDidLoad
and the other is inside viewDidAppear
.
These are two different states for your app. My understanding is viewDidLoad
is called the first time you load up that view in the foreground. viewDidAppear
is called every time you come back to that view, for example when you press the back button to come back to the view.
If you expect your data to change in between the times that the user will navigate to and from that view, then you may want to put your API call in viewDidAppear
. However I think for almost all apps, viewDidLoad
is sufficient. Apple recommends viewDidAppear
for all API calls, but that seems like overkill. I imagine it would make your app less performant as it's making many more API calls that it needs to.
Combining all the steps
First: write the function that calls the API. Above, this is fetchFilms
. This will have a completion handler, which will return the data you are interested in. In my example, the completion handler returns an array of films.
Second: call this function in your view controller. You do this here because you want to update the view based on the data from the API. In my example, I am refreshing a table view once the API returns the data.
Spotify Api Data
Third: decide where in your view controller you would like to call the function. In my example, I call it in viewDidLoad
.
Fourth: decide what to do with the data from the API. In my example, I am refreshing a table view.
Inside NetworkManager.swift
(this function can be defined in your view controller if you'd like, but I am using the MVVM pattern).
Inside FilmsViewController.swift
:
Gosh, we made it! Thanks for sticking with me.
MusicKit lets users play Apple Music and their local music library from your app or website. When users provide permission to access their Apple Music account, they can use your app or website to create playlists, add songs to their library, and play any of the millions of songs in the Apple Music catalog. If your app detects that the user is not yet an Apple Music member, you can offer a trial from within your app.
Apple Music API
Use the Apple Music API to retrieve information about albums, songs, artists, playlists, music videos, Apple Music stations, ratings, charts, recommendations, and the user’s most recently played content. With proper authorization from the user, you can also create or modify playlists and apply ratings to the user’s content. The API can be used with iOS apps, Android apps, and websites.
Get started. To communicate with the Apple Music service, you’ll need to create a MusicKit identifier and private key to sign your developer tokens using Certificates, Identifiers & Profiles in your Apple Developer Program account.
Request Music Data with the Apple Music API. Let your app search for songs, playlists, artists, and more. Your app can even request music we think your users will love.
iOS Apps
Get details on how to build iOS apps that integrate Apple Music using the Apple Music API, as well as the StoreKit and MediaPlayer frameworks.
Authorize Apple Music with StoreKit. Check if a user has an Apple Music membership to automatically play music, or let them start a trial membership directly within your app.
Control Playback with MediaPlayer. Play any song from Apple Music and access a user’s music library, with their permission.
Android Apps
MusicKit for Android lets you build native Apple Music features into your Android app. Libraries are available to let users sign in to their Apple Music account and play music directly from your app.
Authentication for Apple Music. The Authentication library provides a way to get access tokens to play music or make calls to the MusicKit Web APIs. This library prompts the user to sign in to Apple Music and, if Apple Music isn’t installed on the device, helps the user download it before returning to your app.
Media Playback for Apple Music. The Media Playback library can be used to play songs, albums, and playlists on Apple Music without leaving your app. Your app can also control music playback from the lock screen or the background.
Spotify Api Key
Websites
Songs from Apple Music can play directly in the browser. With the Apple Music player, users can stream songs from Apple Music in your website using the default player or one you’ve customized. Add an Apple Music player to your website using JavaScript.