UIWebView vs WKWebView
以前から、Webページを表示するにはUIWebViewが使用されてきました。ただ、iOS 8から導入されたWKWebViewというのがありまして、こちらのほうがJavaScriptの実行が速かったりするなど、色々と改善されているようです。
そういうことなら、すぐにWKWebViewに移行したいところですが、iOS 7では使用できません。iOS7以前では、UIWebViewを使用する必要があります。
また、UIWebViewとWKWebViewでは、delegateメソッドが微妙に異なるので、両対応をしようとすると両方のdelegateメソッドを書かなくてはならず、手間がかかります。
作ってみた
というわけで、UIWebViewとWKWebViewを自動切り替えする仕組みを作ってみました。
ソースはこちら
とは言え、WebViewのフル機能に対応するのは面倒なので、必要な機能のみに絞っています。
今回作ったのは、以下の機能だけです。
- URL request設定
- URLを開くかどうかの判定(カスタムスキーム用)
- ローディング開始
- ローディング終了
- ローディングエラー
作っては見たものの、いまいち自信がないので、誰か改良してくださらないですかね |д゚)チラッ
(特に、UIViewを挟んでいるのが、よろしくない気がする。)
ちょっと説明
名前がTOTWebViewというわりに、そのものはWebViewではなくUIViewを継承しています。 で、 initのところでSubViewとして UIWebView or WKWebViewを追加しています。
if ([WKWebView class]) {
_wkWebView = [[WKWebView alloc] initWithFrame:frame];
_wkWebView.navigationDelegate = self;
_wkWebView.UIDelegate = self;
[self addSubview:_wkWebView];
} else {
_uiWebView = [[UIWebView alloc] init];
_uiWebView.delegate = self;
[self addSubview:_uiWebView];
}
あとは、UIWebViewとWKWebViewの両方のdelegateメソッドを用意しておいて、その中身で独自に定義したDelegate を返すようにしています。
// 独自定義の delegate
@protocol TOTWebViewDelegate
- (BOOL)shouldStartLoadWithURL:(NSURL*)url;
- (void)didStartLoading;
- (void)didFinishLoading;
- (void)didFailLoadingWithError:(NSError*)error;
@end
WKWebViewだと、Webサイト読み込みにプログレスが取れたりするのですが、UIWebViewだと取れません。なので、機能が低い方に合わせることにします。
WKWebView雑感など
今回は、アプリの中でWebViewを使用するという要件があって、このような調査をしてみた次第です。
ただ、WKWebView はまだまだノウハウが少なく、これまで長年使われてきたUIWebViewに比べるとだいぶ差があります。普通にWeb閲覧用途で使用するには問題無いとは思うのですが、Cookieを独自で設定するだとか、そういうちょっと凝ったことをしようとすると、調査に骨が折れます。
あと、テストも手間を考えると、なかなか両対応には踏み出せないところもあります。
というわけで、両対応する仕組みを作ってみたものの、結局はUIWebViewのみで作ることになったのでした。
参考サイト
-
let UIWebView as WKWebView - Yahoo! JAPAN Tech Blog
この記事を見て、作ってみようと思い立ちました。たぶん、↑のやり方が正当なやり方なのかなあ、という気がします。