skip to content
Jonathan Dionne

Get final URL by following redirection using Swift

/ 2 min read

Swift’s URLResolver class simplifies handling URL redirects using async-await. It performs a lightweight “HEAD” request to only fetch headers, efficiently detecting if a URL redirects to another location. If there’s a redirect, it returns the new URL; otherwise, it returns the original. This approach utilizes Swift’s modern concurrency features for straightforward and efficient URL management in apps.

Snippet

URLResolver.swift
import Foundation
class URLResolver {
func resolve(url: URL) async -> URL? {
await withCheckedContinuation { continuation in
var request = URLRequest(url: url)
request.httpMethod = "HEAD"
let task = URLSession.shared.dataTask(with: request) { _, response, error in
guard let httpResponse = response as? HTTPURLResponse, error == nil else {
continuation.resume(returning: nil)
return
}
if let location = httpResponse.value(forHTTPHeaderField: "Location"),
let redirectedURL = URL(string: location) {
continuation.resume(returning: redirectedURL)
} else {
continuation.resume(returning: httpResponse.url)
}
}
task.resume()
}
}
}

Usage

Here’s a simple example demonstrating how to use URLResolver in a Swift application:

Example
// Use the URLResolver
func fetchFinalURL(from urlString: String) async {
guard let url = URL(string: urlString) else {
print("Invalid URL")
return
}
let resolver = URLResolver()
if let finalURL = await resolver.resolve(url: url) {
print("Final URL is: \(finalURL)")
} else {
print("Failed to resolve URL or no redirection found.")
}
}
// Example usage
Task {
await fetchFinalURL(from: "http://example.com")
}