1# Generating Bindings to Objective-C 2 3`bindgen` does not (yet) have full objective-c support but it can generate bindings 4for a lot of the apple frameworks without too much blocklisting. 5 6In order to generate bindings, you will need `-x objective-c` as the clang 7args. If you'd like to use [block](https://crates.io/crates/block) you will need 8`-fblocks` as a clang arg as well. 9 10Depending on your setup, you may need `--generate-block` to generate the block 11function aliases and `--block-extern-crate` to insert a `extern crate block` at 12the beginning of the generated bindings. The same logic applies to the 13`--objc-extern-crate` parameter. 14 15The objective-c classes will be represented as a `struct Foo(id)` and a trait 16`IFoo` where `Foo` is the objective-c class and `id` is an alias for `*mut 17objc::runtime::Object` (the pointer to the objective-c instance). The trait 18`IFoo` is needed to allow for the generated inheritance. 19 20Functions that use or return objective-c pointers of instance `Foo` will return 21`Foo`. The reason this works is beacuse `Foo` represented as `transparent`. 22This will be helpful for a lot of objective-c frameworks however there are some 23cases where functions return `instancetype` which is a type alias for `id` so 24an occasional `foo.0` may be required. An example of this would in the UIKit 25framework should you want to add a `UILabel` to a 26[UIStackView](https://developer.apple.com/documentation/uikit/uistackview/1616227-addarrangedsubview?language=objc) 27you will need to convert the `UILabel` to a `UIView` via `UIView(label.0)`. 28 29Each class (struct) has an `alloc` and a `dealloc` to match that of some of the alloc 30methods found in `NSObject`. 31 32In order to initialize a class `Foo`, you will have to do something like `let 33foo = Foo(Foo::alloc().initWithStuff())`. 34 35To blocklist an Objective-C method, you should add the bindgen generated method 36path (e.g. `IFoo::method` or `IFoo::class_method`) as a blocklist item. 37 38## Supported Features 39 40* Inheritance matched to rust traits with prefixes of `I` which 41stands for interface. 42* Protocols which match to rust traits with prefixes of `P` which 43stands for Protocol. 44* Classes will generate `struct Foo(id)` where `Foo` is the class 45name and `id` is a pointer to the objective-c Object. 46* Blocks 47 48## Useful Notes 49 50* If you're targeting `aarch64-apple-ios`, you'll need to have the clang arg 51`--target=arm64-apple-ios` as mentioned 52[here](https://github.com/rust-lang/rust-bindgen/issues/1211#issuecomment-569804287). 53* The generated bindings will almost certainly have some conflicts so you will 54have to blocklist a few things. There are a few cases of the parameters being 55poorly named in the objective-c headers. But if you're using anything with 56Core Foundation, you'll find that `time.h` as has a variable called timezone that 57conflicts with some of the things in `NSCalendar.h`. 58* Some small subset of the function headers in the apple frameworks go against 59apple's guidelines for parameter names and duplicate the names in the header 60which won't compile as mentioned 61[here](https://github.com/rust-lang/rust-bindgen/issues/1705). 62* instancetype return methods does not return `Self` for you given class, it 63returns a `mut * objc::runtime::Objc` which is aliased as `id`. This is because 64objective-c's inheritance doesn't perfectly match that of rusts. 65* Depending on what you're trying `bindgen` against, you may end up including 66all of Core Foundation and any other frameworks. This will result in a very 67long compile time. 68 69## Not (yet) Supported 70 71* Nullability attributes which return `Option`s. 72* Probably many other things. Feel free to [open an issue](https://github.com/rust-lang/rust-bindgen/issues). 73 74# Example crate(s) 75 76* [uikit-sys](https://github.com/simlay/uikit-sys) 77