WKWebView是苹果在 iOS8.0以后推出的新的 webView库。目前现在很多 APP 都混合了 webView,这个库将来的用处会越来越大。这一段正好有个小项目用到了WKWebView ,学习了一下,在这里写篇文章总结一下。
iOS 中和 webView 相关和交互的文件都放到了 WebKit 这个库中
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
上面是整个库的头文件。其中核心是WKWebView.h头文件。
WKWebView 执行js代码,是通过 WKUserContentController 和 WKUserScript两个类来实现
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"js"];
NSString *filejs = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
WKUserScript *userscript = [[WKUserScript alloc] initWithSource:filejsinjectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[wkUController addUserScript:userscript];
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
wkWebConfig.userContentController = wkUController;
self.webView = [[WKWebView alloc] initWithFrame:self.contentView.frame configuration:wkWebConfig];
首先创建WKUserScript对象,用来保存注入到 web View 的脚本。
一个脚本对应于一个 WKUserScript 对象
- (instancetype)initWithSource:(NSString *)source injectionTime:(WKUserScriptInjectionTime)injectionTime forMainFrameOnly:(BOOL)forMainFrameOnly;
第二步:创建WKUserContentController对象,WKUserContentController用来提供JavaScript 传递到 web view的方法。通过使用 - (void)addUserScript:(WKUserScript *)userScript 方法来增加脚本。
第三步 创建WKWebViewConfiguration 对象 这个对象用来收集初始化WKWebView 相关的属性信息。
他保有一个WKUserContentController类型的属性
@property (nonatomic, strong) WKUserContentController *userContentController;
第四步 初始化 WKWebView
self.webView = [[WKWebView alloc] initWithFrame:self.contentView.frame configuration:wkWebConfig];
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
WKWebView 通过这个语句来执行js语句,js语句执行的结果通过completionHandler block语句传递出来。
有时候需要在 JS 返回数据给 iOS APP,例如当点击一个条目的时候,希望把条目的信息传递给 iOS APP,可以
js 可以利用 window.webkit.messageHandlers..postMessage() 来进行传递数据。
例如
window.webkit.messageHandlers.appName.postMessage({body: '传数据'});
appName就是我们要注入的名称,注入以后,就可以在JS端调用了,传数据统一通过body传,可以是多种类型,只支持NSNumber, NSString, NSDate, NSArray,NSDictionary, and NSNull类型。
// 注入JS对象名称AppModel,当JS通过appName来调用时,
// 我们可以在WKScriptMessageHandler代理中接收到
[config.userContentController addScriptMessageHandler:self name:@"appName"];
当JS通过appName发送数据到iOS端时,通过WKScriptMessageHandler 代理,就会收到数据
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"AppModel"]) {
// 打印所传过来的参数,只支持NSNumber, NSString, NSDate, NSArray,
// NSDictionary, and NSNull类型
NSLog(@"%@", message.body);
}
}