1.1. Decluttering our App11 (Contacts App with JSON)
So far in 11.8. Decluttering codes from View Controller (Recommended Read) section, we learned how to write protocols and use extensions to modularize your code. Let's start there.
So far, we have the following structure of the project:
App 11
Data Models (Directory)
Contact.swift
ContactNames.swift
Contact API Coinfigs (Directory)
APIConfigs.swift
ContactsProtocol.swift
Edit Screen (Directory) — Added later for completeness
Views (Directory)
EditScreenView.swift
EditViewController.swift
Main Screen (Directory)
Views (Directory)
ContactsTableViewCell.swift
MainScreenView.swift
ContactListTableViewManager.swift — Added later with extension magic!
ContactsAPICalls.swift
ContactsViewController.swift — Changed from ViewController using SceneDelegate
AppDelegate.swift
SceneDelegate.swift
1.1.1. Updating Contact API Protocol code
To be able to accommodate the async-await calls to remove the spaghetti code, we need a few changes in our Contact API protocol in ContactsProtocol.swift file:
The basic differences here from before are:
We made all the API call functions asynchronous by adding the async notation.
We are also making the functions return something (Bool, Contact, etc.) so that it becomes easier when we sequence them from the controller.
1.1.2. Making API calls async
So we will now rewrite (a little) the current code for the API calls (getall, add, delete, getdetails) to be able to call them asynchronously.
getAllContacts()
For example, the previous code for the getall API call in ContactAPICalls.swift file was:
Here, our callback was on line 4, completionHandler. This closure gets returned when the network call is complete.
Now, we need to get rid of the completionHandler since we will be managing the asynchronous operations ourselves.
So, the updated code becomes something like:
Let's compare the two codes and check what happened here.
Instead of using the completionHandler, we are separating the AlamoFire call on line 5 with the await notation and retrieving the response asynchronously.
Since we are sequencing the call, await will suspend execution until it receives the response.
Then, we retrieve the status code from the response on line 9, and subsequently write a switch-case block to filter cases with different status codes.
We only return true if it is in the 200-level block. Every other case returns false.
It already looks less cluttered!
1.1.3. Control Code
Now, let's see how we can call getAllContacts using the Task{} block from the ViewController. Let's check the corresponding code in ContactsViewController.swift file:
In the above code:
When the app loads, we want to load the list of current contacts, so we call callGetAllContacts() function on line 25. Lines 30 through 37 show the implementation of the function.
You can see we have a Task{} block. Inside the block, everything will sequentially wait.
On line 32, we call the API and wait for it to return the result. If the response was of 200-level, we reload the data in our table view.
Last updated
Was this helpful?