Lua Cocoa
Lua Cocoa tasks access the Cocoa framework via the LuaCocoa bridge.
LuaCocoa provides a bridge between the Lua and Objective-C programming languages.
Calling the Task Run Function
KosmicTask Lua Cocoa powered tasks are initiated by calling the Run Function defined in the task Settings. In the following example the task Run Function is set to kosmicTask.
function kosmicTask()
return "Hello, kosmos!"
end
Result Objects
Tasks written in Lua Cocoa can return native Lua objects or Cocoa objects as task results. The LuaCocoa bridge ensures that all objects are coerced as required.
function kosmicTask()
-- return a NSArray instance
return NSArray:arrayWithArray_({"item 1", "item 2"})
end
Result File Handling
KosmicTask supports the returning of file contents within task results.
KosmicTask automatically looks for a kosmicFile record containing file paths within a dictionary type result object. If found, KosmicTask will return the contents of the file or files to the client.
For Lua Cocoa powered tasks files are returned as results using the following syntax:
local result = {}
result.kosmicFile = path
return result
A common usage scenario is that a task creates a temporary file (or files) whose contents are then returned to the client. KosmicTask therefore supports automatic temporary file creation and deletion. Temporary files created through KosmicTask are automatically deleted once the parent task has completed.
Lua Cocoa powered tasks can create temporary files by calling the KosmicTaskController resultFileWithName_ function.
LuaCocoa.import("Foundation")
function kosmicTask()
-- get the kosmicTaskController class
local taskController = NSClassFromString("KosmicTaskController")
-- get our image file result path
-- this file will be automatically deleted when the task ends.
local path = taskController:resultFileWithName_('capture.png')
path = tostring(path) -- get a native lua string
-- execute
os.execute("screencapture -t png " .. path)
-- return file content in dictionary
local result = {}
result.kosmicFile = path
result.kosmicInfo = "file returned"
return result
end
Logging and Debugging
Diagnostic and logging information can be written to a task's error stream on io.stderr.
-- send log value to stderr
io.stderr:write("Goodbye, kosmos!")
NSObject Subclassing
Lua objects can be subclassed directly from Cocoa's NSObject
-- create class definition
personClass = LuaCocoa.CreateClass("Person", NSObject)
-- method: initWithFirstName_lastName_
personClass["name"] =
{
function(self)
return "me"
end,
"-@@:@@"
}
Obj-C instance variables are declared and accessed using the followng syntax:
self.__ivars.var1 = "I am an instance variable var1"
self.__ivars.var2 = "I am an instance variable var2"
For details of the Lua colon syntax that is used to access NSObject methods see http://www.lua.org/pil/16.html
Type Encoding
NSObject subclass methods need to provide a type encoding method signature that defines both the function return type and its argument types.
The signature is constructed as follows:
[+/-][return type encoding][@:][argument type encoding]…
where:
[+/-]use + to designate a class method and - an instance method[return type encoding]a type encoding for the function return value[@:]this element is always required (it represents the receiver and selector passed as the first two arguments toobjc_msgSend())[argument type encoding]a type encoding for each function argument
Examples
+(void)initialize has a signature of +v@:
-(void *)timerFired:(id)sender has a signature of -v@:@
-(void)setObject:(id)obj forKey:(id)key has a signature of -v@:@@
+(NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats has a signature of +@@:d@:@c
Runloop Management
When a Lua Cocoa task is run the script runner is transformed into a fully fledged application complete with a run loop (an instance of NSRunLoop). This enables the task to utilise all the features of the Cocoa framework, many of which depend upon the existence of a run loop in order to perform correctly.
By default however the LuaCocoa task will exit its run loop whenever the task entry point exits unless it is requested to do otherwise. This is the case in the example above.
In order for the task to continue executing it is necessary to tell the task controller object (KosmicTaskController) to keep the task running after the script entry point function has returned. KosmicTaskController is a predefined class that can be accessed within the task script by using the statement taskController = NSClassFromString("KosmicTaskController").
To keep the task running call the KosmicTaskController keepTaskRunning static method. The task will then continue to process input events on its runloop until the KosmicTaskController stopTask_ static method is called. The task will then end and return its result to the client.
-- get the kosmicTaskController class
taskController = NSClassFromString("KosmicTaskController")
-- create class definition
KosmicTask = LuaCocoa.CreateClass("KosmicTask", NSObject)
-- method: start
KosmicTask["start"] =
{
function(self)
local selector = LuaCocoa.toselector("timerFired:")
-- schedule the timer
self.__ivars.timer = NSTimer:scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(1, self, selector, nil, true)
self.__ivars.count = 0
-- keep the task running after the entry point function exits
KosmicTaskController:keepTaskRunning()
return
end,
"-v@:"
}
-- method: timerFired:
KosmicTask["timerFired_"] =
{
function(self, timer)
self.__ivars.count = self.__ivars.count + 1
-- stop task and return result
if self.__ivars.count == 5 then
-- invalidate the timer
timer:invalidate()
KosmicTaskController:stopTask_("timer expired " .. self.__ivars.count .. " times")
end
return
end,
"-v@:@"
}
-- task entry point
function kosmicTask()
-- allocate our task object
task = KosmicTask:alloc():init()
-- start the task
task:start()
end
System Framework Access
Lua Cocoa tasks can access system framework classes using the LuaCocoa.import function.
LuaCocoa.import("AddressBook")
function kosmicTask()
local person = ABAddressBook:sharedAddressBook():me()
return person:valueForProperty_(kABFirstNameProperty)
end
Syntax Checking
Syntax checking is provided by luac.
LuaCocoa home http://playcontrol.net/opensource/LuaCocoa/
LuaCocoa documentation http://playcontrol.net/opensource/LuaCocoa/documentation.html
LuaCocoa source http://bitbucket.org/ewing/luacocoa
Lua home http://www.lua.org/
Lua reference manual http://www.lua.org/manual/5.1/
Lua online demo http://www.lua.org/demo.html
