Closed madsmtm closed 3 months ago
Both approaches have issues, so I've tried to strike a nice balance; we now emit
extern_methods!
when the category is defined in the same library/framework as the class, andextern_category!
otherwise. This doesn't completely resolve the issues around categories not having a stable name, but it does somewhat alleviate them.
Yeah, I think this is a reasonable trade off. I think the negative to this approach is that debugging/understanding is harder. There's two possible ways a function is added to a rust-side class - importing the trait that the category implements (a class has a category from a different library/framework) vs not.
The ergonomics of including a bunch of traits just for a few specific functions was pretty rough.
Semirelated, I wish there was a good way to do source maps/links to apple docs for things.
Both approaches have issues, so I've tried to strike a nice balance; we now emit
extern_methods!
when the category is defined in the same library/framework as the class, andextern_category!
otherwise. This doesn't completely resolve the issues around categories not having a stable name, but it does somewhat alleviate them.Yeah, I think this is a reasonable trade off. I think the negative to this approach is that debugging/understanding is harder. There's two possible ways a function is added to a rust-side class - importing the trait that the category implements (a class has a category from a different library/framework) vs not.
Thanks for the feedback; I'll try to document it at some point, tracking in https://github.com/madsmtm/objc2/issues/576.
Semirelated, I wish there was a good way to do source maps/links to apple docs for things.
Well, there is no good way, but there probably is a way, tracking in https://github.com/madsmtm/objc2/issues/309.
Categories are a way for Objective-C code to add extra methods to a class. There are basically two ways we could handle these in
header-translator
:Emit
extern_methods!
directly on the class (done currently).This breaks when the class is defined in a different library/framework than the category, because of Rust's coherence rules.
Create a trait, and implement that for the class (done in
uikit-sys
, and now byextern_category!
).One problem here is that the category name is not part of the API in Objective-C, so we actually have no stable name to refer to. Relatedly, it's annoying to have to import category traits with confusing names all the time.
Both approaches have issues, so I've tried to strike a nice balance; we now emit
extern_methods!
when the category is defined in the same library/framework as the class, andextern_category!
otherwise. This doesn't completely resolve the issues around categories not having a stable name, but it does somewhat alleviate them.This allows us to fix https://github.com/madsmtm/objc2/issues/531, we now emit the missing key-value coding categories (and other such categories on
NSObject
). This should also help with splittingicrate
up into multiple crates in the future, instead of it being a big monolithic one. Finally, this is required forheader-translator
to work on user-defined categories in the future (see https://github.com/madsmtm/objc2/issues/501).CC @simlay as you've gone with the second approach in
bindgen
's Objective-C support, wanted to hear your thoughts about this combined solution? I note that yours is currently better, since it implements the category trait for subclasses as well.