Kyobashi.swift復習(OSSから学ぶSwift実践テクニック)

今回は、先日のポストで紹介する余裕がなかった、OSSから学ぶSwift実践テクニックについて詳しく見てみたいと思います。
題材として取り上げられていたOSSは、Alamofireです。

ProtocolとExtensionで 組み込み型を抽象化(5枚目〜)

README.md

Alamofire.request(.GET, "https://httpbin.org/get")

って書いてあるけど Alamofire.swiftには

 public func request(
    method: Method,
    _ URLString: URLStringConvertible,
    parameters: [String: AnyObject]? = nil,
    encoding: ParameterEncoding = .URL,
    headers: [String: String]? = nil)
    -> Request

とあって、Stringじゃない!
じゃあ、URLStringConvertibleって何かっていうと、

public protocol URLStringConvertible {
    var URLString: String { get }
}
extension String: URLStringConvertible {
    public var URLString: String {
        return self
    }
}
extension NSURL: URLStringConvertible {
    public var URLString: String {
        return absoluteString
    }
}
extension NSURLComponents: URLStringConvertible {
    public var URLString: String {
        return URL!.URLString
    }
}
extension NSURLRequest: URLStringConvertible {
    public var URLString: String {
        return URL!.URLString
    }
}

という感じ。
最初、既存クラスがprotocolの拡張になっている、というところが理解できなかったのですが、 The Swift Programming Language (Swift 2.1) > Protocols > Adding Protocol Conformance with an Extension のあたりに詳しく記載がありました。
Swiftのextensionは既存クラスにcomputed propertyを追加したり、 既存クラスを、あるprotocolに適合させるために使うことができるために、こういう記法が使えるみたいですね。

メソッドチェーンで requestを使いやすく

これは、先程の記法より理解しやすいですね。
それぞれのメソッドでselfを返却しているので、ドットシンタックスメソッドチェーンを作りやすくなっているという話です。

 public func stream(closure: (NSData -> Void)? = nil) -> Self {
        if let dataDelegate = delegate as? DataTaskDelegate {
            dataDelegate.dataStream = closure
        }
        return self
    }

    public func authenticate(usingCredential credential: NSURLCredential) -> Self {
        delegate.credential = credential
        return self
    }

まとめ

イケてる実装しているOSSのコードをこうやって解説してくれるの、ありがたいですね。
extensionの仕様がObjective-Cのcategoryとだいぶ違うことに気付けたのが、大きな収穫でした。

参考