? ? ? ? 前段時(shí)間將項(xiàng)目中的Cordova做了一下升級(jí)舞蔽,由于項(xiàng)目本身比較大荣病,涉及到的Native和H5交互的模塊又非常多,所以整個(gè)項(xiàng)目改造下來(lái)還是發(fā)了點(diǎn)時(shí)間的渗柿,廢話不多說(shuō)个盆,直接進(jìn)入主題,整個(gè)項(xiàng)目改造大致可以分為下面幾個(gè)階段:
1.集成最新版Cordova,也就是4.0.0版本(這個(gè)版本在設(shè)計(jì)架構(gòu)上完全區(qū)別于老版Cordova)
2.研究新Cordova框架(類似使用了構(gòu)建者模式+運(yùn)行時(shí)機(jī)制朵栖,下面細(xì)聊)
3.涉及到Cordova的地方整改颊亮,模塊的整合,重構(gòu)
首先陨溅,如何集成Cordova 4.4.0:
? ? ? ?從Adobe收購(gòu)了Nitobi Software和它的PhoneGap產(chǎn)品终惑,然后宣布這個(gè)移動(dòng)開(kāi)發(fā)框架將會(huì)繼續(xù)開(kāi)源,并把它提交到Apache Incubator门扇,以便完全接受ASF的管治雹有,導(dǎo)致項(xiàng)目無(wú)法直接通過(guò)Cocoapods集成,唯一的辦法就是通過(guò)Shell創(chuàng)建一個(gè)Cordova項(xiàng)目悯嗓,然后將整個(gè)項(xiàng)目中的有用資源取出來(lái)件舵,丟進(jìn)自己的工程里面,這樣脯厨,一些配置就得自己手動(dòng)完成(配置也很簡(jiǎn)單铅祸,繼續(xù)看)
? ? ? ?扯了半天,終于進(jìn)入主題了,集成Cordova是通過(guò)命令行來(lái)做的临梗,但是必須先安裝Cordova命令工具涡扼,而這個(gè)命令工具是在npm命令工具下的,這就要求先安裝node.js(www.runoob.com/nodejs/nodejs-install-setup.html),里面包含了安裝npm工具的命令盟庞,這不是重點(diǎn)吃沪,安裝的過(guò)程自己看看,也很簡(jiǎn)單什猖。
現(xiàn)在假設(shè)已經(jīng)安裝好了npm工具票彪,直接執(zhí)行以下幾個(gè)命令創(chuàng)建一個(gè)iOS的Cordova項(xiàng)目:
$ mkdir Cordova ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #新建文件夾?
$ cd Cordova
$ cordova create hello com.example.hello HelloWorld ?#創(chuàng)建一個(gè)cordova項(xiàng)目
$ cd hello
$ cordova platform add ios ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#指定生成iOS平臺(tái)的代碼項(xiàng)目
$ cordova plugin add cordova-plugin-wkwebview-engine #添加WK插件
這樣就創(chuàng)建了一個(gè)新版Cordova項(xiàng)目,接下來(lái)就將需要的文件拖到自己的項(xiàng)目里面不狮,見(jiàn)圖:
拖完后降铸,加入到編譯環(huán)境中,此時(shí)項(xiàng)目已經(jīng)包含了Cordova了摇零,但是這個(gè)還不夠推掸,因?yàn)镃ordova本身就是H5交互Native的橋梁,Native支持了驻仅,還得H5也支持谅畅,這里需要注意的地方是新版的cordova.js能夠支持舊版的cordova,但是舊版的cordova.js絕不支持新版(向下兼容了)噪服,所以自己項(xiàng)目中已經(jīng)集成了舊Cordova的毡泻,必須要求H5同胞們也得升級(jí)一下,那么你就必須給他們提供一下新版的cordova.js粘优,進(jìn)入“www文件夾”牙捉,找找就會(huì)看到有三個(gè)js文件,不要想了敬飒,直接發(fā)給H5的同事,讓他們快點(diǎn)替換舊版cordova.js芬位,修改一下處理邏輯无拗,H5那邊處理起來(lái)很簡(jiǎn)單,別讓他們忽悠你說(shuō)搞不定或者需要幾天時(shí)間昧碉。
再假設(shè)H5那邊已經(jīng)把新版cordova集成完畢并且沒(méi)bug了英染,現(xiàn)在就到了iOS程序員裝逼的時(shí)候了,不多說(shuō)被饿,直接上干貨四康,一起看看cordova 4.4.0在架構(gòu)設(shè)計(jì)上,有哪些值得我們研究的地方:
首先看Cordova框架的整體類結(jié)構(gòu)狭握,類有很多闪金,但是真正需要我們?nèi)リP(guān)心的沒(méi)幾個(gè),首先就是CDVViewController這個(gè)類,這個(gè)類和舊版的一樣哎垦,但是仔細(xì)看這個(gè)類就會(huì)發(fā)現(xiàn)它的屬性webView由UIWebView變成了UIView囱嫩,這個(gè)和它需要支持WKWebView有關(guān),先說(shuō)說(shuō)思想(高手談思想漏设,菜鳥(niǎo)談代碼墨闲,我們不做菜鳥(niǎo)),設(shè)計(jì)思想:
? ? ? ?通過(guò)一個(gè)協(xié)議CDVWebViewEngineProtocol來(lái)管理CDVUIWebViewEngineer和CDVWKWebViewEngineer郑口,再通過(guò)CDVUIWebViewEngineer管理UIWebView鸳碧,CDVWKWebViewEngineer管理WKWebView,說(shuō)到底犬性,就是簡(jiǎn)單的面向協(xié)議編程瞻离,使用這個(gè)編程思想是必然的,因?yàn)閃KWebView和UIWebView有太多共性仔夺,只要抽象出共性琐脏,定義好協(xié)議接口,沒(méi)啥搞不定的缸兔。
再看看這個(gè)類的代碼日裙,啥也不用想,直接來(lái)這個(gè)方法- (UIView*)newCordovaViewWithFrame:(CGRect)bounds,
仔細(xì)看會(huì)發(fā)現(xiàn)惰蜜,它是先從config.xml配置里面去取CordovaDefaultWebViewEngine這個(gè)key下的值CDVWKWebViewEngineer昂拂,如果配置里面設(shè)置了這個(gè)key值,就說(shuō)明需要使用CDVWKWebViewEngnieer抛猖,即使如此格侯,它還要判斷一下是不是真的支持使用WK,這里提一個(gè)細(xì)節(jié):
WKWebView在iOS8.0時(shí)不能通過(guò)LoadRequest加載本地資源财著,這個(gè)bug已經(jīng)在iOS9.0解決了联四,可以看到上面已經(jīng)做了這個(gè)判斷是否繼續(xù)使用WKWebView。
這個(gè)類有一個(gè)屬性:
? ? ? ? ?解決方案:先不用知道wenViewEngineer到底是屬于CDVWKWebViewEngineer還是CDVUIWebViewEngnieer撑教,但是我只知道它一定遵循CDVWebViewEngineProtocol這個(gè)協(xié)議朝墩,具體wenViewEngineer這個(gè)屬性是哪個(gè),是根據(jù)(UIView*)newCordovaViewWithFrame:(CGRect)bounds,這個(gè)方法系統(tǒng)自己推理出來(lái)的伟姐,所以我們拿到self.webEngineer后直接調(diào)用協(xié)議里面的方法收苏,就可以加載網(wǎng)頁(yè)了,如果覺(jué)得方法不夠用愤兵,可以在CDVWebViewEngineProtocol協(xié)議里面添加鹿霸,但添加的協(xié)議方法的實(shí)現(xiàn)必須在CDVWKWebViewEngineer和CDVUIWebViewEngnieer兩個(gè)類中都去實(shí)現(xiàn),不然必出問(wèn)題秆乳。
再看協(xié)議CDVWebViewEngineProtocol懦鼠,協(xié)議里面有屬性engineWebView,其實(shí)就是當(dāng)前ViewController的webView(具體里面的屬性指針傳遞就不細(xì)說(shuō),就直接這么理解)葛闷,協(xié)議方法用于給CDVWKWebViewEngineer和CDVUIWebViewEngnieer兩個(gè)類使用憋槐;
這樣,就簡(jiǎn)單但又直接的了解的cordova淑趾,其實(shí)知道了這些對(duì)于使用cordova做項(xiàng)目足矣阳仔。
最后,如何定義方法扣泊,如何定義JS插件呢近范?
很簡(jiǎn)單,在config.xml里面添加:
提供給H5同胞你的插件名和方法,讓H5那邊調(diào)一下延蟹,不出意外评矩,Native這邊必然就可以響應(yīng)了,至于我的項(xiàng)目的整改阱飘,其實(shí)就包含WKWebView的使用和NSURLProtocol做離線緩存了斥杜,這里我先列舉一下遇到的坑:
1.WKWebView的Cookie不會(huì)從NSHTTPCookieStorage里面去取,但會(huì)往里面存,所以所有涉及到登錄的H5頁(yè)面沒(méi)法加載出來(lái)沥匈,Cookie的解決方案接下來(lái)會(huì)說(shuō)明蔗喂;
2.WKWebView使用NSURLProtocol做離線緩存時(shí),請(qǐng)求沒(méi)法攔截到高帖,即使攔截到缰儿,請(qǐng)求體也被蘋果干掉了,如何解決散址,有幾個(gè)方案乖阵,接下來(lái)會(huì)說(shuō)明;
3.WKWebView有自己獨(dú)立的進(jìn)程预麸,分配的資源很有限瞪浸,開(kāi)啟的WK多了,返回時(shí)會(huì)看看白屏吏祸,網(wǎng)上的解決方案貌似沒(méi)啥用默终,有一個(gè)解決方案,接下來(lái)會(huì)說(shuō)明犁罩;
4.WK自身設(shè)計(jì)上存在一些特殊的地方,接下來(lái)會(huì)分享出來(lái)两疚。