たまにはPCから離れて生活するのも有りだなと思って、金曜の夜から今日の昼までほとんどPCを開かずに過ごしました。
その間にFeedlyで記事がたまりに溜まっていましたが、毎日数時間毎にFeedlyに張り付いて確認するよりは気持ち的には楽でした。笑
今日は、 APIKit で定義したRequestのURLをビルドして用いる方法のメモを残していきます。
特定のAPIだけ、APIKitでの通信ではなくて、WebView等で通信したい
基本的には APIKit で定義したRequestを、APIKitのSessionに流して通信を行うのですが、定義したRequestの一部をWebViewで行いたい場合があります。
例えば、 OAuth 認証みたいに、APIを叩いて、その認証をユーザーに行わせる画面のHTMLを返却するような場合に、
WebViewでURLと必要なパラメータを送信すれば表示できますが、 APIKit のSessionにRequestを投げてHTMLを取得してから表示…としようとするとうまくいかない場合が有ります。
そうなった時に、APIKitから外れて NSURLRequest
を定義して…っていうのも一つの手ですが、
- 他のAPIと共通のBaseURL等の定義箇所が増えてしまうので、何か変更があったときに面倒
- 他のAPIと同じように定義しておきたい
といった問題が出てきます。
自分もこれで躓いてどうするんだろうと思ってAPIKitのソースを眺めていたら、解決策が見つけられました。
APIKitのbuildURLRequest()
を使う
RequestType を継承していれば、buildURLRequest()を用いてNSURLRequestを生成することができます。
定義はこのようになっています。
public func buildURLRequest() -> Result.Result<NSURLRequest, APIKit.APIError>
APIKit では、Resultを利用しているので、この関数で返される値は、NSURLRequest
かAPIError
が入ったenumになっています。
なので、必要があれば返ってきたResult型のenumを検証して、NSURLRequestが使えるか調べる必要があります。
switch request.buildURLRequest() {
case .Success(let request):
webView.loadRequest(request)
case .Failure(let error):
print(error)
}
もし、確実にNSURLRequest
が作られる!というのが保証できるのであれば、以下のように書くこともできます。
webView.loadRequest(requestbuildURLRequest().value!)
使用例
あるAPISomeAPI
があって、その一つにAuthorizeRequest
というRequestがあったときに、
APIKitのSessionで通信するのではなくて、SFSafariViewControllerにURLを渡して通信を行う場合の例です。
final class SomeAPI {
}
protocol SomeRequestType: RequestType {
}
extension SomeRequestType {
var baseURL: NSURL {
return NSURL(string: "https://some.com/api/v9")!
}
}
extension SomeAPI {
struct AuthorizeRequest: SomeRequestType {
typealias Response = AnyObject
var method: HTTPMethod {
return .GET
}
var path: String {
return "/oauth/authorize"
}
var parameters: [String: AnyObject] {
return [
"client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"client_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
]
}
func responseFromObject(object: AnyObject, URLResponse: NSHTTPURLResponse) -> Response? {
return nil // Sessionでの通信がないので、何かする必要はなし
}
}
}
こんな感じに定義して、
import SafariServices
func openOAuth() {
let safariVC = SFSafariViewController(URL: SomeAPI.AuthorizeRequest().buildURLRequest().value!.URL!)
presentViewController(safariVC, animated: true, completion: nil)
}
とすることで、無事APIKitでの定義を活かしつつ、NSURLRequest
(この例では更にNSURLを取得しています)を作って利用することができます。