lua in iOS App

http://www.cocoachina.com/ios/20150227/11183.html


起源

其实很早我在参加一个沙龙的时候,就听到了点评的同学在用lua做ab test,虽然那个时候我觉得我自己很牛逼了,但是其实还是啥都没有听懂,直到今天才回过神来仔细看了下这个东西。

Lua(简称撸啊)在iOS中的确被广泛的使用着,在行业中最著名的莫过于魔兽世界(山口山)以及移动互联网的愤怒的小鸟。

Lua在cocos2d以及iOS的应用动态变化上面使用比较广泛,下面我们用两个例子来说明下。

框架

不得不说,最著名的莫过于wax和waxpatch,一个是能够在iOS中使用lua语言编写界面控件,一个是能够动态更新。

wax

我们首先先要下载wax.framework,然后新建一个iOS app的project,将该模块添加到我们的工程中去。

851528621fb71d44350ba919d89f56f5.png

接着我们需要在 AppDelegate.h import #import

在AppDlegate的实现中增加

1
2
3
4
5
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     // Override point for customization after application launch.
     wax_start( "init.lua" , nil);
     return  YES;
}

接着我们来增加这个 init.lua ,如下代码,其实就如同ViewController头文件定义一样。

1
2
3
4
5
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     // Override point for customization after application launch.
     wax_start( "init.lua" , nil);
     return  YES;
}

有了头文件之后我们也需要有实现吧,这个代码可读性就比oc来的高多了,但是需要在第一行声明在oc中的这个类名。

1
2
3
4
5
6
7
8
9
10
11
12
13
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

先不要急着编译,我们还需要更改一下编译的方式以及确认framework已经被准确导入

51c2e759675e9a231d6e9e7f952b86ce.png

我们来看下效果:

bdcdadd0343ea05fcd890e56dc2ba027.gif

waxpatch

waxpatch完全就是基于这个wax的框架之上去做的一个动态更新的组件了。我们来看下动态更新的流程。

第一步:增加一个加载的协议

增加一个 ProtocolLoader.h ,其中添加需要去动态更新的组建名称。

1
2
3
4
5
6
7
#import < UIKit/UIKit.h>
 
@interface ProtocolLoader : NSObject < UIApplicationDelegate, UIWebViewDelegate, UIActionSheetDelegate, UIAlertViewDelegate, UISearchBarDelegate, UITextViewDelegate, UITabBarControllerDelegate> {}
@end
 
@implementation ProtocolLoader
@end

第二步:声明需要加载的远程服务器地址,并且增加解压缩的头文件和实现

我在 AppDelegate.m 中先声明了我远程更新库的地址: 

同时增加解压缩实现:

c28f2239b12550faf7d64c780f785afa.png

第三步:加载

当然,我们都会理解为加载的逻辑是在 AppDelegate.m 中实现的,不过其实在该文件中只是调用了加载这个方法,具体的实现我在debug的过程发现在 wax.m 的文件中,核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
     // 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));
     }

加载之后就会动态的加载我们远程服务端的逻辑.

远程zip包

接着我们来看下远程服务端上都有什么,远程服务端可以自己定义zip包的名字以及内容,但约定的内容是必须有一个patch.lua文件以及其他的.lua的文件,patch.lua中是需要定义本次更新的View的主类名称。比如 require "MainViewController"

而其他的类自然就是需要更新的逻辑,如:

1
2
3
4
5
6
7
8
9
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

动态效果

然后我们来看下我更新之后的效果吧:

e7357cf7f8a9f55f2e82f033cb0d13d1.gif

总结

xcode对于lua动态支持做的还是不错的,不过资料的确比较少,之后看看是不是还有很多可做之处。不过做ab test应该绰绰有余了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值