欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

IOS 原生与HTML交互

程序员文章站 2022-05-09 20:34:09
跟原生开发相比,H5的开发相对来一个成熟的框架和团队来讲在开发速度和开发效率上有着比原生很大的优势,至少不用等待审核。那么问题来了,H5与本地原生代码势必要有交互的,比如本地上传一...

跟原生开发相比,H5的开发相对来一个成熟的框架和团队来讲在开发速度和开发效率上有着比原生很大的优势,至少不用等待审核。那么问题来了,H5与本地原生代码势必要有交互的,比如本地上传一些信息,H5打开本地的页面,打开本地进行微信等第三方分享等,今天就简单讲一下iOS中本地UIWebView,WKWebView与H5的交互。

DEMO地址:点击下载

UIWebView的交互

stringByEvaluatingJavaScriptFromString的使用

UIWebView在2.0时代就有的类,一直到现在(目前9.x)都可以使用的WEB容器,它的方法很简单,在iOS7.0之前JS交互的方法只有一个stringByEvaluatingJavaScriptFromString:

- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

使用stringByEvaluatingJavaScriptFromString方法,需要等UIWebView中的页面加载完成之后去调用.

以下是简单的使用场景:

1、获取当前页面的url。

-(void)webViewDidFinishLoad:(UIWebView*)webView{ 
    NSString*currentURL=[webViewstringByEvaluatingJavaScriptFromString:@"document.location.href"]; 
}

2、获取页面title:

-(void)webViewDidFinishLoad:(UIWebView*)webView{ 
        NSString*currentURL=[webViewstringByEvaluatingJavaScriptFromString:@"document.location.href"]; 
NSString*title=[webviewstringByEvaluatingJavaScriptFromString:@"document.title"]; 
}

3、修改界面元素的值。

NSString*js_result=[webViewstringByEvaluatingJavaScriptFromString:@"document.getElementsByName('q')[0].value='iOS';"];

4、表单提交:

NSString*js_result2=[webViewstringByEvaluatingJavaScriptFromString:@"document.forms[0].submit();"];

这样就实现了在google搜索关键字:“iOS”的功能。
5、插入js代码
上面的功能我们可以封装到一个js函数中,将这个函数插入到页面上执行,代码如下:

jsparamfunc="" jsvalue="" mark="" message="" message:msg="" model="[[NLJsObjCModel" model.jscontext="self.jsContext;" model.webview="self.webView;" msg="" navigationaction="" navigationresponse="" nljsobjcmodel="" nsdictionary="" nsobject="" nsstring="" objective-c="" onclick="OCModel.showAlertMsg('js title', 'js message')" param="" params="" pragma="" pre="" property="" protocol="" script="[[WKUserScript" script.text="\"functionmyFunction(){"" script.type="text/javascript" self.jscontext="[webView" self.jscontext.exceptionhandler="^(JSContext" span="" style="color: red; font-size: 50px;" target="_blank" test="" title="\" to="" type="button" uialertview="" uiwebview="" uiwebviewdelegate="" use="" value="Call ObjC system alert" var="" varfield="document.getElementsByName('q')[0];"" varscript="document.createElement('script');"" void="" was="" webview="" wknavigation="" wknavigationaction="" wknavigationdelegate="" wknavigationresponse="" wkuserscript="" wkwebview="" wkwebviewconfiguration="">"baseURL:nil];
[self.view addSubview:_webView];

五、webView 执行JS代码
用户调用用JS写过的代码,一般指服务端开发的:

//javaScriptString是JS方法名,completionHandler是异步回调block
[self.webView evaluateJavaScript:javaScriptString completionHandler:completionHandler];

六、JS调用App注册过的方法
在WKWebView里面注册供JS调用的方法,是通过WKUserContentController类下面的方法:

- (void)addScriptMessageHandler:(id )scriptMessageHandler name:(NSString *)name;

scriptMessageHandler是代理回调,JS调用name方法后,OC会调用scriptMessageHandler指定的对象。

JS在调用OC注册方法的时候要用下面的方式:

window.webkit.messageHandlers..postMessage()

注意,name(方法名)是放在中间的,在这里个人理解该name可以理解为一个标识,该标识将OC本地的实例对象绑定到JS中,将messageBody只能是一个对象,如果要传多个值,需要封装成数组,或者字典。整个示例如下:

//OC注册供JS调用的方法
[[_webView configuration].userContentController addScriptMessageHandler:self name:@"app"];

//OC在JS调用方法做的处理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
    NSLog(@"JS 调用了 %@ 方法,传回参数 %@",message.name,message.body);
}

//JS调用
    window.webkit.messageHandlers.app.postMessage(null);

最后:

简单做一个总结,在iOS7以前我们只能使用UIWebView,所以在js交互中只能通过stringByEvaluatingJavaScriptFromString进行本地调用H5,而H5端调用本地多采用URLSchemes方式。

iOS7之后使用UIWebView则可以使用JavaScriptCore框架,通过JSContext进行JS交互。
iOS8之后可以使用WKWebView本身的框架,毕竟WKWebView本身已经优化很多,并且提供了更多的方法和协议,不过注意一点的是在WKWebView中鉴于一些线程和进程的问题是无法获取JSContext的。