LoginSignup
3
2

resolvingAgainstBaseURL 解説: Swiftで絶対URLと相対URL

Last updated at Posted at 2024-03-10

記事を書くに至った動機

URLのパラメーターを取得する際に
URLComponentsとinitializer内の第二引数のresolvingAgainstBaseURLは何だろうと気になった為、記事にしました。

init?(
    url: URL,
    resolvingAgainstBaseURL resolve: Bool
)

URLComponentとは

カスタムURLをスキームを利用した際に、

struct URLComponents

URLComponents を使用することで、URLを安全に組み立てたり分解したりすることが可能になります。

下記のように

init?(string URLString: String)

Stringから初期化してもいいのですが、
URLであることが保証されるresolvingAgainstBaseURL付きのイニシャライザを利用した方が安全かと思います。

resolvingAgainstBaseURLについて

本題ですが、
resolvingAgainstBaseURLをtrueにすると相対URLを絶対URLに変換する試みが行われます。
具体的にtrueの場合とfalseの場合の違いを見ていきます。

trueの場合

相対URLであれば、それをベースURLに対して解決し絶対URLを生成します。

if let baseURL = URL(string: "https://example.com/directory/"),
   let relativeURL = URL(string: "subdirectory/file", relativeTo: baseURL),
   let urlComponents = URLComponents(url: relativeURL, resolvingAgainstBaseURL: true) {
    print(urlComponents.url?.absoluteString ?? "Invalid URL")
}
// 出力: https://example.com/directory/subdirectory/file

falseの場合

falseにするとURLはそのまま使用され、ベースURLに対して相対URLを解決しません。

if let baseURL = URL(string: "https://example.com/directory/"),
   let relativeURL = URL(string: "subdirectory/file", relativeTo: baseURL),
   let urlComponents = URLComponents(url: relativeURL, resolvingAgainstBaseURL: false) {
    print(urlComponents.url?.absoluteString ?? "Invalid URL")
}
// 出力: subdirectory/file

実際のアプリでの使い方

実用的な使い方としてurlからパラメーターを取得するコードを載せます。

let urlString = "https://example.com/path?param1=value1&param2=value2"

// パラメーター名だけ取得したい場合
if let url = URL(string: urlString), let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
    let queryItemNames = urlComponents.queryItems?.map { $0.name } ?? []
    print(queryItemNames)
} else {
    print("Invalid URL")
}

// パラメーター名と値両方をreduceして取得したい場合
if let url = URL(string: urlString), let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
    let queryItems = urlComponents.queryItems ?? []
    let parameters = queryItems.reduce(into: [String: String]()) { (result, item) in
        result[item.name] = item.value
    }
    print(parameters)
} else {
    print("Invalid URL")
}

参照

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2