Swift API Calls

Abhishek Biswas
4 min readMar 16, 2023

How API calling is done in swift?

In this blog article, I will explain how API call is done in swift programming. I will use JsonDecode() function in parsing the JSON files which are coming from the API response.

First, create an XCode project. Then create a blank swift file and we are good to go. Before going to the code, let me first show the URL and the response of the URL. The URL is https://reqres.in/api/users?page=1 and the response is

{
"page": 1,
"per_page": 6,
"total": 12,
"total_pages": 2,
"data": [
{
"id": 1,
"email": "george.bluth@reqres.in",
"first_name": "George",
"last_name": "Bluth",
"avatar": "https://reqres.in/img/faces/1-image.jpg"
},
{
"id": 2,
"email": "janet.weaver@reqres.in",
"first_name": "Janet",
"last_name": "Weaver",
"avatar": "https://reqres.in/img/faces/2-image.jpg"
},
{
"id": 3,
"email": "emma.wong@reqres.in",
"first_name": "Emma",
"last_name": "Wong",
"avatar": "https://reqres.in/img/faces/3-image.jpg"
},
{
"id": 4,
"email": "eve.holt@reqres.in",
"first_name": "Eve",
"last_name": "Holt",
"avatar": "https://reqres.in/img/faces/4-image.jpg"
},
{
"id": 5,
"email": "charles.morris@reqres.in",
"first_name": "Charles",
"last_name": "Morris",
"avatar": "https://reqres.in/img/faces/5-image.jpg"
},
{
"id": 6,
"email": "tracey.ramos@reqres.in",
"first_name": "Tracey",
"last_name": "Ramos",
"avatar": "https://reqres.in/img/faces/6-image.jpg"
}
],
"support": {
"url": "https://reqres.in/#support-heading",
"text": "To keep ReqRes free, contributions towards server costs are appreciated!"
}
}

The question arises that why I choose this URL as this URL provides free API containing some dummy data for testing. now let me show how API call are made in swift

The below Swift code snippet is for a APIManager Class that is responsible for handling API requests.

public class APIManager {
// creating a single ton class of APIManager
static let shared = APIManager()

@frozen enum Constant{
static let urlLinks = "https://reqres.in/api/users?page=1"
}

public func APICaller(compleation: @escaping(Result<Sample, Error>)-> Void){
let dataTask = URLSession.shared.dataTask(with: APIUrlRequest(url: Constant.urlLinks)) { (data, response ,error) in
if let error = error {
compleation(.failure(error))
}else if let data = data {
do{
let result = try JSONDecoder().decode(Sample.self, from: data)
print(result)
compleation(.success(result))
}catch{
compleation(.failure(error))
}
}
}
dataTask.resume()
}


private func APIUrlRequest(url: String) -> URLRequest {
let urlStr = URL(string: url)

guard let urlString = urlStr else {
print("Invalid URL")
fatalError("Invalid URL")
}
var urlReq = URLRequest(url: urlString)
urlReq.httpMethod = "GET"
return urlReq
}
}

The Singleton instance of the APIManager is created by using the static let shared = APIManager() syntax, which ensures that only one instance of the APIManager class is created throughout the entire application.

@frozen the keyword is used to create a constant enum named Constant, which contains a static string constant named urlLinks. This constant defines the endpoint of the API that the APIManager will be requesting.

The APICaller the function is defined, which takes a completion handler as its parameter. The completion handler returns a Result type that contains either an Sample object or an error, depending on whether the API request was successful.

Inside the APICaller function, a URLSession data task is created using the APIUrlRequest function. This data task is used to make the API request.

If there is an error during the API request, the completion handler is called with a failure result that contains the error.

If the API request is successful, the data received from the API is decoded using the JSONDecoder class. The decoded data is then passed to the completion handler as a successful result that contains an Sample object.

The APIUrlRequest the function is defined as a private function inside the APIManager class. This function takes a string URL and returns an URLRequest object. Inside this function, the string URL is converted into a URL object, and then an URLRequest object is created using that URL object. Finally, the HTTP method of the URLRequest object is set to GET. The dataTask.resume() the method is called to start the data task.

Before doing the API Call First, we create a struct object for mapping the JSON response.

public struct Sample: Codable {
let page, perPage, total, totalPages: Int
let data: [Datum]
let support: Support

enum CodingKeys: String, CodingKey {
case page
case perPage = "per_page"
case total
case totalPages = "total_pages"
case data, support
}
}

struct Datum: Codable {
let id: Int
let email, firstName, lastName: String
let avatar: String

enum CodingKeys: String, CodingKey {
case id, email
case firstName = "first_name"
case lastName = "last_name"
case avatar
}
}

struct Support: Codable {
let url: String
let text: String
}

Here we create Three structs Sample, Datum, and Support, all of which conform to the Codable protocol.

The Sample struct has the following properties:

  • page, perPage, total, and totalPages are all of type Int.
  • data is an array of Datum objects.
  • support is an object of type Support.

The Datum struct has the following properties:

  • id is of type Int.
  • email, firstName, lastName, and avatar are all of type String.

The Support struct has the following properties:

  • url and text are both of type String.

The CodingKeys enums in each of the structs provide custom keys for encoding and decoding from JSON.

Now In the ViewController file of swift, let's call the API, The snippet below shows the calling of API in the view controller class. The calling of API is done in viewDidLoad as the viewDidLoad function calls when the app is loaded in the memory.

APIManager.shared.APICaller { result in
switch result {
case .success(let result):
print(result)
break
case .failure(let error):
print("error")
break
}
}

let me explain this part of the code. This code calls the APICaller method of the APIManager singleton instance, using the shared instance variable APIManager.shared. It passes in a closure as an argument, which is called when the method completes its asynchronous task of retrieving data from the API.

The closure takes a single parameter of type Result<Sample, Error>. The switch the statement is used to handle the possible outcomes of the API request. If the request was successful, the case .success(let result) branch is executed, which extracts the retrieved data from the Result object using optional binding and prints it to the console. If there was an error, the case .failure(let error) branch is executed, which prints the error message to the console.

This concludes the API call in swift. please inform me of any suggestions. Thank you for reading and please put an upvote for further blogs article related to swift.

--

--