1. 程式人生 > >Ali-Wax使用和原始碼解析系列-Wax的整合和除錯環境搭建

Ali-Wax使用和原始碼解析系列-Wax的整合和除錯環境搭建

那些多餘的話

在ios平臺的基礎框架中,程式碼的直接動態部署一直是一個無法解決的問題,所以我們只能退而求其次,通過建立指令碼語言和OC的bridge來實現動態更新的目標。在這個方向上,wax-lua框架是第一個解決方案,但是隨著wax-lua作者的放棄維護,wax框架逐漸被降級為做補丁修復的工具。之後隨著objc語言的完善和SDK中JavaScriptCore(webkit)framework api的開放,另外一種指令碼語言js以一種更為被蘋果認可的姿態進入了這個方向,先有國外FaceBook釋出的ReactNative框架,讓更多的前端開發者可以通過js語言完成可以毗鄰native效果的app,後有國內騰訊的bang開源JSPatch,專注於ios平臺Patch修復。

本人最近一直在維護公司內部的的wax框架,也一直在探索ios熱更新方向上的新技術。先是wax框架的相容64位維護,wax框架整合到產品後多個元件交叉使用runtime的bug修復;再是探索Tianium跨平臺JS框架;再到FaceBook出品開源的ReactNative框架;再到最後的JSPatch… 這些框架的原始碼和Demo我都有涉及,從希望到失望…首先是自己維護的wax框架穩健性不夠,特別是通過AOP+forward相容64位後bug頻現,用作patch熱更新尚且能夠應付,但是想用來做元件動態部署成熟度還不夠。其次Tianium框架,關於jscore部分沒有開源不敢用,另外其bind oc api部分需要時刻跟進新版本的SDK是一個low點。 再其次是ReactNative框架,原始碼我沒有怎麼看,但是我寫了一個稍微複雜的頁面,當圖片在同一個頁面載入較多的時候,卡頓的現象特別明顯,讓我對js的效率產生了深深的懷疑。 JSPatch同樣是利用了forward訊息轉發機制完成了js和oc的bind,但是社群和框架成熟度仍然不夠。

最近阿里開源了增強版的wax框架,我連續看了兩天原始碼,對其增強部分的實現有了一個大致的瞭解,也讓我對lua-bind的方案有了很大的信心。之前受Andfix android平臺熱更新框架思路的影響,自己很想在這條路上再繼續折騰一番:如果能夠把OC程式碼通過一個轉換器轉化成lua程式碼,ios平臺的準直接動態部署應該是可以實現的。 所有的開發人員仍然用自己最熟悉的objc開發需求,測試和發版,比較版本程式碼的不同可以讓低版本的產品使用者使用高版本的功能。我們可以不按照版本釋出,轉而按照模組開發,所有的新需求和新運營方案都可以在不發版的情況推送給使用者。

Ali-Wax簡介

wax-lua 的語言優勢:

  • (1)自動垃圾回收:再也不用使用alloc,retain和release;
  • (2)程式碼少:沒有標頭檔案,沒有static型別、array常量、dictionary常量;
  • (3)能夠使用任何一個framework,例如cocoa、UITouch、Fondation等,任何用oc寫的framework,wax自動將其暴露給lua使用;
  • (4)超級簡單的http請求: 和REST的web service一起互動使用;
  • (5)lua也有函式閉包,也就是所謂的blocks;
  • (6)lua有內建的Regex-like 模式匹配library;

相比原Wax框架:

  • 64位支援;
  • 執行緒安全;
  • 其他一些特性:

>
1. lua function 轉化成 oc block,
2. 在lua中呼叫oc block,
3. getting/setting 私有成員變數,
4. 內建通用的C函式,
5. 支援lua程式碼debug;

在接下來的部落格系列中,我將結合Ali—Wax原始碼,介紹如何實現這些增強特性的,敬請期待。下面我們先來看看如何使用和整合wax框架和其debug環境。

Ali-Wax的Podfile整合

Wax框架只是一個熱更新實現方案,我們用於具體的產品進行補丁修復或者功能元件釋出還需要實現一個版本管理方案。在實現版本方案的時候,肯定涉及到在wax框架上的功能定製,比如說補丁現場恢復功能等(這部分功能我會開源到我的fork程式碼中)。另外我們現在用CocoaPods管理我們的程式碼元件版本,為了方便各自的產品修復bug,發放版本。 我建議大家fork一份程式碼到自己的github中,進行版本管理。

