Generating Bindings to Objective-C
bindgen does not (yet) have full objective-c support but it can generate bindings
for a lot of the apple frameworks without too much blocklisting.
In order to generate bindings, you will need -x objective-c as the clang
args. If you'd like to use block you will need
-fblocks as a clang arg as well.
Depending on your setup, you may need --generate-block to generate the block
function aliases and --block-extern-crate to insert a extern crate block at
the beginning of the generated bindings. The same logic applies to the
--objc-extern-crate parameter.
The objective-c classes will be represented as a struct Foo(id) and a trait
IFoo where Foo is the objective-c class and id is an alias for *mut objc::runtime::Object (the pointer to the objective-c instance). The trait
IFoo is needed to allow for the generated inheritance.
Functions that use or return objective-c pointers of instance Foo will return
Foo. The reason this works is because Foo represented as transparent.
This will be helpful for a lot of objective-c frameworks however there are some
cases where functions return instancetype which is a type alias for id so
an occasional foo.0 may be required. An example of this would in the UIKit
framework should you want to add a UILabel to a
UIStackView
you will need to convert the UILabel to a UIView via UIView(label.0).
Each class (struct) has an alloc and a dealloc to match that of some of the alloc
methods found in NSObject.
In order to initialize a class Foo, you will have to do something like let foo = Foo(Foo::alloc().initWithStuff()).
To blocklist an Objective-C method, you should add the bindgen generated method
path (e.g. IFoo::method or IFoo::class_method) as a blocklist item.
Supported Features
- Inheritance matched to rust traits with prefixes of
Iwhich stands for interface. - Protocols which match to rust traits with prefixes of
Pwhich stands for Protocol. - Classes will generate
struct Foo(id)whereFoois the class name andidis a pointer to the objective-c Object. - Blocks
Useful Notes
- If you're targeting
aarch64-apple-ios, you'll need to have the clang arg--target=arm64-apple-iosas mentioned here. - The generated bindings will almost certainly have some conflicts so you will
have to blocklist a few things. There are a few cases of the parameters being
poorly named in the objective-c headers. But if you're using anything with
Core Foundation, you'll find that
time.has has a variable called timezone that conflicts with some of the things inNSCalendar.h. - Some small subset of the function headers in the apple frameworks go against apple's guidelines for parameter names and duplicate the names in the header which won't compile as mentioned here.
- instancetype return methods does not return
Selffor you given class, it returns amut * objc::runtime::Objcwhich is aliased asid. This is because objective-c's inheritance doesn't perfectly match that of rusts. - Depending on what you're trying
bindgenagainst, you may end up including all of Core Foundation and any other frameworks. This will result in a very long compile time.
Not (yet) Supported
- Nullability attributes which return
Options. - Probably many other things. Feel free to open an issue.