Fakie
Fakie is a framework that lets you write native iPhone apps in
Lua. It bridges Objective-C and Lua using the Objective-C runtime. With Fakie, anything you can do in Objective-C is automatically
available in Lua! What are you waiting for, give it a shot!
上述文字大概意思是说Fakie是打通lua和Objective-c的世界的桥梁, OC中的任何特性,通过Fakie, 都可以适用LUA. 比如OC中有一个类叫UIView,使用了Fakie之后, 你也可以在LUA脚本中使用UIView, 你可以继承UIView,继承的方法也很简单,下面有介绍,你也可以直接创建一个UIView的实例,可以调用所有这个类所支持的函数,无论是类方法,还是成员方法,比如initWithFrame(), 更有意思的是Fakie中的命名基本和OC是一致的,甚至也有CGRectMake…, 这一点真的太棒了,我非常喜欢!
于是在LUA脚本中创建一个子view就非常简单了
local view = FakieCreateInstance(UIView);
view:initWithFrame(CGRectMake(100, 100, 200, 200));
self:view():addSubview(view);
Why write iPhone apps in Lua?
I love writing iPhone apps, but would rather write them in a dynamic language than in Objective-C. Here
are some reasons why many people prefer LUA over Objective-C…
- Online Patching Aka Hot Patching
- Less Header File
- It’s very easy
为什么要使用LUA写iOS app, 我的经验告诉我, 每次发布更新都要经过苹果审核,最少一周的时间啊。所以iOS app需要一种可以动态更新的能力. 无论是用来修复线上bug还是说完全的功能更新, 让我绕过至少一周的等待,我的耐心很少,每次的等待都让我很焦虑,所以我需要动态更新!
另外为什么选择lua, 因为lua是非常简单使用的语言, 关键是速度快,速度,是属于LUA的骄傲!
后面的基本上都是用法了, iOS程序猿扫一眼就知道是个什么情况了。 使用Fakie以后, Lua中所有的属性的访问方式都是函数的形式获取的。比如 self.view 变成了self:view() 和self:setView(newView)。 这个也好理解, xcode帮我们把点语法的调用,自动转换成了getter和setter的调用, Fakie中没有人帮你做这个事情,所以就需要自己调用了。
For some simple Fakie apps How would I create a tableView and initialize it?
/**
Fakie provide a usefull function called
FakieCreateInstance,you can use this function to
create any instance of class.
colon is used for sending a message to
Objective-C object and dot used for sending a
class message.
*/
local tableView = FakieCreateInstance(UITableView);
tableView:initWithFrame(CGRectZero);
self:view():addSubview(tableView);
tableView:setDelegate(self);
tableView:setDataSource(self);
/**
you can access super class variable by
setValue_forKeyPath and valueForKeyPath
*/
function MyViewController:viewDidLoad()
self:super():viewDidLoad();
self:setValue_forKeyPath("this is a sub text", "label.text")
label = self:valueForKeyPath("label")
end
What about NSDictionary, NSArray, NSSet, NSString
/**
Fakie apply a series of handful Functions for you
OCString(string): convert lua string to NSString
OCDic(table): convert table to NSMutableDictionary
OCArray(table): convert table to NSMutableArray
OCSet(table): convert table to NSMutableSet
if you do not call these functions explicitly,Fakie will do these convertions automatically for you. the default behavior is string to
NSString, table to NSMutableArray or NSMutableDictionary
*/
local dataSource = OCArray({"Hello", "Fakie", "!"})
self:setValue_forKeyPath(dataSource, "dataSource")
What about methods with multiple arguments?
Just add underscores to the method name, then write the arguments like you would in a regular C function
function MyViewController:tableView_numberOfRowsInSection(tableView,section)
local array = self:valueForKeyPath("dataSource")
return array:count();
end
...
label = self:valueForKeyPath("label")
local size = label:text():sizeWithFont(label:font())
What if I want to create a custom UIViewController?
/**
Created in "MyViewController.lua"
Creates an Objective-C class called MyController with UIViewController
as the parent. This is a real Objective-C object, you could even
reference it from Objective-C code if you wanted to.
*/
FakieClassBegin{"MyViewController",UIViewController,
protocals = {"UITableViewDataSource", "UITableViewDelegate"}}
function MyViewController:init()
-- to call a method on super, simply use self:super()
self = self:super():initWithNibName_bundle("MyControllerView.xib", nil)
if nil ~= self then
-- do your stuff here
end
return self
end
function MyViewController:viewDidLayoutSubviews( )
self:super():viewDidLayoutSubviews();
local rect = self:view():frame();
self:tableView():setFrame(CGRectMake(0, 100, rect.size.width, rect.size.height - 100))
label = self:valueForKeyPath("label")
local size = label:text():sizeWithFont(label:font())
label:setFrame(CGRectMake((rect.size.width - size.width)/2,
(100 - size.height)/2,
size.width, size.height));
end
function MyViewController:viewDidLoad()
-- Do all your other stuff here
local dataSource = OCArray({"Hello", "Fakie", "!"})
self:setValue_forKeyPath(dataSource, "dataSource")
end
function MyViewController:tableView_heightForRowAtIndexPath(tableView, indexPath)
return self:getheight(table, indexPath)
end
function MyViewController:tableView_cellForRowAtIndexPath(tableView,
indexPath)
local identifier = "identifier"
local cell = tableView:dequeueReusableCellWithIdentifier(identifier);
if nil == cell then
cell = FakieCreateInstance(UIMyTableViewCell)
cell:initWithStyle_reuseIdentifier(0, identifier);
end
if 0 == indexPath:row() then
cell:contentView():setBackgroundColor(UIColor.orangeColor())
else
cell:contentView():setBackgroundColor(UIColor.yellowColor())
end
local dataSource = self:valueForKeyPath("dataSource")
local title = dataSource:objectAtIndex(indexPath:row())
cell:updateWithTitle(title)
return cell
end
FakieClassEnd("MyViewController")
//! after finished MyViewController.lua, you can create MyViewController
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreenmainScreen].bounds];
...
do your stuff
...
initialize Fakie library here by calling fakie_start()
...
self.window.rootViewController = [[NSClassFromString(@"MyViewController") alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
Which API’s are included?
Fakie translate and pass the message from LUA’s world to Objective-C’s world, and also do the samething from Objective-C’s world to LUA. Therefore, all of the Objective-C api can work through.
About lua version
Fakie support latest version of Lua. The current release is Lua 5.3.0.
Fakie also support lua 5.2 and Lua 5.1.
Lua 5.0.3 is released on 26 Jun 2006, it’s too old, so Fakie will not
support this version and the versions before.
Lua 5.0.3 is released on 26 Jun 2006, it’s too old, so Fakie will not support this versionand the versions before.