澳门威利斯人_威利斯人娱乐「手机版」

来自 澳门威利斯人 2020-03-26 01:52 的文章
当前位置: 澳门威利斯人 > 澳门威利斯人 > 正文

IOS进阶之WKWebView

图片 1标题图片

主干使用方式WKWebView有多个delegate,WKUIDelegateWKNavigationDelegate。WKNavigationDelegate首要管理部分跳转、加载管理操作,WKUIDelegate首要处理JS脚本,确认框,警示框等。由此WKNavigationDelegate尤其常用。相比较常用的格局:

Xcode8揭橥之后,编写翻译器起初不帮助IOS7,所以重重利用在适配IOS10将来都不在适配IOS7了,在那之中囊括了无尽大商家,和讯快讯,滴滴出游等。因而,大家集团的选用也思考淘汰IOS7。

#pragma mark - lifeCircle- 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// 页面开始加载时调用- webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{}// 当内容开始返回时调用- webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{}// 页面加载完成之后调用- webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{}// 页面加载失败时调用- webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{}// 接收到服务器跳转请求之后调用- webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{}// 在收到响应后,决定是否跳转- webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(WKNavigationResponsePolicy))decisionHandler{ NSLog(@"%@",navigationResponse.response.URL.absoluteString); //允许跳转 decisionHandler(WKNavigationResponsePolicyAllow); //不允许跳转 //decisionHandler(WKNavigationResponsePolicyCancel);}// 在发送请求之前,决定是否跳转- webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(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];}// 输入框- webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(NSString * __nullable result))completionHandler{ completionHandler;}// 确认框- webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(BOOL result))completionHandler{ completionHandler;}// 警告框- webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:completionHandler{ NSLog(@"%@",message); completionHandler();}

支撑到IOS8,第二个要改的当然是用WKWebView轮流原本的UIWebView。WKWebView有众多醒目优势:

OC与JS交互作用WKWebview提供了API达成js人机联作不供给依附JavaScriptCore也许webJavaScriptBridge。使用WKUserContentController实现js native人机联作。同理可得就是先注册约定好的法子,然后再调用。

  • 越多的支撑HTML5的特点

  • 官方注明的高达60fps的滚动刷新率以至内置手势

  • 将UIWebViewDelegate与UIWebView拆分成了14类与3个公约,早前相当多不便宜完结的意义可以兑现。文书档案

  • Safari相同的JavaScript引擎

  • 侵吞越来越少的内存

JS调用OC方法oc代码:

UIWebView

@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>{ WKWebView * webView; WKUserContentController* userContentController;}@end@implementation ViewController#pragma mark - lifeCircle- 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"]]];}- dealloc{ //这里需要注意,前面增加过的方法一定要remove掉。 [userContentController removeScriptMessageHandlerForName:@"sayhello"];}#pragma mark - WKScriptMessageHandler- userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"name:%@\\n body:%@\\n frameInfo:%@\\n",message.name,message.body,message.frameInfo);}@end

图片 2UIWebView

地点的OC代码倘诺证实地衡量试一下就能够意识dealloc并不会进行,那样必然是非常的,会招致内部存款和储蓄器泄漏。原因是[userContentController addScriptMessageHandler:self name:@"sayhello"];那句代码形成无法自由内部存款和储蓄器。(ps:试了下用weak指针依然不能够放出,不精通是怎么原因。)由此还亟需越来越改善,准确的写法是用三个新的controller来管理,新的controller再绕用delegate绕回来。

WKWebView

oc代码:

图片 3WKWebView

@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>{ WKWebView * webView; WKUserContentController* userContentController;}@end@implementation ViewController#pragma mark - lifeCircle- 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"]]];}- dealloc{ //这里需要注意,前面增加过的方法一定要remove掉。 [userContentController removeScriptMessageHandlerForName:@"sayhello"];}#pragma mark - WKScriptMessageHandler- userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"name:%@\\n body:%@\\n frameInfo:%@\\n",message.name,message.body,message.frameInfo);}@end

因此,使用WkWebview替换UIWebView抑或很有不可紧缺的。

WKDelegateController代码:

WKWebView有两个delegate,WKUIDelegateWKNavigationDelegate。WKNavigationDelegate首要管理部分跳转、加载管理操作,WKUIDelegate主要管理JS脚本,确认框,警示框等。因而WKNavigationDelegate尤其常用。

#import <UIKit/UIKit.h>#import <WebKit/WebKit.h>@protocol WKDelegate <NSObject>- userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;@end@interface WKDelegateController : UIViewController <WKScriptMessageHandler>@property (weak , nonatomic) id<WKDelegate> delegate;@end

正如常用的措施:

.m代码:

