TLC is a very compact and minimal Objective-C bridge for LuaJIT. Written by Fjõlnir Ásgeirsson
localobjc=require("objc")
objc.loadFramework("AppKit")
pool=objc.NSAutoreleasePool:new()
objc.NSSpeechSynthesizer:new():startSpeakingString(objc.NSStr("Hello From Lua!"))
os.execute("sleep "..2)TLC supports the following:
- Loading frameworks
- Accessing Objective-C objects
- Creating Objective-C classes
- Calling methods on said objects
- Creating blocks from Lua functions
- Converting the basic lua types to objects (Explicitly)
- Loading BridgeSupport files
TLC Does not yet support the following:
- Calling methods that take a variable number of arguments
- Defining variadic blocks, methods or callbacks, or ones that take pass-by-value(non-pointer) structs or unions. (A limitation of LuaJIT FFI)
localobjc=require("objc")objc.loadFramework("Foundation")
-- You can also use BridgeSupport-- It is slower, but you get access to all C types, functions & constants automaticallylocalbs=require("objc.BridgeSupport")
bs.loadFramework("Foundation")
-- You can then access constants using bsmyView.center=bs.CGPointZerolocalNSString=objc.NSStringlocalmyStr=NSString:stringWithUTF8String("I am an NSString.")
-- Calling selectors with multiple arguments requires replacing the colons with underscores-- Except the ones at the end, they are optional.-- Example selector:with:multiple:parameters: => selector_with_multiple_parameters()-- selectorWithAnonymousParams:::: => selectorWithAnonymousParams()localanObject=MyObject:selector_with_multiple_parameters(arg1, arg2, arg3, arg4)-- If you know the type of the variable you want to convert you should use these functionslocalstring=NSStr("foobar")
localnumber=NSNum(123)
localarray=NSArr({"a","b","c"})
localdictionary=NSDic({ a=1, b=2, c=3 })
-- If not,-- The Obj() function takes an arbitrary value and determines the correct class to convert it tolocalobject=Obj(anyVariable)-- This creates a class and registers it with the runtime (it is also accessible with objc.MyClass after creation)-- The dictionary specifies an instance variable of type int(type encoding: i)-- To learn about type encodings read https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.htmllocalMyClass=objc.createClass(objc.NSObject, "MyClass", { ivar="i" })
-- Creates an init method returning an object(@) and taking as arguments an object(@) and a selector(:)-- All methods must take self and selector as their first two argumentsobjc.addMethod(MyClass, objc.SEL("init"), function(self, sel)
print("Creating an instance of", self:class())
objc.setIvar(self, "anIvar", 123)
returnobjc.callSuper(self, sel)
end, "@@:")
-- Add a getter for 'ivar'objc.addMethod(MyClass, objc.SEL("ivar"), function(self, sel)
returnobjc.getIvar(self, "ivar")
end, "i@:")
-- Add a setter for 'ivar'objc.addMethod(MyClass, objc.SEL("setIvar:"), function(self, sel, anIvar)
objc.setIvar(self, "ivar", anIvar)
end, "v@:i")
-- 'instance' is an object pointer usable on the lua side as well as the objective-c sidelocalinstance=MyClass:alloc():init()
instance:setIvar(123)
print(instance:ivar())-- To create a block you call createBlock with it's type encoding (Default being void return and no argument)-- A block returning an integer and taking one object and one double as argumentslocalblock=objc.createBlock(function(object, double)
print("I was passed these arguments: ", object, double)
return123end, "i@d")-- If you don't want to type 'objc.' before using a class you can set the global namespace to use it as a fallbacksetmetatable(_G, {__index=objc})
-- And then you can simply write the class names without the 'objc.' prefixobj=CoolClass:doThings()