美文网首页
iOS下实现原生代码ObjC与JS交互的方式

iOS下实现原生代码ObjC与JS交互的方式

作者: Mr狮子先生 | 来源:发表于2018-03-09 11:20 被阅读0次

    分两种情况,一是使用第三方库,二是使用iOS自带的方式。

    1 使用第三方开源库

    第三方开源库,也是基于iOS自带的方式,进行了封装,免去了一系列的初始化处理、错误处理等。

    主流库是WebViewJavascriptBridge,下载地址 Githubhttps://github.com/marcuswestin/WebViewJavascriptBridge

    2 使用iOS自带的组件

    这里又分两种情况,区别在于是使用UIWebView还是WKWebView。

    2.1 UIWebView和WKWebView共用的组件

    2.1.1 注册接口方法

    首先,定义一套协议 WebExport,需要继承 JSExport,在里面声明要注册的接口。
    PS:JSExport协议的继承,是UIWebView下特有的方式,为了共用,WKWebView也实现此套协议。

    关于参数的问题,个人建议,统一传一个参数即可,方便日后的扩展。这个参数优先使用JSON对象,或者JSON字符串。

    然后,实现继承自UIViewController的一个基类,在这个基类上实现这套协议。要使用交互的UIViewController,只需要继承这个基类即可,不需要额外添加实现代码。

    @protocol WebExport <JSExport>
    
    /**
     登录
     */
    - (void)login;
    
    /**
     使用Safari打开url
    
     @param jsonObject url
     */
    - (void)openSystemBrowser:(id)jsonObject;
    
    @end
    
    

    2.2 UIWebView和WKWebView分别注入对象

    注入对象,则要区分UIWebView和WKWebView。

    2.2.1 UIWebView注入桥接对象

    先声明属性
    @property(nonatomic, strong) JSContext *jsContext;

    然后注入供H5调用的对象

    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        self.jsContext[@"appInterface"] = self;
        self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
            DLog(@"JS调用APP接口异常:%@", exceptionValue);
        };
    }
    

    其中,appInterface是H5要引用的对象,可随意命名。

    注入的时机,个人认为是在H5页面加载完成之后进行,即在webViewDidFinishLoad回调方法里进行。
    但需要注意,向H5公开的接口都是在H5加载完之后,才能进行调用。

    H5的调用方法如下:

    window.appInterface.login();
    window.appInterface.openSystemBrowser("http://www.baidu.com");
    

    H5调用接口后,ObjC会自动调用基类里的接口实现,不需要做额外处理。

    2.2.2 WKWebView注入桥接对象

    WKWebView下,不需要手动注入桥接对象,WKWebView已自动注入了对象,这个对象H5可以通过 window.webkit.messageHandlers 获得。

    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"login"];
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"openSystemBrowser"];
    
    

    H5的调用方法如下:

    window.webkit.messageHandlers.login.postMessage("")
    window.webkit.messageHandlers.openSystemBrowser.postMessage("http://www.baidu.com")
    

    H5调用接口后,ObjC会执行如下代理方法

    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
    {
        NSString *interfaceName = message.name;//接口名称
        id interfaceParams = message.body;//接口参数,JSON格式
        
        // 响应接口
        if ([interfaceName isEqualToString:@"login"]) {
            [super login];
        } else if ([interfaceName isEqualToString:@"openSystemBrowser"]) {
            [super openSystemBrowser:interfaceParams];
        }
    }
    

    PS:像login接口,如果是没有参数的情况下,需要传入一个空的对象,否则ObjC的代理方法会不执行。

    3 总结

    第三方库,在iOS端使用比较方便,错误处理也比较好。但是,对于H5来说,需要提前注入的JS代码有点多,不如使用iOS自带的方式简洁。

    而使用iOS自带的组件实现,iOS端需要做一些额外处理。但H5不需要注入额外JS代码,只需要调用接口,即可实现与ObjC的交互,调用代码相对比较简洁,易用。

    相关文章

      网友评论

          本文标题:iOS下实现原生代码ObjC与JS交互的方式

          本文链接:https://www.haomeiwen.com/subject/dpjpfftx.html