• 问题

    感觉到uni-app框架有pit,公司强推该框架的小哥识趣的闭嘴,思考到全盘替换周期跟老本挺大,基于uni-app能打包成H5,采纳webview+js的原生形式集成

    根本构造:原生壳 + webview[iOS & Android] + js

  • 计划

    确定根底框架后,次要的问题就是web与js的交互,限于技术能力,只谈iOS方向

    首先,UIWebView用的不多,曾经iOS14+了,用UIWebView不被diss的话,大略你们团队也就那样了,其对应的交互框架为JavaScriptCore。Pass不讲

    再次,可拦挡跳转的url并解析,以约定好的key/value,调用原生办法,该交互方式满足简略的性能需要,仅限web唤起iOS调用,看状况

    接着,WKWebview中,JS调用native办法,通过WKScriptMessageHandler协定,外围是:window.webkit.messageHandlers.办法名.postMessage(参数),native调用JS就简略很多,外围是:[weblview evaluateJavaScript:xxx completionHandler: ^(id object, NSError * _Nullable error) { }];

    如上:如果有异步操作,怎么办?如果实现block岂不更好?

    最初:WebViewJavascriptBridge,来吧,你值得领有

  • 分析
    1.js调用native办法

    - html中web中按钮点击,- bridge调用callHandler, - 调用_doSend()- 赋值messagingIframe.src = xxx://__wvjb_queue_message__- native的webview执行代理办法decidePolicyForNavigationAction- 获取url, native执行WKFlushMessageQueue- webview执行evaluateJavaScript, 调用js的_fetchQueue(),把_doSend()调用时写入sendMessageQueue中的值取出来,即获取js传递过去的参数- native办法flushMessageQueue,解决js传递过去的参数,封装在block中- 留神:js传递过去的参数,有可能还有function回调的存在,function是解决js调用native之后,native的执行后果回调给js,造成一个js->native->js的过程。

    2.native调用js办法

    - native中的bridge调用callHandler办法- BridgeBase中调用-(void)sendData:(id)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName- BridgeBase中调用_queueMessage- 这里有个判断,当startupMessageQueue!=nil时,音讯放在数组中,当=nil时,间接调用_dispatchMessage- native中startupMessageQueue在执行injectJavascriptFile办法后会被设置为nil- injectJavascriptFile追溯可知当decidePolicyForNavigationAction中判断url的host=__bridge_loaded__时调用,- 而在js中设置的bridge时设置的WVJBIframe.src = 'https://__bridge_loaded__', 到此应该不必多问,分析_dispatchMessage- _dispatchMessage中执行_evaluateJavascript, 执行的js中的办法_handleMessageFromObjC(xxx)- Bridge_JS中查问_dispatchMessageFromObjC, 接着调用_dispatchMessageFromObjC- 此时设置回调A-block, 外面的数据是js中的执行后果,js在开始的时候注册registerHandler,是key/block,此时通过key能够找到对应的B-block,将message传递过去的data跟设置的A-block当做对应的key/block的B-block的参数,间接执行该B-block即可。可能在js的registerHandler中获取到native传递过去的参数,同时也可能通过A-block将js的执行后果回调给native

    3.总结

    初始化时给web注入不少料,外围是 1.拦挡url, 2.回调实现基于初始化注入字典便于key/value形式治理block 3.evaluateJavaScript执行js

    4.延长

    如上的做法适宜UIWebView&WKWebView。实际上如果只针对WKWebView的话,可在_doSend办法中间接调用window.webkit.messageHandlers.xxx.postMessage(null),而非设置src的形式。可参照WKWebViewJavascriptBridge
  • Game Over。