iOS WKWebview和JS的一次交互

起因是因为公司最近的活动比较多,在H5页面需要我们做分享,我们做监控app的分享并做回调,比如说转盘抽奖活动,分享一次需要我们这边调个接口,分享成功抽奖次数+1。

我给出的建议是把以后的页面需要分享的页面都交给我们来做,避免每出一个活动还有重新传包。

  • 只要前端在页面的onclick函数里面写下(iOS)
window.webkit.messageHandlers.share.postMessage({title:'分享的标题',
                                                                content:'分享的内容',
                                          url:'https://www.jianshu.com/u/71b03c7180a1'});

(Android)

window.AndroidShare.share("{'title':'交互数据','next': 1}");
  • 我们通过给每次的H5链接拼接iOSAndroid字符串让前端判断是安卓还是iOS。
// 这个表示链接前面已经有拼接了一些参数
if ([self.urlString containsString:@"&"]) {
        self.urlString = [self.urlString stringByAppendingString:@"&iOS"];
} 
// 表示链接前面没有拼接参数
else {
        self.urlString = [self.urlString stringByAppendingString:@"?iOS"];
}
  • WKWebView的创建
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
// 监听页面的share标识符
    [userContentController addScriptMessageHandler:self name:@"share"];
    configuration.userContentController = userContentController;
    
    WKPreferences *preferences = [WKPreferences new];
    preferences.javaScriptCanOpenWindowsAutomatically = YES;
    preferences.minimumFontSize = 40.0;
    configuration.preferences = preferences;
    
    self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
    self.webView.navigationDelegate = self;
    self.webView.UIDelegate = self;
    [self.view addSubview:self.webView];
    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.urlString]]];
  • 遵循WKScriptMessageHandler协议,并实现
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    //message.boby就是JS里传过来的参数
    if ([message.name isEqualToString:@"share"]) {
        NSLog(@"body = %@",message.body);
    }
}
  • 注意移除
 // 视图将要消失
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"share"];
}

数据处理

window.webkit.messageHandlers.share.postMessage({title:'分享的标题',
                                                                content:'分享的内容',
                                          url:'https://www.jianshu.com/u/71b03c7180a1'});

后面postMessage的数据根据需要给我们,我们这里是分享,我需要前端给我的数据有分享出去到微信三方显示的,网页地址,标题,副标题,图片地址,还需要分享的时候客户端要做的请求的URL,请求完后的弹窗提示message。

WKWebview一个小坑

  • 前端和我说他那边写的一个alertJS在项目中不执行,但是在微信和支付宝打开是可以弹出的。查证了一个原因是WKWebview不会执行JS的alert代码,但是前端写的自定义弹窗我们这边是能显示。

!!!说,是不是苹果也觉得H5的默认弹窗是在是太low了!!

  • 我们遵循WKUIDelegate协议,实现下面三种样式的弹窗。
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}


/**
 <#Description#>

 @param webView <#webView description#>
 @param message <#message description#>
 @param frame <#frame description#>
 @param completionHandler <#completionHandler description#>
 */
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    //    DLOG(@"msg = %@ frmae = %@",message,frame);
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}


/**
 <#Description#>

 @param webView <#webView description#>
 @param prompt <#prompt description#>
 @param defaultText <#defaultText description#>
 @param frame <#frame description#>
 @param completionHandler <#completionHandler description#>
 */
- (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];
}

你可能感兴趣的:(iOS WKWebview和JS的一次交互)