Skip to content

Instantly share code, notes, and snippets.

@tncowart
Last active September 5, 2019 00:43
Show Gist options
  • Save tncowart/9436b59bfb060c2b7fbe888e45d85352 to your computer and use it in GitHub Desktop.
Save tncowart/9436b59bfb060c2b7fbe888e45d85352 to your computer and use it in GitHub Desktop.
Splitting URL fragment into components
extension URL {
private func splitQuery(_ query: String) -> [String: [String]] {
return query.components(separatedBy: "&").map { $0.components(separatedBy: "=") }.reduce(into: [String: [String]]()) { result, element in
guard !element.isEmpty,
let key = element[0].removingPercentEncoding,
let value = element.count >= 2 ? element[1].removingPercentEncoding : "" else { return }
var values = result[key, default: [String]()]
values.append(value)
result[key] = values
}
}
var fragmentItems: [String: [String]] {
guard let fragment = self.fragment else {
return [:]
}
return splitQuery(fragment)
}
var queryItems: [String: [String]] {
guard let query = self.query else {
return [:]
}
return splitQuery(query)
}
}
// queryItems has the same behavior as fragmentItems
let test = URL(string: "http://example.com#name=Alice%20Barker&name=Bob&job=developer")!
test.fragmentItems // ["name": ["Alice Barker", "Bob"], "job": ["developer"]]
test.fragmentItems["name"] // Optional(["Alice Barker", "Bob"])
let test2 = URL(string: "http://example.com#name")!
test2.fragmentItems // ["name": [""]]
test2.fragmentItems["name"] // Optional([""])
let test3 = URL(string: "http://example.com#")!
test3.fragmentItems // ["": [""]]
test3.fragmentItems["name"] // nil
let test4 = URL(string: "http://example.com")!
test4.fragmentItems // [:]
test4.fragmentItems["name"] // nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment