lua in iOS App
起源
其實(shí)很早我在參加一個沙龍的時候,就聽到了點(diǎn)評的同學(xué)在用lua做ab test,雖然那個時候我覺得我自己很牛逼了,但是其實(shí)還是啥都沒有聽懂,直到今天才回過神來仔細(xì)看了下這個東西。
Lua(簡稱擼?。┰趇OS中的確被廣泛的使用著,在行業(yè)中***的莫過于魔獸世界(山口山)以及移動互聯(lián)網(wǎng)的憤怒的小鳥。
Lua在cocos2d以及iOS的應(yīng)用動態(tài)變化上面使用比較廣泛,下面我們用兩個例子來說明下。
框架
不得不說,***的莫過于wax和waxpatch,一個是能夠在iOS中使用lua語言編寫界面控件,一個是能夠動態(tài)更新。
wax
我們首先先要下載wax.framework,然后新建一個iOS app的project,將該模塊添加到我們的工程中去。
接著我們需要在 AppDelegate.h import #import
在AppDlegate的實(shí)現(xiàn)中增加
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- // Override point for customization after application launch.
- wax_start("init.lua", nil);
- return YES;
- }
接著我們來增加這個 init.lua ,如下代碼,其實(shí)就如同ViewController頭文件定義一樣。
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- // Override point for customization after application launch.
- wax_start("init.lua", nil);
- return YES;
- }
有了頭文件之后我們也需要有實(shí)現(xiàn)吧,這個代碼可讀性就比oc來的高多了,但是需要在***行聲明在oc中的這個類名。
- waxClass{"ViewController", UIViewController}
- function viewDidLoad(self)
- self.super:viewDidLoad(self)
- local label = UILabel:initWithFrame(CGRect(0, 120, 320, 40))
- label:setColor(UIColor:blackColor())
- label:setText("Hello Wax!")
- label:setTextAlignment(UITextAlignmentCenter)
- local font = UIFont:fontWithName_size("Helvetica-Bold",50)
- label:setFont(font)
- self:view():addSubview(label)
- end
先不要急著編譯,我們還需要更改一下編譯的方式以及確認(rèn)framework已經(jīng)被準(zhǔn)確導(dǎo)入
我們來看下效果:
waxpatch
waxpatch完全就是基于這個wax的框架之上去做的一個動態(tài)更新的組件了。我們來看下動態(tài)更新的流程。
***步:增加一個加載的協(xié)議
增加一個 ProtocolLoader.h ,其中添加需要去動態(tài)更新的組建名稱。
- #import < UIKit/UIKit.h>
- @interface ProtocolLoader : NSObject < UIApplicationDelegate, UIWebViewDelegate, UIActionSheetDelegate, UIAlertViewDelegate, UISearchBarDelegate, UITextViewDelegate, UITabBarControllerDelegate> {}
- @end
- @implementation ProtocolLoader
- @end
第二步:聲明需要加載的遠(yuǎn)程服務(wù)器地址,并且增加解壓縮的頭文件和實(shí)現(xiàn)
我在 AppDelegate.m 中先聲明了我遠(yuǎn)程更新庫的地址:
- #define WAX_PATCH_URL @"https://github.com/monkeytest15/waxDemo/raw/master/patch.zip"
同時增加解壓縮實(shí)現(xiàn):
第三步:加載
當(dāng)然,我們都會理解為加載的邏輯是在 AppDelegate.m 中實(shí)現(xiàn)的,不過其實(shí)在該文件中只是調(diào)用了加載這個方法,具體的實(shí)現(xiàn)我在debug的過程發(fā)現(xiàn)在 wax.m 的文件中,核心代碼如下:
- // Load stdlib
- // ---------------
- #ifdef WAX_STDLIB
- // If the stdlib was autogenerated and included in the source, load
- char stdlib[] = WAX_STDLIB;
- size_t stdlibSize = sizeof(stdlib);
- #else
- char stdlib[] = "require 'wax'";
- size_t stdlibSize = strlen(stdlib);
- #endif
- if (luaL_loadbuffer(L, stdlib, stdlibSize, "loading wax stdlib") || lua_pcall(L, 0, LUA_MULTRET, 0)) {
- fprintf(stderr,"Error opening wax scripts: %s\n", lua_tostring(L,-1));
- }
加載之后就會動態(tài)的加載我們遠(yuǎn)程服務(wù)端的邏輯.
遠(yuǎn)程zip包
接著我們來看下遠(yuǎn)程服務(wù)端上都有什么,遠(yuǎn)程服務(wù)端可以自己定義zip包的名字以及內(nèi)容,但約定的內(nèi)容是必須有一個patch.lua文件以及其他的.lua的文件,patch.lua中是需要定義本次更新的View的主類名稱。比如 require "MainViewController"
而其他的類自然就是需要更新的邏輯,如:
- waxClass{"MainViewController", UITableViewController}
- function tableView_cellForRowAtIndexPath(self, tableView, indexPath)
- local cell = self:ORIGtableView_cellForRowAtIndexPath(tableView, indexPath)
- cell:textLabel():setText("" .. (20 - indexPath:row()))
- cell:detailTextLabel():setText("This is monkey")
- cell:textLabel():setTextColor(UIColor:blueColor())
- return cell
- end
動態(tài)效果
然后我們來看下我更新之后的效果吧:
原文鏈接:http://blog.sina.com.cn/s/blog_7022adbf0102vcg3.html