Viper & Protocol
VIPER Pattern
PREVIEW12m 24s
9m 29s

The course is part of this learning path

Start course
1h 22m

In this course, we're going to take a look at the VIPER architectural pattern and also protocol-oriented programming, and we're going to start a project which utilizes these methods.

Learning Objectives

  • Understand the fundamentals of the VIPER architectural pattern and protocol-oriented programming
  • Learn how to create VIPER components
  • Learn how to use interactors, view functions, and routers
  • Use VIPER components and protocol-oriented programming to build an app

Intended Audience

This course is intended for anyone who wants to learn how to develop apps on iOS.


To get the most out of this course, some basic knowledge of iOS development would be beneficial. We recommend that you take this course as part of the Developing Mobile Apps for iOS learning path.


Hi. Within this lecture, we're going to continue building our Viper components. So far, we have written the router a little bit but to make it much more clear to you, I believe we need to go ahead and write the presenter, interactor, and the view as well. So, we're going to be focusing on the interactor but it's a good idea to start from the presenter then, we will move on to the other ones. So, I'm just going to write a protocol over here and I'm going to call it AnyPresenter. And of course, this will have a class as well. I'm going to call this CryptoPresenter and this will be an AnyPresenter. So, we will be following these steps for the interactor and the view as well. So, let's think about it; what we will have in the protocol. So, this will be talking to the interactor, the router, and the view as well, So, we will need for the instances or other references of all the components over here. So, I believe we can start by writing those. For example, in the protocol, let's start writing var. router, this will be an AnyRouter. So, I'm going to make them optional so that we don't get an error but as you can see, once I do this, it asks me if I want to make it {get} or {get set}. So, if I want an only read option, then I can just state get, if I want both read and write then I can just make it get set. So, I'm going to make them get set. So, maybe we can just assign the values later on. Here you go. And of course, we are getting the error over here on the downside because we are not conforming to the protocol right now. So, we can actually make it right by adding the stops but also, we're just going to have to say interactor over here even though we don't have it yet. I'm just going to write it because we will be writing that in like a second. So, I'm just going to come over here to interactor and write the protocol over here as usual and I'm going to call this AnyInteractor and obviously, I'm going to create the class as well. I'm going to call this CryptoInteractor. As long as you consider these steps that we are following, they are exactly the same as the previous one. We are creating the protocol. We are creating the class and I'm going to do the same thing in view as well. So, let's call this AnyView. I'm going to call this protocol AnyView and again, this will be our class but this time, this is not only going to be like CryptoView but it's going to be a CryptoViewController because, let's import the UI kit, because this will be a UIViewController as well as the AnyView, So, this is now a UIViewController but I can add any view over here as well. So, I should add UIViewController because this is actually going to be the UIViewController that we will be presenting our views to the user. That's why I did that. And here you go. Once we go back to the presenter, if we do command B. Now, we don't get any errors in the protocol. Now, we get error on the downside but let me add the view over here as well, like our view AnyAnyView with optional get set and now, we are done with the presenter. Any presenter protocol I mean. We're not done yet with the class because we need to add all of those things inside of the class in order to get rid of these error messages. As you can see, we are getting the error messages right now. Because why? Because we are not conforming to the protocol. And we added all of those references because we need to talk to those competence in the presenter. For example, in the interactor, if we're only going to talk with the presenter, then we are only going to add the presenter reference. Furthermore, we need to create a function in the presenter protocol over here because let me just write it and you will understand it immediately. I'm going to call this interactorDidDownloadCryptos. So, why I'm doing this because we are going to download cryptos in the interactor and we need a way to say the presenter. Cryptos are now downloaded so go ahead and alert the view to show these cryptos. So, that is what presenter is doing. The presenter is going to get the idea or get the alert from the interactor. Interactor will say that, "Okay. I downloaded it" and presenter will say to view, "Okay. Now, data is here. Please show it to the user." That's what presenter does. So, we need this function and this function will return as a result. So, remember this result. It will give us either the data or failure, like a success or a failure, data or the error. So, data will be cryptos in a list. Like this okay. List of crypto. An errror will be just an error. Here you go. Of course, we will just make this right when we write the actual interactor. We're going to make it in a way that we're going to just assign these results in the interactor but we know that we are going to download something in the Interactor and we can easily do that. You're going to see what I mean once we go to the interactor if you didn't understand it right now but right now, we complete the protocol. Of course, we need to add the stuffs over here. In order to do that, you can just click on this error message and try to say fix and make the code at the variables and the functions for you or you can just write it yourself. Let me try to hit Fix. For some reason, it added them twice so I'm going to just delete one of them. Here you go. That's all you got to do. Like you have the variables and you have the function over here as well. So once you get the data, you can just write whatever you want to do with it. You can write something like, "Hey, View. Just present this data that I have gotten from the interactor." In order to do that, of course you need to control. You need to check to see if the result is a success or result is a failure. So, if the result is a failure, then maybe you may want to show something to the user like an error message in the view. Since we have the reference of View, we can just say something like view.updateView, but we don't have that functionality yet. We're going to write that later on but we can just do the switch. We can check to see if the result is actually this result is actually a failure or a success. So, I can just come over here and say case.success. It's going to give us the crypto list. I'm going to say cryptos. So if this is the case, again, we're just going to say something like view.update. If the case is a failure case.failure and then it's going to give us an error then we're just going to say view.update again with an error or view just show error, whatever we may want to put in the view. We haven't done it yet so we cannot write it yet. By the way, it asks us to add something over here Since I have already, I have just given a comment but I need to write something like print, update maybe print("error") over here so that it won't give us an error message. Here we go. Now, we're going to update this later on once we finish with the view. But that's it. That's what presenter will do. That's good. But the main thing over here is the interactor because that's where the business logic happens. So, I'm going to open the protocol and just write the presenter over here with a get set because this will be our only variable because this is what the interactor talks. So, what kind of function do we need here? Of course, we need a function in order to download the data. So, we can call this something like downloadCryptos, getCryptos, downloadFromAPI, anything you want. But obviously, we need that so I'm just going to call this downloadCryptos or crypto. Whatever you want and of course after that, we need to apply them over here. We need to add the presenter and also the function as well. So, inside of this function, I'm going to create a URL session and just download it from my GitHub. So, what we need to do over here is to create the URL session. I'm going to say guard let url. So, I'm going to start with the URL so we need the the url string. So, I'm going to share this with you in the resources of this lecture but if you cannot find it, just pause the video right now and see for yourself. You can just write it by looking at it and I'm going to say else and return. So, it means that if this fails then do nothing. Of course this is not going to fail because it's an valid URL, so I'm just going to create a task. I'm going to say URLSession like this URLSession.shared, so for some reason we cannot see the shared, here you go URLSession.shared.dataTask(with: url). Okay great, now, that's not what we need right, because we need the completion block as well. So, let me find this, here you go, with URL with Completion Handler. This one, the bottom one. Here you go this is what I'm looking for. So, I'm going to just click it and hit 'Enter' over here, so this will give me the data, the response and the error as well. So, what we need to do, we need to give some variable names over here. I'm going to call them simply data, response and error. So, I'm going to delete this, add response with a small r, error with like a lowercase e, and here you go. By the way we haven't discussed this much but we can come over here to this data and put weak self like this in front of it, which means that we get to wipe the data from the memory once we change this view and even though we don't have any kind of secondary views or screens in this application. It's a very simple application, we will have in a professional application, most probably. Okay, so it's a good idea to add this weak self in front of the data in order to avoid any memory leaks. It does not have anything to do with the Viper but I just wanted to let you know when I see it. Great, now we have the data and response and we can start by checking to see if the error is nil, if there is a response or something like that. So, I'm just going to come over here and say guard let data = data, error = nil which means that we have the data and we have a nil error. If this isn't the situation, maybe we can just return or handle the error or like show it to the user. And then I'm going to do try catch to just try and parse the response. Okay so over here, of course I'm going to say, let cryptos and use the JSONDecoder with try like this, try JSONDecoder.decode. Great, and the decodable protocol will be Crypto over here with the array itself. Okay. Inside of the array because it starts with the array, as you can see it comes inside of the array and then from data, here you go. Now once we get this we can just pass it to the Presenter actually that's why we have the reference over here. We're getting some error over here saying that, use .self, so we don't have any kind of variable over here. But here we go. We need to add this over there [Crypto].self. Great. Once we have this then we can come over here under the let cryptos we can just pass it through the presenter. So, I can just say self.presenter. let's see InteractorDidDownloadCrypto. Here we go, that's why we have created this. Okay. So, that we can communicate with the presenter inside of the interactor. So, here you go now, it asks for a result then I just can say .success or .failure, of course in this case it's a .success because I get the data, I get the cryptos and I can just pass the cryptos over here. Okay, that's easy. Now, since we can pass the .error as well as a result, let's do that. Let's do that over here and let's do that under the catch. But we can make this into a little bit more complicated scenario and we can actually handle the errors in a correct way. We can create an enum and we can specify the different kind of error messages if we want to. Let's do that in the Presenter, I'm just going to come over here and create an enum and/or enum whatever you may want to call it and I'm going to call this a NetworkError and this will be an Error. So, I just call this NetworkError, you can call it anything you want but we're going to have some different cases over here. Like we can have a network failure or we can have a parsing failure. So, I'm going to call this NetworkFailed, ParsingFailed. Of course you can create some much more variance over here. Like you can add some more detailed error messages as well, but what does it mean NetworkFailed? Maybe the internet connection got lost or something. What does it mean to have a ParsingFailed? It means that we got the data but we couldn't parse it, maybe our entity was wrong, maybe our modelling was wrong, maybe our struck was wrong. For example, if I get the error over here, it means that we didn't even get the data. So, we can safely say that self.presenter.interactorDidDownloadCrypto, and I can just say .failure, and for the error message I can say network error, okay NetworkError.NetworkFailed. So, that's the case that I'm talking about but I can copy and paste it over there and I can just say .ParsingFailed because I got the data but I couldn't parse it, I couldn't use the JSONDecoder in a way that I want, obviously. Great, now I have a more structural way in order to debug this app or just show it to the user later on. So, if you're done over here, don't forget to add the task.resume, otherwise this task won't get even executed. Great. Now actually, we are done with the Interactor, we're not even going to add something later on to this class I believe, or this protocol. So, this will do it's job, it will let the Presenter know and the Presenter will take care of this. So, this will just get the data from the networking service and pass it to the Presenter like this. So, it will talk to the entity, it will get the data, it will pass it to the Presenter, and Presenter will pass it to the View. So, that's what we're trying to do. But of course we don't have the functions in the View yet, so we need to take care of that. But of course this lecture has been too long right now. So, I believe what we need to do, we need to go into the View and finish it in the next lecture. Also, we haven't assigned any values to these routers, interactors and views. I know that; we're going to do that later in the router. So, let's stop here and continue within the next one.


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