Working with URLs can be tedious if you're unfamiliar with some of Foundation's hidden gems. In this episode, we take a look at one of those gems, the URLQueryItem struct. This nifty, little struct takes care of a range of seemingly trivial tasks. Let's take a look.

Building URLs

Fire up Xcode and create a playground by choosing the Blank template from the iOS section.

Building URLs with URLQueryItem in Swift

Remove the contents of the playground and add an import statement for the Foundation framework at the top.

import Foundation

In Mastering MVVM with SwiftUI, we build a weather application that uses Clear Sky, a weather service, to fetch weather data. We start by creating a URL object that points to the weather service.

import Foundation

let baseURL = URL(string: "https://cocoacasts.com/clearsky")!

To fetch weather data, we need to pass an API key and a set of coordinates. We could manually append the query parameters to the URL, but the URLQueryItem struct makes this much easier.

Let's create a URL query item for the API key. The initializer accepts a name and a value. We pass api_key as the name and the API key as the value. Note that the value is of type String?.

import Foundation

let baseURL = URL(string: "https://cocoacasts.com/clearsky")!

let apiKey = URLQueryItem(name: "api_key", value: "abcdef")

We can repeat these steps for the set of coordinates, that is, the latitude and the longitude. Because the value is required to be a string, we pass the latitude and the longitude as a string to the initializer.

import Foundation

let baseURL = URL(string: "https://cocoacasts.com/clearsky")!

let apiKey = URLQueryItem(name: "api_key", value: "abcdef")
let latitude = URLQueryItem(name: "lat", value: "12.34")
let longitude = URLQueryItem(name: "long", value: "43.21")

The URL struct defines the appending(queryItems:) method to generate a URL by appending an array of URLQueryItem objects. Foundation ensures the query items are properly formatted and encoded. The method returns a URL object we can use to create a URLRequest object.

let url = baseURL.appending(queryItems: [
    apiKey,
    latitude,
    longitude
])

let request = URLRequest(url: url)

The resulting URL looks like this.

https://cocoacasts.com/clearsky?api_key=abcdef&lat=12.34&long=43.21

Query Parameters without a Value

The value of a query item is optional. This is rather uncommon, though. A query parameter without a value could be used as a flag or a switch, that is, it is present/enabled or absent/disabled. We simply pass nil as the query parameter's value.

let excludeSuggestions = URLQueryItem(name: "exclude_suggestions", value: nil)

The URL struct supports query parameters without values as you can see here.

https://cocoacasts.com/clearsky?api_key=abcdef&lat=12.34&long=43.21&exclude_suggestions

In this episode, we explored the use of the URLQueryItem struct in combination with the URL struct. URLQueryItem also works great with the URLComponents struct. You can read more about URLComponents in Working With URLComponents In Swift.

What's Next?

The Foundation framework has many hidden gems to make your life as a developer easier. The URLQueryItem struct is one such example. It ensures the URLs you create are sound and comply with common standards, such as RFC 3986.