另外Ali-Wax框架中集成了lua的debug方案:mobdebug,位於wax/tools/mobdebug處,作者配置了Podspec,可以直接pod到你的除錯工程中。 這部分程式碼也不會有什麼變化,已建議作者單獨列一個git工程,目前我放到了自己的git空間裡,大家可以共享。

這樣我們就可以在專案工程中通過Pofile直接整合wax框架和程式碼除錯環境了(當然你也可以通過path指向wax clone專案的本地);podifle如下:

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '6.0'
inhibit_all_warnings!

workspace 'WLDWaxService'
xcodeproj 'LDWaxService'

target :LDWaxService do
    pod 'wax', :git => 'https://github.com/philonpang/wax.git'
    pod 'mobdebug', :git  => 'https://github.com/philonpang/mobdebug.git'
    link_with 'LDWaxService'
end

Ali-Wax的luaDebug

  • download ZeroBraneStudio (lua程式碼除錯IDE,直接git clone到本地)
  • run ZeroBraneStudio: 進入ZeroBraneStudio/zbstudio資料夾,直接雙擊ZeroBraneStudio.app檔案即可執行(將app拷貝到application中不能執行)
  • import lua code: click the 6th buttonSmaller icon, choose your lua code’s root directory
  • start debug server: click Project->Start Debugger Server. (每次開啟ZeroBraneStudio的時候,記得開啟這個選項)
  • run this code before you enter debug
    wax_start(nil, nil);//must start before debug
    extern void luaopen_mobdebug_scripts(void* L);
    luaopen_mobdebug_scripts(wax_currentLuaState());
  • addrequire('mobdebug').start('YOUR_MAC_IP_ADDRESS')to your lua code. if you use simulator 'YOUR_MAC_IP_ADDRESS' can be empty
  • launch your app,when require('mobdebug').start() is invoked, ZeroBraneStudio’s dock will become active, then you should add breakpoint. (這種情況下,當你在模擬器中執行app後,會自動跳在ZeroBraneStudio中啟動lua檔案中斷點下來)

坑1:import luaCode 的tip

官方截圖上看到的截圖是整個xcode工程的目錄,如果你import了整個工程,在目錄和檔案較多的情況下,ZeroBraneStudio中的斷點是無效的
其實你只需要import存放lua檔案的目錄即可。

坑2:xcode工程中的lua程式碼檔案

xcode新增檔案有兩種方式:Create groups 和 Create folder reference兩種。 按照前一種方式,你引入目錄的所有檔案在執行時會被拷貝到“XX.app/”目錄下,而後面一種方式目錄會以引用方式加入,執行時檔案仍然放在“XX.app/拷貝目錄/”下,而且當引入目錄中有新檔案新增的時候,不用再執行一遍新增操作。

所以我們在本地除錯程式碼的時候,建議以第二種方式引入目錄,這樣我們可以隨時在ZeroBraneStudio中新增檔案(而不用在xcode工程中再進行一次add操作)進行除錯。 但是執行lua程式碼中的require程式碼行時,會提示找不到對應的require檔案。這其實是lua 預設search 檔案的路徑沒有設定照成的,所以我們需要設定lua的search路徑環境變數。 程式碼如下:

#import "wax.h"
#import "wax_http.h"
#import "wax_json.h"
#import "wax_xml.h"


    //設定lua的search路徑環境變數
    NSString *patchPath = [[NSBundle mainBundle] pathForResource:@"patchDemo" ofType:nil];
    NSString *pp = [NSString stringWithFormat:@"%@/?.lua;", patchPath];
    setenv(LUA_PATH, [pp UTF8String], 1);

    //啟動wax框架和debug環境
    wax_start(nil, luaopen_wax_http, luaopen_wax_json, luaopen_wax_xml, nil);//must start
    extern void luaopen_mobdebug_scripts(void* L);
    void * p = wax_currentLuaState();
    luaopen_mobdebug_scripts(p);

    //執行啟動檔案
    wax_runLuaString("require('patch')");

完成以上步驟之後,你就可以在你的專案工程中開心的除錯lua程式碼了。如下圖所示: