Meet the Rest APIs Tutorial JSON Family And How to make HTTP POST, GET, PUT and DELETE requests with URLSession using iOS Swift 5.2




In this article, We will learn How to use web services which is part of the server (API) that handles data for mobile apps. As an iOS developer, you often need to use a web service from your app. 

    What are web services in mobile applications?

    The words "web services" mean many things to people in different fields.it is the part of the server (API) that handles data for the mobile apps. They are services that act as intermediaries between the mobile application and the databases. Usually, web services fetch data, arrange it in an agreed format and send it at the request of the mobile application. They can also write the data in the database when it is received from the mobile app.

    Web service is a way of exchange data over the network between two or more applications.
    web service is a way of interacting with remote web services that provide data for an application.


    Communication Architecture-


    1- The client prepares a request URLRequest using the address of the resource the app wants to access. 
    2- The Prepared request can be sent by using URLSession/NSURLConnection/AlmoFire/AFNetworking
    3- The server processes the request and prepares the response (the resources/data from the DB) 
    4- The server prepared the response (JSON/XML) will be sent over the network to client. 
    5- Clientparses the response using NSJSONSerlization/Codeable(JSONDecoder/JSONEncoder) and present on the user interface.

    Create a URL Request-

    All of first create a URLRequest. A URLRequest can be created with a URL, representing the API endpoint to make an HTTP request.

    let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")!
            
     //  Create a URLRequest for an API endpoint
      var urlRequest = URLRequest(url: url)

    GET HTTP Request-

    If you need to make a GET request, you can set the HTTP method and HTTP body on the URLRequest.

     urlRequest.httpMethod = "GET"
     urlRequest.allHTTPHeaderFields = ["content" : "application/json"]
            urlRequest.httpBody = Data()
    

    Create URLSessionDataTask-

    To handle a request-response, create a URLSessionDataTask with a completion handler. Use the completion handler to parse the request-response and handle any error that may have occurred.

      //3--- Create Data Task
            let dataTask = session.dataTask(with: urlRequest){ data, response, error in
                guard error == nil else {
                    print("Error: error calling PUT")
                    print(error!)
                    return
                }
                guard let data = data else {
                    print("Error: Did not receive data")
                    return
                }
                guard let response = response as? HTTPURLResponse, (200 ..< 299) ~= response.statusCode else {
                    print("Error: HTTP request failed")
                    return
                }
    

    Parsing-

    Clientparsethe response using NSJSONSerlization/Codeable (JSONDecoder/JSONEncoder) and present on the user interface.

    You can check similar solutions parse a JSON file using JsonDecoder

          do {
                    guard let jsonObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                        print("Error: Cannot convert data to JSON object")
                        return
                    }
                    // 4--- parse the response received from server...
                    guard let prettyJsonData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) else {
                        print("Error: Cannot convert JSON object to Pretty JSON data")
                        return
                    }
                    guard let prettyPrintedJson = String(data: prettyJsonData, encoding: .utf8) else {
                        print("Error: Could print JSON in String")
                        return
                    }
                    //5--- convert to data into model classand present it on UI or save on DB
                    print(prettyPrintedJson)
                    
                    // update UI using the response here
                } catch {
                    print("Error: Trying to convert JSON data to string")
                    return
                }

    Server contains-

    The server contains a collection of resources/records which contain a specific address(URL) to access them. This communication system is often categorized into two types, namely Simple Object Access Protocol or SOAP, and Representational State Transfer or REST.

    1. RESTFUL (JSON/XML) Lightweight 
    2. SOAP (XML) Heavyweight 
    REST & SOAP are types of architecture implemented as server-side. But as iOS developers, we don't care about how the entire REST architecture on the server-side.

    What is URL?

    URL stands for Uniform Resource Locator is the global address of documents and other resources on the planet Wide Web. Its main purpose is to spot the situation of a document and other resources available on the web and specify the mechanism for accessing it through an internet browser.

    URL Structure-

    A URL has different parts, but in the context of REST APIs, we are usually interested in three parts. 


    • Host

    The hostname identifies the host where the resource is found. A hostname is a domain name assigned to a host computer. This is usually a combination of the host's local name with its parent domain's name. For example, www.appcodezip.com consists of the host's machine name www and the domain name appcodezip.com.

    • Path

    The path identifies the specific resource within the host that the user wants to access. For example, /app/aDauthentication.asmx/technews/home/, etc.

    • Query String

    The query string contains data to be passed to server-side scripts, running on the online server. For example, parameters for a search. The query string preceded by a question mark (?), is usually a string of name and value pairs separated by an ampersand (&), for example, UserLogin   ?first_name=sohan&last_name=mishraand so on.

    How to prepare a request-


    An HTTP request usually contains:

    A URL for the resource we want 

    An HTTP method to state the action we want to perform

    Optional Parameter in the form of HTTP headers

    Optional data we want to send to the server.

    HTTP is that the application protocol, or set of rules, internet sites use to transfer data from the online server to your screen. You’ve seen HTTP (or HTTPS) listed within the front of each URL you type into an internet browser. HTTP defines several request methods, or verbs, the client (your browser or app) use to point the specified action.

    In HTTP there are four methods that are commonly utilized in a REST-based Architecture i.e., POST, GET, PUT, and DELETE. These correspond to make, read, update, and delete (or CRUD) operations respectively. There are other methods which are less frequently used like OPTIONS and HEAD.

    What Is a REST API?-

    Rest is simple way of sending and receiving data between client and server and it does not have any much standards defined, you'll send and receive data as JSON, XML, or maybe a Text. It's Light-weighted compared to SOAP. I would suggest you to travel with Rest for mobile development since it's lightweight.


    REST stands for REpresentational State Transfer and API stands for that defines a set of functions that programmers can use to send requests and receive responses using the HTTP protocol methods such as GET and POST. REST may be a software style of architecture that defines the set of rules to be used for creating web services. Web services that follow the remainder style of architecture are referred to as RESTful web services. It allows requesting systems to access and manipulate web resources by employing a uniform and predefined set of rules. Interaction in REST-based systems happen through the Internet’s Hypertext Transfer Protocol (HTTP).

    GET-

    The HTTP GET method is employed to read (or retrieve) a representation of a resource. within the safe path, GET returns a representation in XML or JSON and an HTTP response code of 200 (OK). In a mistake case, it most frequently returns a 404 (NOT FOUND) or 400 (BAD REQUEST). This HTTP method GET to retrieve information from REST API.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
        func getRestApiMethod() {
            let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")!
            
            // 1--- Create Request
            var urlRequest = URLRequest(url: url)
            urlRequest.httpMethod = "GET"
            urlRequest.allHTTPHeaderFields = ["content" : "application/json"]
            urlRequest.httpBody = Data()
            //2--- send the request to server
            let session = URLSession.shared   // Reference to Shared Session
             //3--- Create Data Task
            let dataTask = session.dataTask(with: urlRequest){ data, response, error in
                guard error == nil else {
                    print("Error: error calling PUT")
                    print(error!)
                    return
                }
                guard let data = data else {
                    print("Error: Did not receive data")
                    return
                }
                guard let response = response as? HTTPURLResponse, (200 ..< 299) ~= response.statusCode else {
                    print("Error: HTTP request failed")
                    return
                }
                do {
                    guard let jsonObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                        print("Error: Cannot convert data to JSON object")
                        return
                    }
                    // 4--- parse the response received from server...
                    guard let prettyJsonData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) else {
                        print("Error: Cannot convert JSON object to Pretty JSON data")
                        return
                    }
                    guard let prettyPrintedJson = String(data: prettyJsonData, encoding: .utf8) else {
                        print("Error: Could print JSON in String")
                        return
                    }
                    //5--- convert to data into model classand present it on UI or save on DB
                    print(prettyPrintedJson)
                    
                    // update UI using the response here
                } catch {
                    print("Error: Trying to convert JSON data to string")
                    return
                }
            }
            dataTask.resume()
        }
    

    Output-

    {
      "completed" : false,
      "title" : "delectus aut autem",
      "userId" : 1,
      "id" : 1
    }
    

    POST- 

    In computing, POST is a request method supported by HTTP used by the World Wide Web. If you want to send data to the server, as in this example by uploading an employee’s data(namecompany, and age) to the database, then use the HTTP method POST.

     
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
        func postRestApiMethod() {
            guard let url = URL(string: "http://dummy.restapiexample.com/api/v1/create") else {
                print("Error: cannot create URL")
                return
            }
            struct UploadData: Codable {        // Create model
                let name: String
                let company: String
                let age: String
            }
            // Add data to the model
            let uploadDataModel = UploadData(name: "Rohan", company: "Jk Tech", age: "25")
            
            // Convert model to JSON data
            guard let jsonData = try? JSONEncoder().encode(uploadDataModel) else {
                print("Error: Trying to convert model to JSON data")
                return
            }
            // Create the url request
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            request.setValue("application/json", forHTTPHeaderField: "Content-Type") // the request is JSON
            request.setValue("application/json", forHTTPHeaderField: "Accept") // the response expected to be in JSON format
            request.httpBody = jsonData
            URLSession.shared.dataTask(with: request) { data, response, error in
                guard error == nil else {
                    print("Error: error calling POST")
                    print(error!)
                    return
                }
                guard let data = data else {
                    print("Error: Did not receive data")
                    return
                }
                guard let response = response as? HTTPURLResponse, (200 ..< 299) ~= response.statusCode else {
                    print("Error: HTTP request failed")
                    return
                }
                do {
                    guard let jsonObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                        print("Error: Cannot convert data to JSON object")
                        return
                    }
                    guard let prettyJsonData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) else {
                        print("Error: Cannot convert JSON object to Pretty JSON data")
                        return
                    }
                    guard let prettyPrintedJson = String(data: prettyJsonData, encoding: .utf8) else {
                        print("Error: Couldn't print JSON in String")
                        return
                    }
                    print(prettyPrintedJson)
                } catch {
                    print("Error: Trying to convert JSON data to string")
                    return
                }
            }.resume()
        }
    

    OutPut-

    "message" : "Successfully! Record has been added.",
      "data" : {
        "age" : "25",
        "id" : 5712,
        "company" : "Jk Tech",
        "name" : "Rohan"
      },
      "status" : "success"
    }
    

    PUT-

    It's used for updating the capabilities. PUT is used to send data to a server to create/update a resource. If you have the data already, and you want to update them, you can use the HTTP method PUT. Sometimes you can do the same with the POST method.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    func putRestApiMethod() {
            guard let url = URL(string: "https://reqres.in/api/users/2") else {
                print("Error: cannot create URL")
                return
            }
            
            // Create model
            struct UploadData: Codable {
                let name: String
                let job: String
            }
            
            // Add data to the model
            let uploadData = UploadData(name: "Rohan", job: "Development")
            
            // Convert model to JSON data
            guard let jsonData = try? JSONEncoder().encode(uploadData) else {
                print("Error: Trying to convert model to JSON data")
                return
            }
            
            // Create the request
            var request = URLRequest(url: url)
            request.httpMethod = "PUT"
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
            request.httpBody = jsonData
            URLSession.shared.dataTask(with: request) { data, response, error in
                guard error == nil else {
                    print("Error: error calling PUT")
                    print(error!)
                    return
                }
                guard let data = data else {
                    print("Error: Did not receive data")
                    return
                }
                guard let response = response as? HTTPURLResponse, (200 ..< 299) ~= response.statusCode else {
                    print("Error: HTTP request failed")
                    return
                }
                do {
                    guard let jsonObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                        print("Error: Cannot convert data to JSON object")
                        return
                    }
                    guard let prettyJsonData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) else {
                        print("Error: Cannot convert JSON object to Pretty JSON data")
                        return
                    }
                    guard let prettyPrintedJson = String(data: prettyJsonData, encoding: .utf8) else {
                        print("Error: Could print JSON in String")
                        return
                    }
                     // update UI using the response here
                    print(prettyPrintedJson)
                } catch {
                    print("Error: Trying to convert JSON data to string")
                    return
                }
            }.resume()
        }
        
        
    

    OUTPUT-
     
    {
      "name" : "Rohan",
      "updatedAt" : "2020-10-15T03:43:10.949Z",
      "job" : "Development"
    }
    

    DELETE-

    it's wont to delete a resource identified by a URI. On successful deletion, return HTTP status 200 (OK) alongside a response body. In other words, The DELETE method deletes the specified resource.
    As the below web service has some response.


    https://jsonplaceholder.typicode.com/posts/1
     
    {
      "userId": 1,
      "id": 1,
      "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
      "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    }

    Remove data from your REST API server using the HTTP method DELETE. 

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
           func deleteRestApiMethod() {
            guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1") else {
                print("Error: cannot create URL")
                return
            }
            // Create the request
            var request = URLRequest(url: url)
            request.httpMethod = "DELETE"
            URLSession.shared.dataTask(with: request) { data, response, error in
                guard error == nil else {
                    print("Error: error calling DELETE")
                    print(error!)
                    return
                }
                guard let data = data else {
                    print("Error: Did not receive data")
                    return
                }
                guard let response = response as? HTTPURLResponse, (200 ..< 299) ~= response.statusCode else {
                    print("Error: HTTP request failed")
                    return
                }
                do {
                    guard let jsonObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                        print("Error: Cannot convert data to JSON")
                        return
                    }
                    guard let prettyJsonData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted) else {
                        print("Error: Cannot convert JSON object to Pretty JSON data")
                        return
                    }
                    guard let prettyPrintedJson = String(data: prettyJsonData, encoding: .utf8) else {
                        print("Error: Could print JSON in String")
                        return
                    }
                   // update UI using the response here
                     print("Data deleted sucessfully..")
                    print(prettyPrintedJson)
                } catch {
                    print("Error: Trying to convert JSON data to string")
                    return
                }
            }.resume()
        }
    

    In this example, the URL using the DELETE method doesn’t return any response after deleting the item. That’s why the results are empty.
     
    Data deleted sucessfully..
    {
    
    }
    

    I hope you enjoyed reading this tutorial, Please share.

    Thanks for reading!!


    Similar solutions you may also like...




    Post a Comment

    1 Comments