URLの構造をバラして部位ごとに上書きや追加をすることができます。
コードは出来たてで検証もそこそこです。
何か補足や訂正などありましたら是非ともコメント欄で教えてください。
Swift version 3.0.2
extension URL {
func ext_set(scheme: String? = nil,
user: String? = nil,
password: String? = nil,
host: String? = nil,
port: Int? = nil,
path: String? = nil,
query: String? = nil,
fragment: String? = nil)
-> URL? {
var result = ""
if let scheme = scheme ?? self.scheme,
!scheme.characters.isEmpty {
result += scheme + "://"
}
if let user = user ?? self.user,
!user.characters.isEmpty {
result += user
if let password = password ?? self.password {
result += ":" + password
}
result += "@"
}
if let host = host ?? self.host,
!host.characters.isEmpty {
result += host
if let port = port ?? self.port,
0...65535 ~= port {
result += ":\(port)"
}
result += path ?? self.path
if self.hasDirectoryPath,
!result.hasSuffix("/") { // trailing slash or not
result += "/"
}
if let query = query ?? self.query,
!query.characters.isEmpty {
result += "?" + query
}
if let fragment = fragment ?? self.fragment,
!fragment.characters.isEmpty {
result += "#" + fragment
}
}
return URL(string: result)
}
}
Example
必要な箇所だけを指定して上書きor追加します。
空文字もしくは許容範囲外のポート番号を指定した場合は削除となります。
let url = URL(string: "http://test.example.com/s?t=0")!
url.ext_set(scheme: "vvvvv")
// -> vvvvv://test.example.com/s?t=0
url.ext_set(host: "yahoo.co.jp")
// -> http://yahoo.co.jp/s?t=0
url.ext_set(port: 8080, path: "/box/index.html")
// -> http://test.example.com:8080/box/index.html?t=0
url.ext_set(query: "q=test&lat=35.7&lon=139.7")
// -> http://test.example.com/s?q=test&lat=35.7&lon=139.7
url.ext_set(path: "", query: "")
// -> http://test.example.com
url.ext_set(fragment: "s3")
// -> http://test.example.com/s?t=0#s3
url.ext_set(user: "example.com&q=menu")
// -> http://example.com&q=menu@test.example.com/s?t=0 // Spoofed URL