Building and Parsing URLs in Swift

Creating and parsing URLs is commonly implemented in iOS and macOS apps that connect to the web. This post presents a number of URL, URLComponents, and URLQueryItem examples in Swift:

  1. Parse URL String
    a. Parse Absolute URL
    b. Parse Relative URL
    c. Get Value Of URL Query Parameters
    e. URLComponents Automatically Decodes URL Encoded strings
    d. Decode URL Encoded String
    f. What is resolvingAgainstBaseURL?
  2. Create URL String
    a. Build A URL With Query Parameters
    b. URLComponents Automatically Encodes Query Items
    c. URL Encode A String
  3. URL Property Examples
    a. URLs and Strings
    b. Port, Host, and Scheme
    c. Query and Fragment
    d. Paths and Extensions

Parse URL String

Parse Absolute URL

An absolute URL is a fully specified address.

var url = URL(
    string: "https://advswift.com/api/v1?page=url+components"
)!

url.host // advswift.com
url.path // /api/v1

Parse Relative URL

A relative URL is a partially specified address, starting at the path, appended to a root URL.

var root = URL(string: "https://advswift.com/")!
var url = URL(
    string: "api/v1?page=url+components", 
    relativeTo: root
)!

url.host // advswift.com
url.path // /api/v1

Get Value Of URL Query Parameters

A common task is to extract the URL query parameters as a dictionary. Parsing a URL with URLComponents provides a queryItems property that contains a list of query item names and values:

var url = URL(
    string: "https://advswift.com/api/v1?page=url"
)!

var components = URLComponents(
    url: url, 
    resolvingAgainstBaseURL: false
)!

// URL query parameters as a dictionary
components.queryItems
// [
//    {
//        "name": "page", 
//        "value": "url"
//    }
// ]

URLComponents Automatically Decodes URL Encoded strings

URL query parameters parsed by URLComponents will automatically be decoded if the query item value was URL encoded:

var url = URL(
    string: "https://advswift.com/api/v1?page=url%20query"
)!

var components = URLComponents(
    url: url, 
    resolvingAgainstBaseURL: false
)!

// Decoded URL query parameters as a dictionary
components.queryItems
// [
//    {
//        "name": "page", 
//        "value": "url query"
//    }
// ]

Decode URL Encoded String

Use the removingPercentEncoding String property to remove URL encoding directly:

var encoded = "url%20components"
var decoded = encoded.removingPercentEncoding
// decoded is "url components"

What is resolvingAgainstBaseURL?

The URLComponents constructor argument resolvingAgainstBaseURL determines if URLComponents should use the absolute URL:

var root = URL(string: "https://advswift.com/")!
var url = URL(
    string: "api/v1?page=url+components", 
    relativeTo: root
)!

var relativeComponents = URLComponents(
    url: url, 
    resolvingAgainstBaseURL: false
)!

// "api/v1?page=url+components"
relativeComponents.string

var absoluteComponents = URLComponents(
    url: url, 
    resolvingAgainstBaseURL: true
)!

// "https://advswift.com/api/v1?page=url+components"
absoluteComponents.string

Create URL String

URLComponents can also be used to construct custom urls:

var components = URLComponents()
components.scheme = "https"
components.host = "advswift.com"
components.path = "/home"

// "https://advswift.com/home"
components.string

Build A URL With Query Parameters

Specifying queryItems on URLComponents will properly build a url with query parameters:

var components = URLComponents()
components.scheme = "https"
components.host = "advswift.com"
components.path = "/home"

components.queryItems = [
    URLQueryItem(name: "topic", value: "swift"),
    URLQueryItem(name: "page", value: "urls")
]

// "https://advswift.com/home?topic=swift&page=urls"
components.string

URLComponents Automatically Encodes Query Items

URLComponents will automatically URL encode query items that contain disallowed characters:

var components = URLComponents()

components.queryItems = [
    URLQueryItem(name: "page", value: "url components")
]

// "?page=url%20components"
components.string

URL Encode A String

Use the String method addingPercentEncoding(withAllowedCharacters:) to URL encode a string directly:

var decoded = "url components"
var encoded = decoded.addingPercentEncoding(
    withAllowedCharacters: .urlQueryAllowed
)
// encoded is "url%20components"

URL Property Examples

URLs and Strings

// Absolute URL
var url = URL(string: "https://advswift.com/home")!
url.absoluteURL // URL struct, https://advswift.com/home
url.absoluteString // "https://advswift.com/home"
url.baseURL // nil

// Relative URL
var root = URL(string: "https://advswift.com")!
var url = URL(string: "v1/api", relativeTo: root)!

url.absoluteURL 
// URL struct, https://advswift.com/home/v1/api

url.absoluteString // "https://advswift.com/v1/api"
url.baseURL // URL struct, "https://advswift.com"

Port, Host, and Scheme

var url = URL(string: "https://advswift.com:80")!
url.port // 80, an Int
url.host // "advswift.com"
url.scheme // "https"

Query and Fragment

// URL Query Example
var url = URL(string: 
    "https://advswift.com/page?topic=swift&examples=true"
)!

url.query // "topic=swift&examples=true"

// URL Fragment Example
var url = URL(string: "https://advswift.com/page#anchor")!
url.fragment // "anchor"

Paths and Extensions

var url = URL(
    string: "https://advswift.com/api/v1/endpoint.ext"
)!

url.path // "/api/v1/endpoint.ext"
url.pathExtension // "ext"
url.pathComponents // ["/", "api", "v1", "endpoint.ext"]

url.relativePath // "/api/v1/endpoint.ext"

url.relativeString 
// "https://advswift.com/api/v1/endpoint.ext"

Encode URL Parameters and Create Custom URLs In Swift

That’s it! By using URL, URLComponents, and URLQueryItem you can create custom urls, parse URL formats, and encode URL query items in Swift.