Wrong Way to Download Images


Threading, Async & Await
Threading Project
9m 13s
7m 43s

The course is part of this learning path

Wrong Way to Download Images

Threading, Async & Await in iOS


Hi. Within this lecture, we're going to go ahead and finish this. We're going to start by doing everything wrong. We're going to download the URL. We're going to show it in the ImageView and we're going to do it in a very wrong way so that we can see what's going on. So, what I'm going to do, I'm going to find some images to download. So, I'm going to go into Google. And I'm going to actually search for something like large image or something so that we can find some big images maybe over 3MB or 4MB, of course, you can try to use your own photos. Just upload anywhere on the Internet or just follow along with me. I believe we can find some large images on Google like this. So, if you hover over the image, you can see the dimensions of this over here. Like I believe this is big. So, let's see. I believe this is big as well. Of course we can download it and just see how many megabytes is as well but like with with eyeballing we can understand whether this is a big picture or not and I believe this should be a big picture. So, I'm going to copy this. And as you can see we can get the URL by copying the image URL. So, make sure you get the image URL somehow because we're going to need it. So, what I'm going to do, I'm going to create an array of the image URLs. So, I'm going to call let urlStrings. Why I'm creating this array because I want to have two images to work upon so that I can change it and see the effects. So, let's find something bigger or even bigger. This is very big actually. So, let me try to open this. And here you go. So, this is like something like 5000 to 5000 dimensions. So, I believe this can be over three to four megabytes. So, this is a very, very big picture to work with. So, that's good. So, that's exactly what we have been looking for so that we can understand if you're downloading it right. So, I can get the image URL. Here we go. So, I'm going to just paste this as the second image. So, right now I have two strings in my urlStrings array. And I'm going to use them both later on. Now, I know which image to download. So first, we can just give the first one then we can add a button and when the user taps on it, we can change the picture. So, what I'm going to do, I'm going to try and show you something. I'm going to just write the ImageView in a correct way and say .image. If we do UIImage as usual, as you can see, there are a couple of options over here, like we can give a system name. We can give a name if we added on our export project and that's it. We can give a cgImage and something like that but we can give data as well. So, working with data is great as long as you get the data in the right format or in a right way, maybe. So, what do I mean by that? So, what is data anyway? So, when we deal with images like downloading images, uploading images, we are not actually downloading like UIImage. So, we are downloading data like bytes, like ones and zeros. So, array of bytes, bytes arrays. So, we are downloading ones and zeros and we are converting it into an image. So, that's exactly the same thing when we are uploading the image as well. That's exactly the same thing when we just saved the image inside of a local database as well. So, you can create a data by saying like data, data like this. So, that's why the name of the classes data and as you can see that's how you can create data with different options. So, what I'm going to do, I'm going to find the contents of because it's asking for a URL. So, this specific parameter, if you try to create a data with the specific parameter, it will actually download the URL and create a data for you. That's exactly what we want. So, I can just open a URL and give it a string. Like this. Inside of this, I can just give my string or we can copy and paste it or we can just use the urlStrings array that we have created. Just put the urlStrings like first element. So, index zero. Now, it's asking whether we want to unwrap the URL because it's giving an optional URL over here since we are using urlString. Now, since we are doing everything wrong, I'm not even going to bother with the if let or don't let. I'm just going to put an ! over here. So, if I give the URL wrong, it will crash but it's not going to happen. It doesn't matter. We're just doing this as an exemplary project and we are doing everything wrong anyway. So, I'm going to put the  ! over here but as you can see, it says that this call can throw. And you haven't actually handled the exceptions or handled the errors as you can see because this data contents of control actually. So, what we're going to do, we can do try catch and I'm not even going to bother with that. I'm just going to do try. Like this try  !. So, I'm doing everything in order to crash this application but it won't crash. I know because we are going to download we're going to be able to download this URL. .Now, but if I have been working on like I had been working on a real project, of course I wouldn't do that. I will just give the do try catch. I would do the guard data and everything. Now, we can give this data to the UIImage. So, that's exactly what it is. We are going to download the data from the Internet using the data class and we're going to just give that data to the ImageView. And let's see if there's something wrong about this. I'm going to open my simulator and wait for a minute in order to just initialize this and here we go. As you can see, it works. now, I can scroll down and up and I can see the image itself. So, even though I did everything wrong, why did it work? So, what did I do wrong by the way, I haven't even dealt with the concurrency at any point. I haven't dealt with the synchronous things like in backgrounds, main thread. I haven't spoken anything about it right now. So, in order to show you the effects in a more efficient way, I'm going to add a new button over here over the navigation bar and we're going to just click it in order to change the picture. So, I'm going to say self.navigationController?.navigationBar. And by navigation bar, I mean the bar that appears over here. I believe we have to specify with the top item and right bar button item. That's exactly what I'm looking for. Of course, it doesn't matter if it's left bar button or right bar button item. I'm going to make this equal to a UIBarButton item. And this UIBarButton item will ask me for the system image, target and the action as usual. So, I believe we have done that before, during the training during this course. So, for the system, I'm just going to choose an icon. It doesn't matter like compose, cancel, add, bookmarks, whatever you want. You can even choose the camera if you want. So, I'm going to go with, I don't know, compose maybe. So, the target will be self as usual and the action will be the function that this is going to be called when this button has been clicked. So, I'm going to say objc fun over here, say changeImage(). And for the change image, I'm going to come over here and say hashtag selector and just give this function name like (changeImage). Not like this but like this. Here, we go, without calling this function, without having parentheses over here. So, when a user taps on this, I'm going to do exactly the same thing. So, I'm going to download another thing right now. So of course, we can create a data over here in order not to create data every time. Let's do that. I'm going to say data over here and delete the left from the viewDidLoad. So, I'm going to work with this data and I'm going to make it equal to exactly the same thing. Actually you can just copy and paste this. So, I'm going to say try! Data (contentsOf: urlString). This time will be the same thing, urlStrings[1]. So, that's it but that's not it, I believe. So, let me just try to change the Image view image as well like UIImage and data. Here we go. I believe that's it. So, we're getting some errors over here. Of course, I forgot to put the URL at the beginning of this urlStrings. So, we're not converting this to a URL. Let me do it like this and put a parentheses at the end like that. But it isn't so great. So, let me see. We have a parentheses missing over here. So, this is not so great because every time I hit on the button, it will just change it once. So, it will change it from the first element to second element and that will be it. So, what I'm going to do, I'm create a tracker or a number or a variable, any variable. And I'm just going to put it over here rather than zero. I'm going to just say [tracker]. So, why I'm doing that because I want to add this in order to just get it to one, like if tracker is zero. I want to increment this and it will be one and else if it's one, then I'm going to just decrement it and it will be zero. So, every time I click on the change image button, it will be changed like that. So, this is a very simple algorithm. If you have watched all the course, I believe you can come up with this yourself as well. So far so good. Now, what is going to happen every time I hit on that change image button. It will change the image. It will download it from scratch. Now, let's see the effect of it right now. I can scroll smoothly. Now let's see what happens when I hit on the button. And remember, we are going to download very big image and as you can see, we cannot scroll. We cannot scroll. It blocked the whole user interface. And once it's downloaded, now I can scroll again. So, it's not surprising because if you're are blocking the main thread, we are doing everything on the user interface on the main threat. So, it's not ideal. Let me try one more time. And as you can see, I cannot scroll down. So, in some telephones or in some iPhones or in some situations, you can even crash the application because it's not ideal to block the user interface. It's not ideal for user experience and it's not ideal for the programming efficiency as well. You can crash the application and even if you don't crash it, no one will use your application if it lags like this. So, it isn't good. So, we're going to have to take care of this ourselves. As you can see, it blocks the whole user interface because we are doing everything on the foreground on the main threat. We have to do this download operation in the background. So, we won't even have to worry about the image size or something like that because once it starts to download, then we can interact with the user interface and it will just show up when it's done. Let's see how to do that in the next lecture together.


About the Author
Learning Paths

Atil is an instructor at Bogazici University, where he graduated back in 2010. He is also co-founder of Academy Club, which provides training, and Pera Games, which operates in the mobile gaming industry.

Covered Topics