API Parsing Using Decodable Protocol in Swift
Tags: swift, apple, basics, beginners
Published: 2020-12-22 15:27:04

# Brief Introduction About Swift

Swift is a language developed by Apple which is made using modern approach, include safety features and software design patterns. As the name suggests swift is fast, safe and easy to use. It is basically made a replacement for c-based family(C, C++ and Objective-C). It can be used to make apps and can be also used for cloud services and it is among the fastest growing languages.

# Steps involved in Swift API Parsing

1. Make a URL.
2. Make URL Session
3. Make Data Task
4. Resume Data Task

# Code Example

So, here for example we will be using **kanye.rest** API.

```swift
// Created by Neeraj Gupta
// Xcode Playground

//
//  ViewController.swift
//  Weather
//
//  Created by Neeraj Gupta on 04/12/20.
//

import UIKit
import PlaygroundSupport

//This line of code tells Xcode to not Kill the process and continue even after reching end of code
PlaygroundPage.current.needsIndefiniteExecution = true

//We need to define a Model for keys which we want to extract from API.
// We will discuss about decodable process later in this lesson
struct Model : Decodable {
//    Here my data contains only a single string so we need to define a single key which is of type string and Note the name of key defined should be same as that in API.
    let quote : String
}

//Storing the url for API in a constant named "url", can be different in your case.
let url : String = "https://api.kanye.rest/"
//Calling function named fetchData by passing this url as argument
fetchData(url : url)

// Here fetchData is taking that url String as parameter
func fetchData(url : String) {
//    Let's proceed with step 1 that is make URL and here we are using optional binding as the URL we get is "optional" and we need to check if it's not returning "nil"
    if let sessionURL = URL(string : url) {
//        Let's see Step 2 that is making session for URL. URLSession(An object that coordinates a group of related, network data-transfer tasks.) as per documentation. Parameter passed "configuration is "A copy of the configuration object for this session."
        let session = URLSession(configuration: .default)
//        Let's proceed with Step 3 that is making Data Task(Creates a task that retrieves the contents of the specified URL, then calls a handler upon completion) as per documentation. We use a method dataTask(func dataTask(with: URL, completionHandler: (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask) from URLSession Object. In completion handler press enter and a closure will appear as below and enter name of parameter in all 3 fields.
        let dataTask = session.dataTask(with: sessionURL) {(data, response, error) in
//            The data we get here is optional so we need to optionally bind it to check for "nil"
            if let safeData = data {
//                Now we have a encoded data and we need to parse or decode it so we make custom function named "JSONParse" and pass data in it
                if let parsedData = JSONParse(data : safeData) {
//                    The data we are getting is optional so we need to optional bind it and check for "nil" and if not nill print key from object received
                    print(parsedData.quote)
                }
                
            }
        }
//        Here we do Step 4 that is resume Data Task. This is used to start the Data Task we just created
        dataTask.resume()
    }
}

//Here is "JSONParse", Our custom method for decoding Data. We pass data of type "Data" as parameter and we are expecting to get Data of type Model(Our Custom Struct) from it. Data we are receiving is optional as we are telling swift by adding "?" to it.
func JSONParse(data : Data) -> Model? {
//    Let's make an instance of JSON Decoder class.
    let decoder = JSONDecoder()
//    We have to use do catch block as "decode" method can throw an error and we need to pass data type we want to decode as as first paramter and the data which we want to decode as second parameter
    do {
//        First parameter we pass here shoould conform to protocol "Decodable" so when we defined struct Model we conform it to "Decodable" protocol.
        let decodedData = try decoder.decode(Model.self, from: data)
        return decodedData
    } catch {
//        This will be executed if we somehow het error while decoding data
        print(error)
        return nil
    }
}

```

This is how we parse data from **API/ REST API/ Web Service**.