Lua Cocoa

KosmicTask Help

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 to objc_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.