How to Make HTTP GET Requests with URLSession (REST API + JSON)

Here, we will explain how to make an HTTP request (GET) using URLSession in Swift.

We'll use the CDTFA Tax Rate API, which allows you to fetch tax rates in California.

Overview of the CDTFA Tax Rate API

The CDTFA Tax Rate API is a public API provided by the State of California that allows you to fetch tax rates.

You can either specify an address or provide latitude and longitude to get the tax rate. In this example, we will use latitude and longitude.


Get Rate By Latitude and Longitude

https://services.maps.cdtfa.ca.gov/api/taxrate/GetRateByLngLat?longitude={longitude}&latitude={latitude}

Replace {longitude} with the longitude and {latitude} with the latitude. A GET request to this URL will return a response like the following:

{
   "taxRateInfo":[
      {
         "rate":0.0775,
         "jurisdiction":"ANAHEIM",
         "city":"ANAHEIM",
         "county":"ORANGE",
         "tac":"300110370000"
      }
   ],
   "geocodeInfo":{
      "bufferDistance":50
   },
   "termsOfUse":"https://www.cdtfa.ca.gov/dataportal/policy.htm",
   "disclaimer":"https://www.cdtfa.ca.gov/dataportal/disclaimer.htm"
}

How to Make an HTTP GET Request with URLSession

Now let's look at how to make an HTTP GET request using URLSession in Swift.

Previously, in “How to Get Current Location in an iOS App (Swift)”, we created an app that retrieves latitude and longitude. Here, we will assume that latitude and longitude are already available and hard-code them to fetch the tax rate using the CDTFA Tax Rate API.

We'll use the latitude and longitude of Disneyland in Los Angeles.


The following code makes a GET request and retrieves the tax rate for the Disneyland area:

import Foundation

let longitude = -117.91966085189185
let latitude = 33.819508122999984

let url = URL(string: "https://services.maps.cdtfa.ca.gov/api/taxrate/GetRateByLngLat?longitude=\(longitude)&latitude=\(latitude)")!

var request = URLRequest(url: url)
request.httpMethod = "GET"

URLSession.shared.dataTask(with: request) {(data, response, error) in
    
    if let error = error {
        print("Unexpected error: \(error.localizedDescription).")
        return;
    }
    
    if let response = response as? HTTPURLResponse {
        if !(200...299).contains(response.statusCode) {
            print("Request Failed - Status Code: \(response.statusCode).")
            return
        }
    }
    
    if let data = data {
        do {
            let jsonDict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
            let taxRateInfos = jsonDict?["taxRateInfo"] as? [[String: Any]]
            if taxRateInfos != nil && taxRateInfos!.count > 0 {
                let taxRateInfo = taxRateInfos?[0] as? [String: Any]
                let rate = taxRateInfo?["rate"]
                let city = taxRateInfo?["city"]
                
                print("City: \(city ?? ""), Tax Rate: \(rate ?? "")")
            }
        } catch {
            print("Error")
        }
    } else {
        print("Unexpected error.")
    }
    
}.resume()

Let's go through the code step by step.

let url = URL(string: "https://services.maps.cdtfa.ca.gov/api/taxrate/GetRateByLngLat?longitude=\(longitude)&latitude=\(latitude)")!

var request = URLRequest(url: url)
request.httpMethod = "GET"

Line 6 generates the URL for the CDTFA Tax Rate API with the specified latitude and longitude.

Lines 8–9 create a URLRequest object from the URL and set the httpMethod to GET.


URLSession.shared.dataTask(with: request) {(data, response, error) in

Starting from line 11, we define a task using URLSession's dataTask(). This handles sending the request, receiving the response, and processing the results.

We pass the request created earlier with the with parameter.

data contains the response body, response contains metadata such as HTTP headers and status codes, and error will only contain a value if the request failed.


if let error = error {
    print("Unexpected error: \(error.localizedDescription).")
    return;
}

If there's a value in error, we print the error and return.


if let response = response as? HTTPURLResponse {
    if !(200...299).contains(response.statusCode) {
        print("Request Failed - Status Code: \(response.statusCode).")
        return
    }
}

Here, we cast response to HTTPURLResponse and check the HTTP status code.

If it's not in the 200 range (success), we print the status code and return.


if let data = data {
    do {
        let jsonDict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
        let taxRateInfos = jsonDict?["taxRateInfo"] as? [[String: Any]]
        if taxRateInfos != nil && taxRateInfos!.count > 0 {
            let taxRateInfo = taxRateInfos?[0] as? [String: Any]
            let rate = taxRateInfo?["rate"]
            let city = taxRateInfo?["city"]
            
            print("City: \(city ?? ""), Tax Rate: \(rate ?? "")")
        }
    } catch {
        print("Error")
    }
} else {
    print("Unexpected error.")
}

Here, we parse the response data to extract the rate and city, then print them.

For more details, see “How to Extract Data from JSON Using a Dictionary in Swift”.


}.resume()

Finally, we call the resume() method to start the task.


If you run this in a Playground, the output will look like this:

City: ANAHEIM, Tax Rate: 0.0775

Swift - How to Make an HTTP GET Request with URLSession 1

This shows the tax rate of Anaheim, where Disneyland is located: 0.0775 (7.75%).


That's it — we've explained how to make an HTTP GET request using URLSession in Swift.