xref: /third_party/rust/crates/bindgen/book/src/objc.md (revision 12a9d9c8)
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