LoginSignup
23
20

More than 5 years have passed since last update.

Swift で URL のクエリストリングを簡単に追加したい

Last updated at Posted at 2017-09-29

やりたいこと

Swift で URL のクエリストリングを簡単に追加したい
例)"https://qiita.com" -> "https://qiita.com?name=value"

環境

Swift 4.0

冗長になりやすい

Swift では文字列結合やURLComponentsを利用することでクエリストリングの追加が可能ですが、いずれも冗長な書き方となってしまいます。

  • 文字列結合を行う場合
let url = URL(string: "https://qiita.com")!
let queryStringAddedUrl = URL(string: 
    url.description.description + (nil == url.query ? "?" : "&") + "name=value"
) // https://qiita.com?name=value
  • URLComponentsを使用する場合
let url = URL(string: "https://qiita.com")!
var components = URLComponents(url: url, resolvingAgainstBaseURL: nil != url.baseURL)
components?.queryItems = [URLQueryItem(name: "name", value: "value")] + (components?.queryItems ?? [])
let queryStringAddedUrl = components?.url // https://qiita.com?name=value

簡潔にしてみた

簡潔に書きたかったのでURLに Extension を実装しました。

URL+.swift
extension URL {

    // クエリを一つ追加した新しいURLを返す
    func queryItemAdded(name: String,  value: String?) -> URL? {
        return self.queryItemsAdded([URLQueryItem(name: name, value: value)])
    }

    // クエリを複数追加した新しいURLを返す
    func queryItemsAdded(_ queryItems: [URLQueryItem]) -> URL? {
        guard var components = URLComponents(url: self, resolvingAgainstBaseURL: nil != self.baseURL) else {
            return nil
        }
        components.queryItems = queryItems + (components.queryItems ?? [])
        return components.url
    }

}

使ってみるとこうなります。シンプルです。

let queryStringAddedUrl = url.queryItemAdded(name: "name",  value: "value") // https://qiita.com?name=value

これだと困ること

  • 同一キーなクエリを追加する必要がある場合
  • String? 以外の型のまま追加したくなる場合

にはこれだけだと対応が難しいです。上の Extension を拡張していくのも良いですが、ググるとURLQueryBuilderのようなライブラリがあるので手を出してみるのもいいかもしれません。

23
20
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
23
20