I’m learning how to fetch images from API recently, so I decided to use the website “Unsplash” to practice. Here’s the demo of my project.
What I Learned From This Project:
- More familiar with URLSession
- Display correct images in the cells
- Deal with large amount of images
Let’s get started!
In order to get the JSON from Unsplash, you need to register as a member, and create your own application. After that, you’ll find your keys in the page.
Now we can use the key to get the JSON on the internet.
Want to read this story later? Save it in Journal.
You can use JSON Editor to make it easier to read.
Since I only need the regular size picture from the JSON, here’s my structure for decoding. The reason why I set regularUrl is because I’ll need URL to get the pictures, so I can take it directly instead of converting String to URL when I’m using URLSession to fetch pictures.
There’s only one button on the first page, so I’ll skip it and focus on the second view. I use UICollectionView to show the pictures, and here’s how I set my CollectionView.
In order to get the information from JSON, we have to use URLSession to send request to the server. If everything goes smoothly, you’ll receive decoded data from the server, and you’ll need an array to store it. In this case, my array is pictureInfo: [ImageInfo]()
Now, we can get the information we need from the array, which is the url of the picture. Let’s use URLSession again to fetch the images.
Let’s run the app and see what we got:
It seems like everything is fine, but what if I want to deal with more photos? The function of the add button on the upper right side is to send the request again. Therefore, the members in our pictureInfo array will be increased 30 pics per time. Let’s see what will happen.(Btw, the new images will be the same as the previous ones, but I’m not sure why.)
As you can see, if we scroll it quickly, it will display wrong images in the cell. It is because of dequeueReusableCell. We reuse the cell to make the whole app works more efficiently. However, the cell will display whatever it receives without any confirmation. So, we need to do 2 more steps to prevent it from happening again.
First, let’s go to CollectionViewCell and set the image equal to nil in the prepareForReuse function.
Then we need to see if the url we request is the same as the one comes back from the server. So let’s change a little bit of the function and add it to a new class.
In the class, we need to declare a url to see if the request one and the back one is the same. In the function, let’s say self.url equal to the parameter url, then send a request to server to get the photo. Please note that in line 21, we’ll see if the 2 urls are the same. If they are, then let self.image equal to the one we get from the server, otherwise do nothing.
Remember to set the class to the ImageView in UICollectionViewCell.
We can call the function directly because the class(MyImageView) is a subclass of UIImageView, so let’s call it in cellForItemAt function.
We’re almost done, let’s take a look at what we have now.
Perfect, the cell displays the correct image once it’s sure the url is the same. But you may notice that some of the images will be black for a while. It’s because every time when we scroll the view, it will send the request to the server, no matter if we have requested it before. It’s kind of wasting time and resource, what can we do to deal with this problem?
Yes, Cache! Cache is a bit similar to dictionary, both of them have “key” and “value”. We can store the image we have requested in the cache, and if we need it, we can take it from cache instead of sending request again. Let’s see how it works.
First, let’s declare NSCache. You can put any type you need in the < >, first one is key, and the second one is the value.
static var cache = NSCache<AnyObject, UIImage>()
Next, let’s see if there’s any image we need in the cache. If there is, then we’ll take it directly(line 18, 19). If not, then we’ll send the request(line 22), and store the image in the cache(line 29).
Run your app, now everything should be perfect.
Here is my Github for this project:
I hope this article will be helpful for someone who is not that familiar with API and handing images from internet. If there’s any comment, please leave your massage. Thanks!