OC Hybrid 开发数据双向流向

OC之WebView 和原生 App 交互。

最近参加了很多面试,都问到了关于 Hybrid 开发。
我基本可以把 WebView 和 OC 之间的双向交互的原理说明白。
并且可以自己手动的写 js 代码完成双端的交互。
但由于,之前没有用过类似的混合开发的框架,被面试官给一票否决了。
想想挺郁闷的。

我所理解的 Hybrid 开发。

说实在话,为什么要用 Hybrid 开发模式?

  1. 可以动态的更新界面,比如活动等。App 端则基本不用做修改。
  2. HTML5可以写出很绚丽的界面。而使用 OC 原生的要写出这么绚丽的界面是一件很费时费力的过程。

说白了,在界面表现灵动性的方面,HTML5比原生的 OC 强大多了。代价也更小。这种情况对于 OC 一个纯开发 App 界面的语言来说,不知道有什么想法。


从 WebView 到 OC 的数据流向。

WebView 本质上就是一个内置的浏览器。
浏览器的执行过程简单来看:

  1. 请求 URL
  2. 服务器返回 HTML 数据
  3. 浏览器解析渲染 HTML + CSS
  4. 浏览器执行 JS。

那么 WebView 如何跟原生的 OC 发生交互呢?
原理就在:当 WebView 这个浏览器发送 URL 请求的时候,在 OC 级别我们可以使用 WebView 的代理方法捕获到这个信号。
**- (BOOL)webView:(UIWebView )webView shouldStartLoadWithRequest:(NSURLRequest )request navigationType:(UIWebViewNavigationType)navigationType

这个代理方法返回值是 BOOL 类型。
返回 YES 表示,请求继续往下走,该干嘛干嘛。
返回 NO 表示,截获了这个请求,请不要往下走了。也就是说,URL 请求,压根就没有发布出去。

对于 WebView 到 App 之间的交互,就是通过这个代理方法来执行的。

简单实现:

  1. 在 HTML 中,镶嵌一个 A 标签,给 href 属性设置一个目的是不跳转到百度,而是被截获的协议链接。
从浏览器到 OC

当点击 WebView 中这个 A 标签的时候,会发送 URL 请求。于是进进入到上面的那个代理方法。

在代理方法中,过滤需要截获的请求。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if ([request.URL.absoluteString containsString:@"gqs"]) {
        NSLog(@"%@",@"捕获到了自定义协议");
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"这是标题" message:@"浏览器到 OC 的通道打通了!" preferredStyle:UIAlertControllerStyleAlert];
        
        UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"知道了!" style:UIAlertActionStyleCancel handler:nil];
        
        [alertController addAction:confirmAction];
        
        [self presentViewController:alertController animated:YES completion:nil];
        
        return NO;

    }
    // 正常的URL链接就让它们继续去执行。
    return YES;
}

到此为止,WebView -> App 的流向就走通了。
原理一句话:App 通过代理方法,截获 WebView 的请求,根据请求筛选,做一些响应的事情。


从 App 到 WebView 的走向。

说白了,就是一个方法。
webView stringByEvaluatingJavaScriptFromString:
这儿方法,就是在当前的 HTML 中,插入一段 js 代码。
你插入的是什么 js 代码,WebView 就执行什么代码。

一个简单的业务场景:

用户需要从联系人列表中,选中一个联系人号码(App 端)。然后把这个号码赋值给 WebView 的某个 HTML 文本框里。

也就是数据走向 : App -> WebView

做法如下:

  1. 在 HTML 中,实现定义一个用户显示用户号码的 js 函数。


     标题


从浏览器到 OC
用户的电话号码:
  1. 在 App 中,选择了用户手机号码之后,调用 stringByEvaluatingJavaScriptFromString 将手机号码传递到 WebView 的 Input id = userPhone 这个文本框上。
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty {
    // NSArray*>
    /**
     ] (
     "!$_, value=>",
     "!$_, value=>"
     )
     */
    NSString *phoneNumber = [contactProperty.value stringValue];
    NSLog(@"%@",phoneNumber); // 拿到用户的电话号码
    
    
    [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"showUserPhoneNum(\"%@\")",phoneNumber]];
}

Hybrid 从 App-> 浏览器.gif

从 App -> WebView 原理:一句话,通过stringByEvaluatingJavaScriptFromString调用 HTML 中已经写好的,或者自己写的 js 代码,来实现App -> WebView 的数据走向。

DEMO 地址

你可能感兴趣的:(OC Hybrid 开发数据双向流向)