#pragma mark - lifeCircle- 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// 页面开始加载时调用- webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{}// 当内容开始返回时调用- webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{}// 页面加载完成之后调用- webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{}// 页面加载失败时调用- webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{}// 接收到服务器跳转请求之后调用- webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{}// 在收到响应后,决定是否跳转- webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(WKNavigationResponsePolicy))decisionHandler{ NSLog(@"%@",navigationResponse.response.URL.absoluteString); //允许跳转 decisionHandler(WKNavigationResponsePolicyAllow); //不允许跳转 //decisionHandler(WKNavigationResponsePolicyCancel);}// 在发送请求之前,决定是否跳转- webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(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];}// 输入框- webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(NSString * __nullable result))completionHandler{ completionHandler;}// 确认框- webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(BOOL result))completionHandler{ completionHandler;}// 警告框- webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:completionHandler{ NSLog(@"%@",message); completionHandler();}
#import "WKDelegateController.h"@interface WKDelegateController ()@end@implementation WKDelegateController- viewDidLoad { [super viewDidLoad];}- userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ if ([self.delegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) { [self.delegate userContentController:userContentController didReceiveScriptMessage:message]; }}@end

WKWebview提供了API达成js交互作用不需求依附JavaScriptCore可能webJavaScriptBridge。使用WKUserContentController达成js native人机联作。说来讲去正是先注册约定好的法子,然后再调用。

h5代码:

oc代码:

<html><head> <script>function say(){//前端需要用 window.webkit.messageHandlers.注册的方法名.postMessage({body:传输的数据} 来给native发送消息 window.webkit.messageHandlers.sayhello.postMessage({body: 'hello world!'});}</script></head> <body> <h1>hello world</h1> <button onclick="say()">say hello</button> </body></html>
@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>{ WKWebView * webView; WKUserContentController* userContentController;}@end@implementation ViewController#pragma mark - lifeCircle- 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"]]];}- dealloc{ //这里需要注意,前面增加过的方法一定要remove掉。 [userContentController removeScriptMessageHandlerForName:@"sayhello"];}#pragma mark - WKScriptMessageHandler- userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"name:%@\\n body:%@\\n frameInfo:%@\\n",message.name,message.body,message.frameInfo);}@end

打字与印刷出的log:

下边包车型地铁OC代码借使证实测量试验一下就能意识dealloc并不会实行,这样必然是老大的,会促成内部存款和储蓄器泄漏。原因是[userContentController addScriptMessageHandler:self name:@"sayhello"];那句代码产生不只怕自由内部存储器。(ps:试了下用weak指针依旧不可能假释,不驾驭是什么样原因。)因而还亟需更为纠正,精确的写法是用叁个新的controller来管理,新的controller再绕用delegate绕回来。

 name:sayhello body:{ body = "hello world!";} frameInfo:<WKFrameInfo: 0x7f872060ce20; isMainFrame = YES; request = <NSMutableURLRequest: 0x618000010a30> { URL: http://www.test.com/ }>

oc代码:

WebViewJavascriptBridge平常的话,二个好的UI总有二个大神会开荒出三个好的第三方卷入框架。WebViewJavascriptBridge的笔者也做了一套援救WKWebView与JS人机联作的第三方框架:WKWebViewJavascriptBridge。cocoaPods: pod 'WebViewJavascriptBridge', '~> 5.0.5'

@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>{ WKWebView * webView; WKUserContentController* userContentController;}@end@implementation ViewController#pragma mark - lifeCircle- 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"]]];}- dealloc{ //这里需要注意,前面增加过的方法一定要remove掉。 [userContentController removeScriptMessageHandlerForName:@"sayhello"];}#pragma mark - WKScriptMessageHandler- userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"name:%@\\n body:%@\\n frameInfo:%@\\n",message.name,message.body,message.frameInfo);}@end

github地址:

WKDelegateController代码:

根本方法如下:

#import <UIKit/UIKit.h>#import <WebKit/WebKit.h>@protocol WKDelegate <NSObject>- userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;@end@interface WKDelegateController : UIViewController <WKScriptMessageHandler>@property (weak , nonatomic) id<WKDelegate> delegate;@end
//初始化方法  (instancetype)bridgeForWebView:(WKWebView*)webView;  enableLogging;//注册函数名- registerHandler:(NSString*)handlerName handler:(WVJBHandler)handler;//调用函数名- callHandler:(NSString*)handlerName;- callHandler:(NSString*)handlerName data:data;- callHandler:(NSString*)handlerName data:data responseCallback:(WVJBResponseCallback)responseCallback;//重置- reset;//设置WKNavigationDelegate- setWebViewDelegate:(id<WKNavigationDelegate>)webViewDelegate;

本文由澳门威利斯人发布于澳门威利斯人,转载请注明出处:IOS进阶之WKWebView

关键词: 澳门威利斯人 IOS 进阶 WKWebView