Given a short URL https://itun.es/us/JB7h_
, How do you expand it into the full URL? e.g. https://music.apple.com/us/album/blackstar/1059043043
Asked
Active
Viewed 3,110 times
3
-
2You should probably add some clarification that this is a Q&A style question so that it doesn't get closed as too broad – Jojodmo Jan 10 '16 at 20:50
2 Answers
9
Extension
extension URL {
func getExpandedURL() async throws -> Result<URL, Error> {
var request = URLRequest(url: self)
request.httpMethod = "HEAD"
let (_, response) = try await URLSession.shared.data(for: request)
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
throw URLError.unableToExpand
}
if let expandedURL = response.url {
return .success(expandedURL)
} else {
throw URLError.unableToExpand
}
}
enum URLError: Error {
case unableToExpand
}
}
Crude Demo
struct ContentView: View {
let shortURL = URL(string: "https://itun.es/us/JB7h_")
@State var expandedURLResult: Result<URL, Error>?
var body: some View {
Form {
Section("Short URL") {
Text(shortURL?.description ?? "")
}
Section("Long URL") {
switch expandedURLResult {
case .some(.success(let expandedURL)):
Text(expandedURL.description)
case .none:
Text("Waiting")
case .some(.failure(let error)):
Text(error.localizedDescription)
}
}
}
.task {
do {
expandedURLResult = try await shortURL?.getExpandedURL()
} catch {
expandedURLResult = .failure(error)
}
}
}
}

Zelko
- 3,793
- 3
- 34
- 40
-
1This completion handler usage is malformed, because it's never called in the error case. – Alexander Jan 30 '22 at 15:53
-
8
The final resolved URL will be returned to you in the NSURLResponse: response.URL
.
You should also make sure to use the HTTP HEAD
method to avoid downloading unnecessary data (since you don't care about the resource body).
Swift 4.2 Updated :
extension URL {
func resolveWithCompletionHandler(completion: @escaping (URL) -> Void) {
let originalURL = self
var req = URLRequest(url: originalURL)
req.httpMethod = "HEAD"
URLSession.shared.dataTask(with: req) { body, response, error in
completion(response?.url ?? originalURL)
}.resume()
}
Older Swift Versions:
extension NSURL
{
func resolveWithCompletionHandler(completion: NSURL -> Void)
{
let originalURL = self
let req = NSMutableURLRequest(URL: originalURL)
req.HTTPMethod = "HEAD"
NSURLSession.sharedSession().dataTaskWithRequest(req) { body, response, error in
completion(response?.URL ?? originalURL)
}.resume()
}
}
// Example:
NSURL(string: "https://itun.es/us/JB7h_")!.resolveWithCompletionHandler {
print("resolved to \($0)") // prints https://itunes.apple.com/us/album/blackstar/id1059043043
}

Alireza Rezagholian
- 99
- 8

jtbandes
- 115,675
- 35
- 233
- 266