- Coding An App For Spotify In Swift Performance
- Coding An App For Spotify In Swift Cd
- Spotify App For Android
- Music Spotify App
- Coding An App For Spotify In Swift Free
The very initiative with which Swift was created was Apple’s “Anyone Can Code”. Clearly, if you’re looking to get started in app development, Swift is your best programming language. Some of the best apps you’ve heard of including Uber, Lyft, Square and Airbnb use Swift as their primary programming language for iOS apps. How to use audio and background play in Swift using Xcode. In this iOS Development Tutorial we will see how to use audio in iPhone apps including what classes you need to import, how to import.
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.
- Completion handlers
URLSession
DispatchQueue
- Retain cycles
Coding An App For Spotify In Swift Performance
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
.
Coding An App For Spotify In Swift Cd
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
Spotify App For Android
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.
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.
Third: decide where in your view controller you would like to call the function. In my example, I call it in viewDidLoad
.
Music Spotify App
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
:
Coding An App For Spotify In Swift Free
Gosh, we made it! Thanks for sticking with me.