WKWebView 與 JS 互動簡單使用
阿新 • • 發佈:2019-02-02
通過調研,我決定使用WKWebView替換原來的UIWebView。
遇到的第一個問題就是WKWebView無法在我喜愛的xib上設定,通過翻牆搜尋資料,原來WKWebView沒有實現initWithCoder方法,自然也就找到了解決辦法:
自定義一個MyWebView,繼承自WKWebView
.h
#import <WebKit/WebKit.h>
@interface MyWebView : WKWebView
@end
.m
#import "MyWebView.h"
@implementation MyWebView
- (instancetype)initWithCoder:(NSCoder *)coder
{
CGRect frame = [[UIScreen mainScreen] bounds];
WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
configuration.userContentController = [WKUserContentController new];
WKPreferences *preferences = [WKPreferences new];
preferences.javaScriptCanOpenWindowsAutomatically = YES ;
configuration.preferences = preferences;
self = [super initWithFrame:frame configuration:configuration];
self.translatesAutoresizingMaskIntoConstraints = NO;
return self;
}
@end
這樣就可以像UIWebView一樣在xib設定約束了。
匯入MyWebView,投入使用
#import "WebViewController.h"
#import "MyWebView.h"
//1. 代理
@interface WebViewController ()<WKScriptMessageHandler, WKUIDelegate>
@property (strong, nonatomic) IBOutlet MyWebView *webView;
@end
@implementation WebViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *button = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"返回"] style:UIBarButtonItemStylePlain target:self action:@selector(goBack)];
self.navigationItem.leftBarButtonItem = button;
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlString]]];
self.webView.UIDelegate = self;
//JS呼叫OC:設定addScriptMessageHandler與name,並且設定<WKScriptMessageHandler>協議與協議方法
[self.webView.configuration.userContentController addScriptMessageHandler:self name:@"callNativeKaihu"];//開戶
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
// 移除handlers,防止記憶體洩露
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"callNativeKaihu"];
}
- (void)goBack{
if ([self.webView canGoBack]) {
[self.webView goBack];
}else{
[self.navigationController popViewControllerAnimated:YES];
}
}
#pragma mark - WKScriptMessageHandler
//OC在JS呼叫方法做的處理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
// 列印所傳過來的引數,只支援NSNumber, NSString, NSDate, NSArray, NSDictionary, NSNull型別
NSLog(@"JS呼叫了 %@ 方法,返回引數 %@",message.name, message.body);
if ([message.name isEqualToString:@"callNativeKaihu"]) {
DRElectronicAccountVC *vc = [[DRElectronicAccountVC alloc]initWithNibName:@"DRElectronicAccountVC" bundle:nil];
vc.dictionary = dic[@"data"];
[self.navigationController pushViewController:vc animated:YES];
}
}
WKWebView預設禁止了一些跳轉
- UIWebView
開啟www.apple.com/itunes/跳轉到appStore, 撥打電話, 喚起郵箱等一系列操作UIWebView預設支援的。 - WKWebView
預設禁止了以上行為,除此之外,js端通過alert(),彈窗的動作也被禁掉了。
如何支援呢?
首先要設定WKWebView的WKUIDelegate,並實現以下方法
#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
// js 裡面的alert實現,如果不實現,網頁的alert函式無效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
completionHandler();
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
// js 裡面的alert實現,如果不實現,網頁的alert函式無效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler(YES);
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
completionHandler(NO);
}]];
[self presentViewController:alertController animated:YES completion:^{}];
}
- (void)dealloc{
NSLog(@"觀測web檢視釋放");
}