由于安全機(jī)制的問題,WKWebView默認(rèn)對JavaScript下alert類的方法(包括alert(),confirm(),prompt())做了攔截,如果要想正常使用,需要實(shí)現(xiàn)WKWebView的三個(gè)代理方法
//用于攔截alert方法,實(shí)現(xiàn)該方法后可以js可以正常調(diào)用alert方法
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;
//用于攔截confirm方法,實(shí)現(xiàn)該方法后可以js可以正常調(diào)用confirm方法
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
//用于攔截prompt方法,實(shí)現(xiàn)該方法后可以js可以正常調(diào)用prompt方法
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler;
下面我們來看一下三個(gè)代理方法的具體實(shí)現(xiàn)
alert
//此方法作為js的alert方法接口的實(shí)現(xiàn),默認(rèn)彈出窗口應(yīng)該只有提示信息及一個(gè)確認(rèn)按鈕,當(dāng)然可以添加更多按鈕以及其他內(nèi)容,但是并不會起到什么作用
//點(diǎn)擊確認(rèn)按鈕的相應(yīng)事件需要執(zhí)行completionHandler,這樣js才能繼續(xù)執(zhí)行
////參數(shù) message為 js 方法 alert(<message>) 中的<message>
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"確認(rèn)" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
confirm
//作為js中confirm接口的實(shí)現(xiàn),需要有提示信息以及兩個(gè)相應(yīng)事件, 確認(rèn)及取消,并且在completionHandler中回傳相應(yīng)結(jié)果,確認(rèn)返回YES, 取消返回NO
//參數(shù) message為 js 方法 confirm(<message>) 中的<message>
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}])];
[alertController addAction:([UIAlertAction actionWithTitle:@"確認(rèn)" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
prompt
//作為js中prompt接口的實(shí)現(xiàn),默認(rèn)需要有一個(gè)輸入框一個(gè)按鈕,點(diǎn)擊確認(rèn)按鈕回傳輸入值
//當(dāng)然可以添加多個(gè)按鈕以及多個(gè)輸入框,不過completionHandler只有一個(gè)參數(shù),如果有多個(gè)輸入框,需要將多個(gè)輸入框中的值通過某種方式拼接成一個(gè)字符串回傳,js接收到之后再做處理
//參數(shù) prompt 為 prompt(<message>, <defaultValue>);中的<message>
//參數(shù)defaultText 為 prompt(<message>, <defaultValue>);中的 <defaultValue>
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = defaultText;
}];
[alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text?:@"");
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
2019-06-12 更新
只要走代理方法就一定要調(diào)用completionHandler閉包,否則會導(dǎo)致crash