11.2. App11: Getting All the Contact Names (getall endpoint)

http://apis.sakibnm.work:8888/contacts/json/getall

Representing JSON in Swift (getall)

From the API details (11.1. The JSON API for the Contact App), we know that getall API returns a JSON string like:

{
    "contacts": [
        {
            "name": "David Tu"
        },
        {
            "name": "Alice Smith"
        }
    ]
}

Now, think about the structure of the JSON above. First of all, the whole thing is a JSON object.

  • This JSON object contains a JSON array named "contacts."

    • The "contacts" array contains a list of two JSON objects.

      • Each JSON object contains a key-value pair, where the key is "name."

Now, think about a similar struct/class in Swift. Can we represent the above JSON structure with a Swift struct?

Yes, we do. What about the following struct?

The first struct ContactName represents the objects in the "contacts" array, and the second struct ContactNames represents the "contacts" array.

Parsing JSON

Let's write the code to parse the JSON response we receive after calling getall. Let's create a new Xcode project, App11, and integrate Alamofire into the project using CocoaPods.

Set up the same Views, Data Models and APIConfigs (MainScreenView.swift, ContactsTableViewCell.swift, APIConfigs.swift, and Contact.swift) as App10.

Do not forget to change the URL in APIConfigs.swift file to json:

The project file structure would look like this:

Let's open the View Controller and write the initial controller code similar to App10.

Representing the 'getall' JSON with Swift (ContactNames.swift)

Now, let's create the ContactNames.swift file to represent the JSON structure:

Creating the 'getall' request using Alamofire

Open ViewController.swift file, and let's write the following code in getAllContacts():

In the above code, we are

  • Setting the method to GET (line 4).

  • Now, we are not receiving a regular String like before; we are receiving a JSON response. So, we will use responseData instead of responseString (line 4).

  • Like before, if there is no network error and the status code is a 200-level code (line 15), we will decode the data using JSONDecoder().

  • In lines 20-22, we decode the received data using the decoder with the data model we wrote, ContactNames. Notice that we are using a try-catch block. Since the decoder might have a runtime exception, we have to handle it gracefully in the catch block.

  • The receivedData is an object of the ContactNames struct, which corresponds to the JSON object we received. In the object, we have a contacts array. (Review ContactNames.swift).

    • So, receivedData.contacts (line 24), should contain the data from JSON's contacts array.

  • In line 24, we are running through each ContactName object and appending the name from the object to contactNames array for the table view (the table view data source).

  • Then we reload the data for the table view.

Now, this code will not work yet. You will get an error like this:

Adopting Codable protocol

It means the data type (ContactNames) we are using as the blueprint to decode the JSON data, cannot be used until it is a decodable data type. So, we need to adopt a protocol named Codable from the structs ContactName and ContactNames. Let's open ContactNames.swift file and update them by adopting the Codable protocol.

Now, the error will go away.

(Make sure you enable unencrypted HTTP) Let's run the app. It will show us the current contacts.

Great! We are done with getall.

Last updated

Was this helpful?