mono / Embeddinator-4000

Tools to turn .NET libraries into native libraries that can be consumed on Android, iOS, Mac, Linux and other platforms.
MIT License
758 stars 95 forks source link

[objc] Support for Events/Callbacks/Delegates/etc #351

Open lemonmojo opened 7 years ago

lemonmojo commented 7 years ago

First of, awesome work with this project! It's already quite usable even at this early stage.

The one feature I'm really missing though is support for somehow calling back into native code from managed. Right now there doesn't appear to be any way to achieve this.

I tried events, c# delegates and System.Action. All of those are either ignored by objcgen or throw an error during generation. I also tried creating an NSObject property which I planned to use as classic Cocoa delegate but this cannot be exposed to native either.

Is there any way to achieve this at the moment and if not, is it planned for the near future?

Thx again for such a useful product!

lemonmojo commented 7 years ago

Just found a workaround by using NSNotificationCenter. Good enough for the time being.

spouliot commented 7 years ago

Unlike Xamarin.iOS and Xamarin.Mac, E4K is not a runtime (nor do we plan to make it one) but only a generator.

That makes callbacks, from managed to native, tricky (if they cannot be directly generated code). This is a known issue and already tracked in #217. It's also documented in https://mono.github.io/Embeddinator-4000/Limitations.html (under Subclassing, which is a case we're not likely to ever support). Hopefully we'll have some alternative for other kinds of "managed to native" callbacks.

Right now the easiest way, as you found out, is to use XI (or XM) to get runtime support that will handle the transitions. If you have an example to share we can add it to the documentation (or/and a sample) to help other people facing the same limitation.

spouliot commented 7 years ago

throw an error during generation.

It would be helpful if you can file issue on those, with test cases (e.g. signatures). We should only warn (and skip) unsupported stuff, the rest needs fixing :)

lemonmojo commented 7 years ago

Thx for clarification! Will definitely post a sample after I get rid of the issue described in https://github.com/mono/Embeddinator-4000/issues/357.

Zomb commented 7 years ago

Does anyone have an example of how to go about doing this using any of the methods mentioned in the Limitations doc? I have tried Interfaces and using NSObject, but not had much luck. Would it be better if I make a sample project with the errors I have and put it on GitHub? Thank you!

lemonmojo commented 7 years ago

In my prototype projects I'm using NSNotifications to work around the lack of events. You can find an example project here: https://github.com/lemonmojo/E4kBackgroundTest

By declaring interfaces and internal classes that implement those interfaces I can pass objects around between mono and objc as event args.

One caveat of this approach is that any objects you want to expose in your event args must be convertible to NSObjects. Also you don't have access to the sender of the event but that can be worked around with using some kind of user state object or an ID that is accessible on both sides.

If you give my sample project a try, make sure to edit the path to objcgen.exe in the managed project settings "Custom Commands - After Build" section. After adjusting the path, build the managed project. Then open the native Xcode project and run it.

Zomb commented 7 years ago

Thank you for the sample! Yes, we can use NSNotifications to work around it, I was just wondering if anyone has had any success with using Xamarin.iOS and NSObject to provide a callback, but if not, we will go down NSNotification route!

lemonmojo commented 6 years ago

Any news on this front?

Missing support for Events/Callbacks/Delegates/etc. is one of the reasons we haven't yet fully adopted E4k. It's cumbersome to work around it using NSNotification's and in some cases just not possible (ie. if source code changes are not possible).

I've noticed that the Dubrovnik project does support events through some magical trickery. Maybe some of that can be used as a reference for implementation in E4k?

Here are some of the relevant pieces code: https://github.com/ThesaurusSoftware/Dubrovnik/blob/b59a271a1678bb18203068ece543dac31c1846d3/Mono.mscorlib/Mono.mscorlib/Categories/System_Delegate%2Bmscorlib.m

https://github.com/ThesaurusSoftware/Dubrovnik/blob/d194e1beccd3e4d47436c4ae67d6a49fc63439e5/Framework/XCode/Categories/NSObject%2BDBManagedEvent.m

https://github.com/ThesaurusSoftware/Dubrovnik/blob/d194e1beccd3e4d47436c4ae67d6a49fc63439e5/Framework/XCode/Representations/DBManagedEvent.h

https://github.com/ThesaurusSoftware/Dubrovnik/blob/4a76d76cc868c60ad07c597f0e543afbf5f0a27e/Framework/XCode/Representations/DBManagedEvent.m

https://github.com/robert-j/Mono.Embedding/blob/master/Mono.Embedding/UniversalDelegateServices.cs

emysa341 commented 6 years ago

Any progress on this ?

amitkhoth commented 4 years ago

@chamons @rolfbjarne What is current status for "Support for Events/Callbacks/Delegates/etc #351".

chamons commented 4 years ago

As both of you can see by the lack of comments on this issue, there is no progress to report.

As this project is open source and community driven, PRs are welcome if you have interest.