objc #
This vlang package provides Objective-C Runtime bindings for V.
Status
It is currently working in progress and should be considered experimental. It's only tested on x86_64 architecture, macOS Sonoma 14.0.
Supported features:
- Bool type
- Id type
- Load classes
- Create instances
- Register selectors
- Send messages (varargs are not supported)
- Class declaration
Installation
v install magic003.objc
Usage
Bool type
The Bool type is an alias of the V bool type.
assert objc.yes == true
assert objc.no == false
Load a class
An Objective-C class can be loaded using either a factory function or a static type method.
cls1 := objc.Class.get('NSMutableArray') or { panic('failed to load class NSMutableArray') }
cls2 := objc.class('NSMutableArray') or { panic('failed to load class NSMutableArray') }
Register and get a selector
An Objective-C selector can be registered using either a factory function or a static type method.
s1 := objc.Sel.get('init')
s2 := objc.sel('init')
Send messages
Messages can be sent to a class or an instance. There are two types of messages:
request[R](): a message with return typeR.notify(): a message without a return value.
unsafe {
// a mutable array instance is created via chained messages
arr := cls1.message(objc.sel('alloc')).request[objc.Id]()
.message(objc.sel('init')).request[objc.Id]()
// load the NSObject class and create an instance
obj_cls := objc.class('NSObject') or { panic('failed to load class NSObject') }
obj := obj_cls.message(sel('new')).request[objc.Id]()
// add an object to the array. Message with one argument and no return value.
// Use `args2()`, `args3()` and etc for more arguments.
arr.message(sel('addObject:')).args1(obj).notify()
// message without an argument.
size := arr.message(sel('count')).request[u64]()
assert size == 1
}
Declare a new class
New classes can be declared and registered with the Objective-C Runtime.
superclass := objc.class('NSObject') or { panic('failed to load class NSObject') }
// create a new class with `NSObject` as the super class.
decl := ClassDecl.new(superclass, 'NewClass', 0) or {
panic('failed to create class NewClass')
}
// add ivars
decl.add_ivar[i64]('num')
decl.add_ivar[objc.Id]('obj')
// add methods
m1 := objc.void_method_1[bool](fn (self objc.Id, cmd objc.Sel, flag bool) {
// do something
})
unsafe { decl.add_method(objc.sel('method1:'), m1) }
m2: = objc.method_1[int, objc.Id](fn (self objc.Id, cmd objc.Sel, obj objc.Id) int {
return 10
})
unsafe { delc.add_method(objc.sel('method2:'), m2) }
// register the class
cls := decl.register()
unsafe {
// create an instance from the new class
obj := cls.message(objc.sel('new')).request[objc.Id]()
// set ivar
obj.set_ivar('num', 1)
// call method
obj.message(objc.sel('method1:')).args1(true).notify()
}
Examples
The unit tests have basic usages.
Check out the examples folder for more examples.
Documentation
- API Documentation: http://magic003.github.io/objc
- Why this project: V and Objective-C interoperability
References
- Programming with Objective-C
- Objective-C Runtime APIs
- rust-objc: Objective-C bindings for Rust.
Constants #
const yes = Bool(true)
yes as true.
const no = Bool(false)
no as false.
fn class #
fn class(name string) ?Class
class returns the class definition of a specified class. It returns none if
the class is not registered with the Objective-C runtime.
Example
cls := class('NSObject') or { panic('failed to load class NSObject') }
fn void_method_4 #
fn void_method_4[A, B, D, E](imp fn (self Id, cmd Sel, a A, b B, d D, e E)) MethodImpl
void_method_4 creates a MethodImpl which has four arguments and no return value.
fn encode #
fn encode[T]() !ec.Encoding
encode returns the Objective-C encoding of the type parameter T.
fn method_0 #
fn method_0[R](imp fn (self Id, cmd Sel) R) MethodImpl
method_0 creates a MethodImpl which returns a value and doesn't have an argument.
fn method_1 #
fn method_1[R, A](imp fn (self Id, cmd Sel, a A) R) MethodImpl
method_1 creates a MethodImpl which has one argument and returns a value.
fn method_2 #
fn method_2[R, A, B](imp fn (self Id, cmd Sel, a A, b B) R) MethodImpl
method_2 creates a MethodImpl which has two arguments and returns a value.
fn method_3 #
fn method_3[R, A, B, D](imp fn (self Id, cmd Sel, a A, b B, d D) R) MethodImpl
method_3 creates a MethodImpl which has three arguments and returns a value.
fn method_4 #
fn method_4[R, A, B, D, E](imp fn (self Id, cmd Sel, a A, b B, d D, e E) R) MethodImpl
method_4 creates a MethodImpl which has four arguments and returns a value.
fn sel #
fn sel(name string) Sel
sel registers a method with the Objective-C runtime system, maps the method name to a selector, and returns the selector value.
Example
sel1 := sel('new')
sel2 := sel('allocWithZone:')
fn void_method_0 #
fn void_method_0(imp fn (self Id, cmd Sel)) MethodImpl
void_method_0 creates a MethodImpl which doesn't have an argument and return value.
fn void_method_1 #
fn void_method_1[A](imp fn (self Id, cmd Sel, a A)) MethodImpl
void_method_1 creates a MethodImpl which has one argument and no return value.
fn void_method_2 #
fn void_method_2[A, B](imp fn (self Id, cmd Sel, a A, b B)) MethodImpl
void_method_2 creates a MethodImpl which has two arguments and no return value.
fn void_method_3 #
fn void_method_3[A, B, D](imp fn (self Id, cmd Sel, a A, b B, d D)) MethodImpl
void_method_3 creates a MethodImpl which has three arguments and no return value.
interface MethodImpl #
interface MethodImpl {
// the function implementation.
imp Imp
// encodings returns the encodings of the method.
encodings() []ec.Encoding
}
An interface of the method implementation which can be added to a class declaration.
fn (Msg1[A]) request #
fn (m Msg1[A]) request[R]() R
request sends a message requesting for a value of type R.
Unsafe because the caller must ensure the return type R and argument types match those of the Objective-C function.
fn (Msg1[A]) notify #
fn (m Msg1[A]) notify()
notify sends a message without a return value.
Unsafe because the caller must ensure the argument types match those of the Objective-C function.
type Bool #
type Bool = bool
A type that represents a Boolean value in Objective-C.
fn (Msg4[A, B, D, E]) request #
fn (m Msg4[A, B, D, E]) request[R]() R
request sends a message requesting for a value of type R.
Unsafe because the caller must ensure the return type R and argument types match those of the Objective-C function.
fn (Msg4[A, B, D, E]) notify #
fn (m Msg4[A, B, D, E]) notify()
notify sends a message without a return value.
Unsafe because the caller must ensure the argument types match those of the Objective-C function.
fn (MsgBuilder) args1 #
fn (m MsgBuilder) args1[A](a A) Msg1[A]
args1 adds 1 argument to the message.
fn (MsgBuilder) args2 #
fn (m MsgBuilder) args2[A, B](a A, b B) Msg2[A, B]
args2 adds 2 arguments to the message.
fn (MsgBuilder) args3 #
fn (m MsgBuilder) args3[A, B, D](a A, b B, d D) Msg3[A, B, D]
args3 adds 3 arguments to the message.
fn (MsgBuilder) args4 #
fn (m MsgBuilder) args4[A, B, D, E](a A, b B, d D, e E) Msg4[A, B, D, E]
args4 adds 4 arguments to the message.
fn (MsgBuilder) request #
fn (m MsgBuilder) request[R]() R
request sends a message requesting a value of type R.
Unsafe because the caller must ensure the return type R matches that of the Objective-C function.
fn (MsgBuilder) notify #
fn (m MsgBuilder) notify()
notify sends a message without a return value.
Unsafe because the caller must ensure the argument types match those of the Objective-C function.
type Sel #
type Sel = voidptr
A type that represents a method selector, SEL, in Objective-C.
fn (Sel) Sel__static__get #
fn Sel.get(name string) Sel
Sel.get registers a method with the Objective-C runtime system, maps the method name to a selector, and returns the selector value.
Example
sel1 := Sel.get('new')
sel2 := Sel.get('allocWithZone:')
fn (Msg2[A, B]) request #
fn (m Msg2[A, B]) request[R]() R
request sends a message requesting for a value of type R.
Unsafe because the caller must ensure the return type R and argument types match those of the Objective-C function.
fn (Msg2[A, B]) notify #
fn (m Msg2[A, B]) notify()
notify sends a message without a return value.
Unsafe because the caller must ensure the argument types match those of the Objective-C function.
fn (Id) message #
fn (id Id) message(op Sel) MsgBuilder
message creates a message with the id as the receiver and op as the method selector.
fn (Id) class #
fn (id Id) class() Class
class returns the class of this instance.
fn (Id) set_ivar #
fn (id Id) set_ivar[T](name string, value T)
set_ivar sets the value of an instance variable.
Unsafe because the caller must ensure the ivar is actually of type T.
fn (Id) get_ivar #
fn (id Id) get_ivar[T](name string) T
set_ivar returns the value of an instance variable.
Unsafe because the caller must ensure the ivar is actually of type T.
type Imp #
type Imp = fn ()
A pointer to the start of a method implementation.
fn (Msg3[A, B, D]) request #
fn (m Msg3[A, B, D]) request[R]() R
request sends a message requesting for a value of type R.
Unsafe because the caller must ensure the return type R and argument types match those of the Objective-C function.
fn (Msg3[A, B, D]) notify #
fn (m Msg3[A, B, D]) notify()
notify sends a message without a return value.
Unsafe because the caller must ensure the argument types match those of the Objective-C function.
struct Class #
struct Class {
ptr voidptr [required] // the Objective-C Class object
}
A type that represents an Objective-C class.
fn (Class) Class__static__get #
fn Class.get(name string) ?Class
Class.get returns the class definition of a specified class. It returns none if
the class is not registered with the Objective-C runtime.
fn (Class) message #
fn (c Class) message(op Sel) MsgBuilder
message creates a message with the class instance as the receiver and op as the method selector.
fn (Class) instance_variable #
fn (c Class) instance_variable(name string) ?Ivar
instance_variable returns the Ivar for a specified instance variable of a given class.
struct ClassDecl #
struct ClassDecl {
cls voidptr [required] // the Objective-C Class object
}
A type used to declare a new class.
fn (ClassDecl) ClassDecl__static__new #
fn ClassDecl.new(superclass Class, name string, extra_bytes usize) ?ClassDecl
ClassDecl.new creates a new class. It returns none if the class could not be created (for example,
the desired name is already in use).
fn (ClassDecl) add_ivar #
fn (d ClassDecl) add_ivar[T](name string) bool
add_ivar adds a new instance variable of type T to a class.
fn (ClassDecl) add_method #
fn (d ClassDecl) add_method(name Sel, method MethodImpl) bool
add_method adds a new method to a class.
Unsafe because the caller must ensure the method type matches that is expected by Objective-C.
fn (ClassDecl) register #
fn (d ClassDecl) register() Class
register registers the class.
struct Ivar #
struct Ivar {
ptr voidptr [required]
}
A type that represents an instance variable in an Objective-C class.
fn (Ivar) name #
fn (v Ivar) name() string
name returns the name of an instance variable.
fn (Ivar) type_encoding #
fn (v Ivar) type_encoding() string
type_encoding returns the type string of an instance variable.
fn (Ivar) offset #
fn (v Ivar) offset() isize
offset returns the offset of an instance variable.
- README
- Constants
- fn class
- fn void_method_4
- fn encode
- fn method_0
- fn method_1
- fn method_2
- fn method_3
- fn method_4
- fn sel
- fn void_method_0
- fn void_method_1
- fn void_method_2
- fn void_method_3
- interface MethodImpl
- type Msg1[A]
- type Bool
- type Msg4[A, B, D, E]
- type MsgBuilder
- type Sel
- type Msg2[A, B]
- type Id
- type Imp
- type Msg3[A, B, D]
- struct Class
- struct ClassDecl
- struct Ivar