本文可能只適合新手⊥╇纾基于Cordova 4.0+拄显,講的比較膚淺,主要是記錄一下這段時間對Cordova的學習案站。文筆比較不好躬审,如有錯誤歡迎指正,歡迎探討。
總結在前:
OC調用js
一承边、webview 調用 stringByEvaluatingJavaScriptFromString 方法
注:同步方法遭殉,可能會阻塞UI
二、JavaScriptCore做js交互
JSContext *context = [self.webview valueForKeyPath:@“documentView.webView.mainFrame.javaScriptContext"]
[context evaluateScript:XXXX];
js調用OC
一博助、利用js打開iFrame方式發(fā)假請求险污,webview進行攔截
(默認方式)iframe的方法:添加iframe到html元素中,并設置iframe的src為指定gap://ready(相當于發(fā)假的URL請求)富岳,觸發(fā)Native側UIWebview:shouldStartLoadWithRequest的方法蛔糯。攔截住此次請求后再調用JS代碼向JS側發(fā)起取參數(shù)的操作,取回后Native再進行處理城瞎。
注:為什么不用document.location: 如果我們連續(xù) 2 個 js 調 native渤闷,連續(xù) 2 次改 document.location 的話疾瓮,在 native 的 delegate 方法中脖镀,只能截獲后面那次請求,前一次請求由于很快被替換掉狼电,所以被忽略掉了
二蜒灰、JavaScriptCore: 在webViewDidFinishLoad完成載入后,對上下文進行設置
JSContext *context = [self.webView valueForKeyPath:”documentView.webView.mainFrame.javaScriptContext"]
context[@"share”] = ^(){….} //設置share 方法
一肩碟、簡單講下什么是Cordova
Apache Cordova是一個開源的移動開發(fā)框架强窖。允許你用標準的web技術-HTML5,CSS3和JavaScript做跨平臺開發(fā)。 應用在每個平臺的具體執(zhí)行被封裝了起來削祈,并依靠符合標準的API綁定去訪問每個設備的功能翅溺,比如說:傳感器、數(shù)據(jù)髓抑、網絡狀態(tài)等咙崎。(摘自官網)
同樣的移動開發(fā)框架,還有react-native, weex等等吨拍。這里不做比較和討論了褪猛。
二、講下這篇文章的背景
我們今天要講的羹饰,不是如何利用web技術去開發(fā)app伊滋。
而是底層最核心的代碼,native和js的交互队秩。
現(xiàn)如今笑旺,Hybrid App非常盛行。我開發(fā)的工程也是Hybrid App馍资。注重用戶體驗燥撞,且變動較少的頁面,使用Native開發(fā)。需要經常迭代的物舒,安卓iOS通用的頁面色洞,就使用H5開發(fā)。而Native和H5的交互冠胯,我們使用的是Cordova工程的部分代碼火诸,也就是比較核心的代碼,諸如CDVViewContoller等荠察。
舉個例子:某公司的考勤頁面置蜀,是H5頁面。在自己公司的App打開這個頁面悉盆,如果要請假時需要填寫backup的同事盯荤,此時選擇同事是調用App Native本地存儲的通訊錄數(shù)據(jù)。這里就涉及到了JS與Native的相互調用和數(shù)據(jù)的傳遞焕盟。
三秋秤、整體的流程
1、利用CDVViewController(或是擴展的類)脚翘,去加載某個H5鏈接灼卢。
2、該H5頁面上某個按鈕的點擊事件需要請求Native插件来农。
(由于我們項目對CDVViewController又進行了一層封裝鞋真,所以插件的加載,JS的注入沃于,不需要對Cordova核心代碼進行改動涩咖,如config.xml)
(--流程基本是通過斷點打出來看的--)
四、具體是如何交互的繁莹,底層機制又是什么檩互?
(JavaScriptCore也是交互的一種方式,但不在本章里討論 )
1蒋困、JS如何調用Native盾似?
(默認方式)iframe的方法:添加iframe到html元素中,并設置iframe的src為指定gap://ready(相當于發(fā)假的URL請求)雪标,觸發(fā)Native側UIWebview:shouldStartLoadWithRequest的方法零院。攔截住此次請求后再調用JS代碼向JS側發(fā)起取參數(shù)的操作,取回后Native再進行處理村刨。
xmlHttpRequest的方法:
execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true);
execXhr.setRequestHeader('cmds', iOSExec.nativeFetchMessages());
Native側UIWebview:shouldStartLoadWithRequest的方法告抄,判定為/!gap_exec來攔截,并從頭部取得插件的具體參數(shù)
保留該方式的原因:
// XHR mode does not work on iOS 4.2, so default to IFRAME_NAV for such devices.
// XHR mode’s main advantage is working around a bug in -webkit-scroll, which
// doesn’t exist in 4.X devices anyways
(iOS5.x版本因為 -webkit-scroll的IFRAME有BUG嵌牺,則推薦使用)
因為我們項目現(xiàn)在都是支持iOS 7+打洼,所以采用的都是iframe方式龄糊。
2、Native如何執(zhí)行JS募疮?
UIWebView 有一個這樣的方法 stringByEvaluatingJavaScriptFromString
3炫惩、底層機制是怎么樣的?
底層機制主要是結合1阿浓、2兩種方式他嚷,形成一種一來一往的交互(可以看上述流程圖)。
與普通調用1芭毙、2兩種方法相比較筋蓖,最核心的點在于:
1、Cordova在JS側與Native側均使用了隊列來保存互相調用的請求退敦,并生成了callbackid能及時找到與此次請求相關的上下文參數(shù)等等粘咖。
2、CDVPlugin侈百、CommandDelegate等可以很好的開發(fā)插件瓮下。注入插件和js的話看個人,可以在繼承CDVViewController里面去做设哗。
五唱捣、具體的插件開發(fā)是什么樣的
1两蟀、生成cfg文件(主要是對插件的描述)
2网梢、生成.js文件(主要是供H5開發(fā)人員可以直接調用)
3、繼承CDVPlugin的類去寫插件類赂毯,有模板可仿照战虏。
具體可看官網 http://cordova.axuer.com/docs/zh-cn/latest/guide/platforms/ios/plugin.html
——————————————————————
參考文章:http://www.reibang.com/p/e74bc7abac8d (是講述js與OC調用的,一個系列的党涕,還不錯)
http://blog.csdn.net/u011417590/article/details/50895734(是講述Cordova核心類CDVViewController源碼的)
http://blog.csdn.net/Linux7985/article/details/53022371 (相對清晰一點烦感,我的結構也是模仿該篇的,可惜版本貌似比較老了)
http://blog.csdn.net/lq83623/article/details/42478223 (講的也比較好膛堤,但下面的結構圖大部分看不懂)
http://www.reibang.com/p/21477a20707a (主要是插件開發(fā)相關)