えいむーさんは明日も頑張るよ

よく使うURLのExtensionまとめ

価格

# URL + Extension

Swift の URL の定義はいろいろ抜けているところがある。本記事はあれってどうやるんだっけという Swift の URL の抜けているところを補うことを目的としたものである。

# URL

URL は String からインスタンスを生成することが多いと思うのだが、URL に変換不可能な文字列が存在するせいでOptional<URL>を返す。そのせいでいちいちオプショナルを外さなければならないので、定数値で確実初期化が成功するとわかっている場合にはアンラップしてしまうのが良い。

ただし、あちこちでアンラップしていると万が一クラッシュしたときにわけがわからなくなるので、アンラップしたイニシャライザを定義してそれを使い回すと良い。

extension URL {
    public init(unsafeString: String) {
        // swiftlint:disable:next force_unwrapping
        self.init(string: unsafeString)!
    }
}

# URLEncoding

URL エンコードした文字列が欲しい場合があるが、URL エンコードは String に対してしか有効でない。

OAuth の署名を作成するときなどは URL 自体を URL エンコードしないといけない場合があるので、覚えておくと良いかも知れない。

extension URL {
    func percentEncodedString(with: CharacterSet) -> String {
        // swiftlint:disable:next force_unwrapping
        self.absoluteString.addingPercentEncoding(withAllowedCharacters: with)!
    }
}

# QueryParameters

GET リクエストなどでクエリにパラメータを埋め込む場合に使える。

辞書をURLQueryItemに変換してURLComponentsに追加してからその URL だけを返す。

URLQueryItem は自動で URL エンコードされるので安全である。

extension URL {
    /// URLにクエリパラメータを追加する
    func appendQueryParameters(_ parameters: [String: Any]) -> URL {
        var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
        components?.queryItems = parameters.compactMap { URLQueryItem(name: $0.key, value: $0.value as? String) }
        // swiftlint:disable:next force_unwrapping
        return components!.url!
    }
}

Alamofire を利用している場合はもっと簡単にparametersに辞書を設定し、encodingとしてURLEncoding.queryStringを指定すれば良い。そうすればリクエスト前に自動的にクエリパラメータがリクエスト URL に追加される。

逆にURLQueryItemsからDictionaryが欲しい場合もあると思うので書いておく。

extension URL {
    /// クエリパラメータをDictionaryに変換する
    func asDictionary() -> [String: Any] {
        guard let queryItems = URLComponents(string: self.absoluteString)?.queryItems else {
            return [:]
        }
        return queryItems.reduce(into: [String: Any]()) { dict, queryItem in
            dict[queryItem.name] = value
        }
    }
}

価格
    えいむーさんは明日も頑張るよ © 2022