LoginSignup
7
5

More than 5 years have passed since last update.

WebKitでPrivateAPI使ってProxyを実装する

Last updated at Posted at 2018-05-01

やりたいこと

ある案件でアプリ内部組み込みブラウザのトラフィックを監視する必要が生まれた。
だから、当初はURLProtocolを使ってハンドリングしようとも考えたが、
URLProtocolUIWebViewでしか使えないので色々悩んだ結果
PrivateAPIに手を出してみたと言うお話。

実装

iOS11以上であれば全く難しくはない
iOS11未満であってもできなくはないがPrivateClassをNSClassFromString(:)
で持ってきて...
って話になるので割愛

WKURLSchemeHandlerなるものがあるのでそれで実装する。

let config = WKWebViewConfiguration()
config.setURLSchemeHandler(WebViewProtocol(), forURLScheme: "dummy")//_urlSchemeHandlersはlazyなのでdummyで初期化してあげる必要がある。

let _handlers = config.value(forKey: "_urlSchemeHandlers") as! NSMutableDictionary

_handlers.setObject(WebViewProtocol(), forKey: "https" as NSString)
_handlers.setObject(WebViewProtocol(), forKey: "http" as NSString)

webview = WKWebView(frame: self.view.frame, configuration: config)

ポイントは
WKWebViewConfiguration::setURLSchemeHandler
で"http","https"を登録すると落ちる(落とされる)ので
value(forKey:)"_urlSchemeHandlers"をそのままいじってしまうこと

(NSMutableDictionaryはクラスなので参照渡し)

んであとはProtocolの中身を書いてしまえばよい


import WebKit
import Alamofire

class WebViewProtocol:NSObject, WKURLSchemeHandler {
    func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
        print(urlSchemeTask.request)
        Alamofire.request(urlSchemeTask.request).response(queue: .main){res in
            if let error = res.error{
                urlSchemeTask.didFailWithError(error)
            }
            urlSchemeTask.didReceive(res.response!)
            urlSchemeTask.didReceive(res.data!)
            urlSchemeTask.didFinish()
        }
    }
    func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {

    }
}

まとめ

多分今後PrivateAPIについてもさもさ書くと思います。

7
5
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
7
5