iOS与Web交互遇到的问题

1、Web APP 在开发过程中不可避免的涉及到输入,所以今天来解决键盘弹起遮挡的问题,主要从iOS原生的方面来解决;

// 添加键盘监听
- (void)addNotification {

    // 键盘即将出现
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    // 键盘出现
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    // 键盘即将消失
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    // 键盘消失
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
   
    [self.webView evaluateJavaScript:@"document.body.scrollTop" completionHandler:nil];
}
- (void)keyboardDidShow:(NSNotification *)notification {
    
    [self.webView evaluateJavaScript:@"document.body.scrollTop" completionHandler:nil];
}
- (void)keyboardWillHide:(NSNotification *)notification {
    
    [self.webView evaluateJavaScript:@"document.body.scrollTop = 0;" completionHandler:nil];
}
- (void)keyboardDidHide:(NSNotification *)notification {
    
    [self.webView evaluateJavaScript:@"document.body.scrollTop" completionHandler:nil];
}

2、数据交互是一个复杂的过程,所以需要一套规则来约束原生和Web APP;
(Web APP采用Vue框架)

// 原生调用JS方法
// JS写法
1.方法统一添加在main.js的methods中
2.把获取的参数赋值给data中的变量
3.页面获取通过this.$root.variable获取,variable为具体变量名
// 原生写法
[self.webView evaluateJavaScript:@“_vue.fn(参数1[,参数2…])” completionHandler:nil];
1._vue 固定写法
2.fn JS定义的具体方法名,参数可以多个
// JS调用原生方法
// JS写法
window.webkit.messageHandlers.mutual.postMessage(JSON);
1.mutual 为iOS定义的方法名,一般用一个就可以,通过参数type去区分功能模块
2.JSON 参数{type:xxx,data:xxx}为JSON格式对象
3.type 类型,不同的值对应不同的功能模块
4.data 传递的具体参数
// 原生写法
1.webview初始化的时候配置,方法名可以多个,一般用一个就可以
WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
[configuration.userContentController addScriptMessageHandler:self name:@"mutual"];
self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
2.实现WKScriptMessageHandler协议
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    
    if ([message.name isEqualToString:@"mutual"]) {
        // message.name定义好的方法名
        // message.body包含参数
        // 进行原生的操作,比如上传图片之类
    }
}

3、清理web app缓存数据

// 仅清理 localstorage 缓存的数据
[self.webView evaluateJavaScript:@"localStorage.clear()" completionHandler:^(id _Nullable obj, NSError * _Nullable error) {}];
// 清理 web app 对应类型的缓存,适用于iOS9及以后
NSArray *types = @[// 磁盘缓存
                   WKWebsiteDataTypeDiskCache,
                   // 内存中的缓存
                   WKWebsiteDataTypeMemoryCache,
                   // HTML离线Web应用程序缓存
                   WKWebsiteDataTypeOfflineWebApplicationCache,
                   // HTML本地存储
                   WKWebsiteDataTypeLocalStorage,
                   // Cookies 缓存
                   WKWebsiteDataTypeCookies,
                   // HTML会话存储
                   WKWebsiteDataTypeSessionStorage,
                   // IndexedDB数据库
                   WKWebsiteDataTypeIndexedDBDatabases,
                   // WebSQL数据库
                   WKWebsiteDataTypeWebSQLDatabases
                   ];
NSSet *websiteDataTypes = [NSSet setWithArray:types];
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
        NSLog(@"清理成功");
}];
// 清理 web app 所有类型的缓存,适用于iOS9及以后
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate dateWithTimeIntervalSince1970:0] completionHandler:^{
        NSLog(@"清理成功");
}];

4、
4.1、由于 iOS IDE 对 console.log() 支持不是很友好;
现目前有一个折中的调试办法,js中调用alert(param),iOS会弹出模态窗;
其中param为字符串类型参数,如果param是json对象,需要转化成字符串alert(JSON.stringify(param));
4.2、iOS中注入如下代码:

// alert
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    
    UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"提示" message:message ? message : @"" preferredStyle:UIAlertControllerStyleAlert];
    [vc addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:vc animated:YES completion:nil];
}
// confirm
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
    
    UIAlertController *vc = [UIAlertController alertControllerWithTitle:@"提示" message:message ? message : @"" preferredStyle:UIAlertControllerStyleAlert];
    [vc addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [vc addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    [self presentViewController:vc animated:YES completion:nil];
}
// prompt
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler {
    
    UIAlertController *vc = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
    [vc addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.text = defaultText;
    }];
    [vc addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(vc.textFields[0].text ? vc.textFields[0].text : @"");
    }])];
    [self presentViewController:vc animated:YES completion:nil];
}

猜你喜欢

转载自blog.csdn.net/qq_16804091/article/details/86133838