diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 81a21fea8e..1bd75cdd06 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -18,6 +18,7 @@ - [Replacing One Type with Another](./replacing-types.md) - [Preventing the Derivation of `Copy` and `Clone`](./nocopy.md) - [Generating Bindings to C++](./cpp.md) +- [Generating Bindings to Objective-c](./objc.md) - [Using Unions](./using-unions.md) - [Using Bitfields](./using-bitfields.md) - [FAQ](./faq.md) diff --git a/book/src/objc.md b/book/src/objc.md new file mode 100644 index 0000000000..7c2892aaa9 --- /dev/null +++ b/book/src/objc.md @@ -0,0 +1,61 @@ +# 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 blacklisting. + +In order to generate bindings, you will need `-x objective-c` as the clang +args. If you'd like to use [block](https://crates.io/crates/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. + +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())`. + + +## Supported Features +* Inheritance matched to rust traits with prefixes of `I` which +stands for interface. +* Protocols which match to rust traits with prefixes of `P` which +stands for Protocol. +* Classes will generate `struct Foo(id)` where `Foo` is the class +name and `id` is 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-ios` as mentioned +[here](https://github.com/rust-lang/rust-bindgen/issues/1211#issuecomment-569804287). +* The generated bindings will almost certainly have some conflicts so you will +have to blacklist 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.h` as has a variable called timezone that +conflicts with some of the things in `NSCalendar.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](https://github.com/rust-lang/rust-bindgen/issues/1705). +* instancetype return methods does not return `Self` for you given class, it +returns a `mut * objc::runtime::Objc` which is aliased as `id`. This is because +objective-c's inheritance doesn't perfectly match that of rusts. +* Depending on what you're trying `bindgen` against, 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 +* Nullablibility attributes which return `Option`s. +* Probably many other things. Feel free to [open an issue](https://github.com/rust-lang/rust-bindgen/issues). + +# Example crate(s) +* [uikit-sys](https://github.com/simlay/uikit-sys)