Join Károly Nyisztor for an in-depth discussion in this video Completing the network controller, part of Swift 4: Protocol-Oriented Programming.
- [Instructor] As per API documentation, we expect JSON data in the payload. I'm going to rely on the JSON parsing capabilities introduced with Sys4. We can map JSON payloads to objects that have a similar structure without writing a single line of code. All we have to do is define the objects that match the JSON structure. So I went ahead and created the structures for the OpenWeatherMap service payload to save us some time. Let's add this file to the project.
So I select the Networking group, right-click on it, and choose Add Files to "Weather App". From the AddOn folders, I pick up the mappings file, and add it to our project. As you can see, so these are the structures that match the JSON payload. The property names and their type must match the corresponding keys and values in the JSON structure. Now, let's get back to our NetworkController.
To decode the response, I'm going to rely on the private helper method, so let's uncomment it. Next, I need to make sure that the return data is not nil. If the payload is nil, I'm going to return an error of type invalid payload. So let's use a guard statement, guard jsonData = data else, we call the completionHandler with WeatherData that's nil, and a NetworkControllerError of type invalidPayload, and I pass in the URL, which is the endpointURL, and return.
Let's fix this one quickly so I must declare it as a constant. All right, next, if everything goes well, I have to call the private helper method to decode the jsonData, self.decode, and let's pass the jsonData, the endpoint is our endpointURL, and the completionHandler. Finally, let's not forget to call the task resume method to start the data task, dataTask.resume().
All right, now we have an API that is supposed to work. Instead of using it right away in the app, let's rather test it first. I wrote a unit test for the (mumbles), fetchCurrentWeather method. Let's go to the unit test called WeatherAppTest.swift, and here is our method. The method is an asynchronous one. I use XCTest expectation to test it. The waitForExpectations will make our method wait until the expectation is either fulfilled or the timeout expires.
So, let's run our test. So, our test failed, let's see what's going on. I'm going to go back to the NetworkController, and let's quickly look at our code. The session is created, here is where we create the endpoint, all right, so when we copied and pasted the URL of the web service, I forgot to add the http prefix, so let's do it now.
Now, let's re-run our test. I'm going back to the unit test, and execute it again. All right, now the test completed successfully. Now we can integrate the method in our ViewController.
- Comparing object-oriented programming with protocol-oriented programming
- Methods and class-bound protocols
- Adopting a protocol
- Declaring asynchronous behavior
- Preparing and implementing fallback logic
- Implementing an app using protocol-oriented programming