1. 程式人生 > >WKWebView 與 JS 互動簡單使用

WKWebView 與 JS 互動簡單使用

通過調研,我決定使用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檢視釋放");
}