wkwebview替换uiwebview_项目笔记-UIWebView替换为WKWebView

随着iOS系统的更新,WKWebView逐渐替代UIWebView成为首选的网页视图组件。WKWebView在性能、内存管理和HTML5支持上都有显著优势。本文详细介绍了WKWebView与UIWebView的对比,JS交互方式,以及在实际项目中迁移UIWebView到WKWebView的步骤,包括API替换、兼容旧版JS调用和处理cookie的方法。
摘要由CSDN通过智能技术生成

背景

iOS8后推出WKWebView,到现在已经iOS13,UIWebView即将不支持。

对比

UIWebView:

加载速度慢、内存占用多

WKWebView(苹果官方文档):

在性能、稳定性、功能方面有很大提升(高达60fps的滚动刷新率以及内置手势);

支持了更多的HTML5特性、JavaScript库;

将UIWebViewDelegate与UIWebView重构成了14个类与3个协议;

JS交互

关于JS交互这篇很详细

UIWebView:

Native->JS

通过调用执行JS代码的API实现:

NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];

复制代码JS-> Native

1、在shouldStartLoadWithRequest:代理方法中拦截信息,与前端协商好URL映射到原生方法。该回调在前端href或者iframe变化时触发。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

NSString *url = request.URL.absoluteString;

if (url 字符串规则匹配) {

// 映射方法,执行Native逻辑

return NO;

}

return YES;

}

复制代码

2、通过JavaScriptCore注入

@protocol JSCallNativeFunc

-(void)dosomething

@end

self Class

//KVC得到WebView的JS上下文

JSContext *context = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

//给这个上下文注入JS对象

context[@"nativeObj"] = self;

//给这个上下文注入callNativeFunction函数当做JS对象

context[@"callNativeFunction"] = ^( JSValue * data )

{

//1 解读JS传过来的JSValue数据

//2 取出指令参数,确认要发起的native调用的指令

//3 取出数据参数,拿到JS传过来的数据

//4 根据指令调用对应的native方法,传递数据

//5 此时还可以将客户端的数据同步返回

}

-(void)dosomething{}

// js代码

nativeObj.dosomething()

复制代码

WKWebView:

Native->JS

通过调用执行JS代码的API实现:

[webView evaluateJavaScript:@"document.title"

completionHandler:^(id _Nullable title, NSError * _Nullable error) {

}];

复制代码JS-> Native

依靠WKScriptMessageHandler协议类和WKUserContentController两个类:

WKUserContentController对象负责注册JS方法,设置处理接收JS方法的代理,代理遵守WKScriptMessageHandler,实现捕捉到JS消息的回调方法

WKUserContentController * wkUController = [[WKUserContentController alloc] init];

[wkUController addScriptMessageHandler:self name:@"jsCallNativeFuncName"];

config.userContentController = wkUController;

#pragma mark - WKScriptMessageHandler

// 通过接收JS传出消息的name进行捕捉的回调方法

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message

{

// message.name ?= 'jsCallNativeFuncName'

SEL sel = NSSelectorFromString(message.name);

if ([_jsCallBack respondsToSelector:sel]) {

[_jsCallBack performSelector:sel];

} else {

NSLog(@"Not Found SEL:%@", message.name);

}

}

// 前端代码

window.webkit.messageHandlers.jsCallNativeFuncName.postMessage({});

复制代码

项目应用

针对我们工程现状的WK迁移方案总结

1.项目目录下扫描“UIWebview”,framework中的引用也可以检测出来

grep -r -n "UIWebView" ./

复制代码

2.API替换

初始化

config

delegate

对应API:

UIWebView

WKWebView

stringByEvaluatingJavaScriptFromString:

evaluateJavaScript: completionHandler:

shouldStartLoadWithRequest:

decidePolicyForNavigationAction:

3.兼容UIWebView中jsCallNative方法

通过js注入将WKWebView的js调用方式包装到UIWebView中原有的方法中,前端项目无需修改代码实现兼容

NSString *jsString = @"var nativeObj = new Object(); \

nativeObj.jsCallNativeFuncName = function(){ \

window.webkit.messageHandlers.jsCallNativeFuncName.postMessage({}); \

}";

WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jsString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];

[WKUserContentController addUserScript:wkUScript];

复制代码

4.关于cookie

/**

我们支持iOS11+,所以可以通过WKHTTPCookieStore以Config给webView注入已存在NSHTTPCookieStorage中的cookie

*/

+ (WKWebViewConfiguration *)wkWebViewConfiguration

{

WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];

if (@available(iOS 11.0, *)) {

WKHTTPCookieStore *cookieStore = configuration.websiteDataStore.httpCookieStore;

NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;

for (NSHTTPCookie *cookie in cookies) {

[cookieStore setCookie:cookie completionHandler:nil];

}

}

return configuration;

}

复制代码

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值