IOS進級のWKWebView
10927 ワード
前言
Xcode 8がリリースされた後、コンパイラはIOS 7をサポートしなくなったため、多くのアプリケーションはIOS 10に適してからIOS 7に適していない.その中には多くの大手企業、網易ニュース、滴滴移動などが含まれている.そのため、当社のアプリケーションもIOS 7を淘汰するつもりです.
IOS 8にサポートされ、最初に変更するのは、元のより多くのHTML 5をサポートする機能 公式に発表された60 fpsまでのスクロールリフレッシュ率と内蔵ジェスチャー はUIWebViewDelegateとUIWebViewを14種類と3つのプロトコルに分割し、以前は多くの不便な機能が実現されていた.文書 Safari同じJavaScriptエンジン より少ないメモリ消費量 UIWebView
UIWebView
WKWebView
WKWebView
したがって、
基本的な使い方
WKWebViewにはdelegate,WKUIdelegate,WKNavigationDelegteの2つがあります.WKNavigationDelegateは主にいくつかのジャンプ、ロード処理操作を処理し、WKUIdelegateは主にJSスクリプト、確認ボックス、警告ボックスなどを処理する.そのため、WKNavigationDelegateはもっとよく使われています.
一般的な方法:
OCとJSのインタラクション
WKWebviewは、JavaScriptCoreまたはwebJavaScriptBridgeを使用することなく、jsインタラクションを実現するAPIを提供します.WKUSerContentControlを使用してjs nativeインタラクションを実現します.簡単に言えば、約束した方法を登録してから呼び出します.
JS呼び出しOCメソッド
ocコード(エラーがあり、メモリが解放されません):
上のOCコードは認証テストをするとdeallocが実行されないことがわかります.これはだめです.メモリが漏洩します.なぜなら、
ocコード(正しい書き方):
WKdelegateControllerコード:
.mコード:
h 5コード:
印刷されたロゴ:
注意点 h 5は1つのパラメータしか伝達できません.複数のパラメータが必要な場合は辞書またはjsonで組み立てる必要があります.
oc呼び出しJSメソッド
コードは次のとおりです.
h 5コードは上です.
WebViewJavascriptBridge
一般的に、良いUIには、良いサードパーティ製のパッケージフレームワークが開発されます.WebViewJavascriptBridgeの著者も、WKWebViewとJSのインタラクションをサポートするサードパーティフレームワーク:WKWebViewJavascriptBridgeを作成しました. cocoaPods: pod 'WebViewJavascriptBridge', '~> 5.0.5' githubアドレス:https://github.com/marcuswestin/WebViewJavascriptBridge
主な方法は次のとおりです.
基本的な実現方法と上に書いたものの差は多くありませんが、パッケージして、興味のある子供靴は自分でpodして使うことができます.
文/o転がる牛の赤ちゃんo(簡書作者)原文リンク:http://www.jianshu.com/p/4fa8c4eb1316著作権は作者の所有で、転載は作者に連絡して授権を得て、そして“簡書の作者”を表示してください.
私は何百回もコードを虐待して、コードは私を初恋のように扱っています!
Xcode 8がリリースされた後、コンパイラはIOS 7をサポートしなくなったため、多くのアプリケーションはIOS 10に適してからIOS 7に適していない.その中には多くの大手企業、網易ニュース、滴滴移動などが含まれている.そのため、当社のアプリケーションもIOS 7を淘汰するつもりです.
IOS 8にサポートされ、最初に変更するのは、元の
WKWebView
をUIWebView
に置き換えることです.WKWebViewには明らかなメリットがたくさんあります.UIWebView
WKWebView
WKWebView
したがって、
WkWebview
をUIWebView
に置き換える必要がある.基本的な使い方
WKWebViewにはdelegate,WKUIdelegate,WKNavigationDelegteの2つがあります.WKNavigationDelegateは主にいくつかのジャンプ、ロード処理操作を処理し、WKUIdelegateは主にJSスクリプト、確認ボックス、警告ボックスなどを処理する.そのため、WKNavigationDelegateはもっとよく使われています.
一般的な方法:
#pragma mark - lifeCircle
- (void)viewDidLoad {
[super viewDidLoad];
webView = [[WKWebView alloc]init];
[self.view addSubview:webView];
[webView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view);
make.right.equalTo(self.view);
make.top.equalTo(self.view);
make.bottom.equalTo(self.view);
}];
webView.UIDelegate = self;
webView.navigationDelegate = self;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
}#pragma mark - WKNavigationDelegate//
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
}//
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
}//
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
}//
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
}//
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
}// ,
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{ NSLog(@"%@",navigationResponse.response.URL.absoluteString); //
decisionHandler(WKNavigationResponsePolicyAllow); // //decisionHandler(WKNavigationResponsePolicyCancel);
}// ,
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{ NSLog(@"%@",navigationAction.request.URL.absoluteString); //
decisionHandler(WKNavigationActionPolicyAllow); // //decisionHandler(WKNavigationActionPolicyCancel);
}#pragma mark - WKUIDelegate// WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{ return [[WKWebView alloc]init];
}//
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
completionHandler(@"http");
}//
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
completionHandler(YES);
}//
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{ NSLog(@"%@",message);
completionHandler();
}
OCとJSのインタラクション
WKWebviewは、JavaScriptCoreまたはwebJavaScriptBridgeを使用することなく、jsインタラクションを実現するAPIを提供します.WKUSerContentControlを使用してjs nativeインタラクションを実現します.簡単に言えば、約束した方法を登録してから呼び出します.
JS呼び出しOCメソッド
ocコード(エラーがあり、メモリが解放されません):
@interface ViewController (){
WKWebView * webView;
WKUserContentController* userContentController;
}@end@implementation ViewController#pragma mark - lifeCircle
- (void)viewDidLoad {
[super viewDidLoad]; //
WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
userContentController =[[WKUserContentController alloc]init];
configuration.userContentController = userContentController;
webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, 100, 100) configuration:configuration]; //
[userContentController addScriptMessageHandler:self name:@"sayhello"];// name sayhello js
[self.view addSubview:webView];
[webView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view);
make.right.equalTo(self.view);
make.top.equalTo(self.view);
make.bottom.equalTo(self.view);
}];
webView.UIDelegate = self;
webView.navigationDelegate = self;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.test.com"]]];
}
- (void)dealloc{ // , remove 。
[userContentController removeScriptMessageHandlerForName:@"sayhello"];
}#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"name:%@\\\
body:%@\\\
frameInfo:%@\\\
",message.name,message.body,message.frameInfo);
}@end
上のOCコードは認証テストをするとdeallocが実行されないことがわかります.これはだめです.メモリが漏洩します.なぜなら、
[userContentController addScriptMessageHandler:self name:@"sayhello"];
というコードがメモリを解放できないためです.(ps:weakポインタを使ってみても解放できないのは、どういうわけか分かりません.)そのため、正確な書き方は新しいcontrollerで処理され、新しいcontrollerはdelegateで巻き戻されるようにさらに改善する必要があります.ocコード(正しい書き方):
@interface ViewController (){
WKWebView * webView;
WKUserContentController* userContentController;
}@end@implementation ViewController#pragma mark - lifeCircle
- (void)viewDidLoad {
[super viewDidLoad]; //
WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
userContentController =[[WKUserContentController alloc]init];
configuration.userContentController = userContentController;
webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, 100, 100) configuration:configuration]; //
WKDelegateController * delegateController = [[WKDelegateController alloc]init];
delegateController.delegate = self;
[userContentController addScriptMessageHandler:delegateController name:@"sayhello"];
[self.view addSubview:webView];
[webView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view);
make.right.equalTo(self.view);
make.top.equalTo(self.view);
make.bottom.equalTo(self.view);
}];
webView.UIDelegate = self;
webView.navigationDelegate = self;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.test.com"]]];
}
- (void)dealloc{ // , remove 。
[userContentController removeScriptMessageHandlerForName:@"sayhello"];
}#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"name:%@\\\
body:%@\\\
frameInfo:%@\\\
",message.name,message.body,message.frameInfo);
}@end
WKdelegateControllerコード:
#import #import @protocol WKDelegate
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;@end@interface WKDelegateController : UIViewController @property (weak , nonatomic) id delegate;@end
.mコード:
#import "WKDelegateController.h"@interface WKDelegateController ()@end@implementation WKDelegateController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ if ([self.delegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
[self.delegate userContentController:userContentController didReceiveScriptMessage:message];
}
}@end
h 5コード:
function say()
{// window.webkit.messageHandlers. .postMessage({body: } native window.webkit.messageHandlers.sayhello.postMessage({body: 'hello world!'});
} hello world
印刷されたロゴ:
name:sayhello
body:{
body = "hello world!";
}
frameInfo: { URL: http://www.test.com/ }>
注意点
addScriptMessageHandler
はremoveScriptMessageHandlerForName
と組み合わせて発生しなければならない.そうしないと、メモリの漏れを引き起こす.oc呼び出しJSメソッド
コードは次のとおりです.
- (void)webView:(WKWebView *)tmpWebView didFinishNavigation:(WKNavigation *)navigation{ //say() JS ,completionHandler block
[webView evaluateJavaScript:@"say()" completionHandler:^(id _Nullable result, NSError * _Nullable error) { NSLog(@"%@",result);
}];
}
h 5コードは上です.
WebViewJavascriptBridge
一般的に、良いUIには、良いサードパーティ製のパッケージフレームワークが開発されます.WebViewJavascriptBridgeの著者も、WKWebViewとJSのインタラクションをサポートするサードパーティフレームワーク:WKWebViewJavascriptBridgeを作成しました.
主な方法は次のとおりです.
//
+ (instancetype)bridgeForWebView:(WKWebView*)webView;
+ (void)enableLogging;//
- (void)registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler;//
- (void)callHandler:(NSString*)handlerName;
- (void)callHandler:(NSString*)handlerName data:(id)data;
- (void)callHandler:(NSString*)handlerName data:(id)data responseCallback:(WVJBResponseCallback)responseCallback;//
- (void)reset;// WKNavigationDelegate
- (void)setWebViewDelegate:(id)webViewDelegate;
基本的な実現方法と上に書いたものの差は多くありませんが、パッケージして、興味のある子供靴は自分でpodして使うことができます.
文/o転がる牛の赤ちゃんo(簡書作者)原文リンク:http://www.jianshu.com/p/4fa8c4eb1316著作権は作者の所有で、転載は作者に連絡して授権を得て、そして“簡書の作者”を表示してください.
私は何百回もコードを虐待して、コードは私を初恋のように扱っています!