Pain When Binding Objective-C Types

wskwwskw USMember, Beta ✭✭

I've been doing some renovation on one of my first MonoTouch/iOS apps and I found some great UI stuff written in Obj-C on Github. Rather than port the code to C#, I figured that learning the binding process would be worth it so I could pull updated commits as bugs get fixed and new iOS versions are released.

First off, I have an appreciation for the amount of engineering work that was put into making this stuff all play nicely. I don't want to sound whiny here.

The binding process seems like it should be much easier. MonoTouch is pretty mature at this point.

In the "Binding Objective-C Libraries" (http://docs.xamarin.com/ios/Guides/Advanced_Topics/Binding_Objective-C_Libraries) document, no mention is made that there is a tool to generate a most-of-the-way-there ApiDefinition.cs file automatically (https://github.com/stampsy/monotouch-binding-generator). Honestly though, even with writing the ApiDefinition.cs file by hand it was only a fraction of the time spent.

Most of the UI "libraries" I've found on Github are just Xcode projects with .h and .m files. They need to be compiled into Cocoa touch static libraries in Xcode (.a files) to be bound properly. There should be some mention of this process and its pitfalls in the documentation, like the non-default the behavior of generating a Universal library for ARM and x86 architectures (A "Universal" Xcode Project Template can be found at https://github.com/michaeltyson/iOS-Universal-Library-Template).

Creating a MonoTouch Binding Project is equally frustrating. When choosing "Add Files" and selecting the .a file, the libWhatever.linkwith.cs file auto-detects the supported architectures (shown in the "assembly: LinkWith" attribute). That is the first indication that my static library was built without x86 support.

Attempting to remove and re-add a recompiled .a file within the MonoTouch Binding Project has issues. The generated .dll would not work in my application some of the time. "Duplicate symbol" errors would randomly appear or disappear between builds. I had to ritually Clean and Rebuild after updating the .a references. I'd also have to close and re-open MonoDevelop because of some phantom libWhatever.linkwith.cs files appearing as missing (in red) but were not removable from the project.

So, here are some recommendations:

Why not explain to your (potentially inexperienced Obj-C / Xcode) users about creating static libraries. Including a Universal Architecture Xcode Project Template would be a good idea. Allowing the user to choose some header/method files and creating the static lib automatically would be even better.

Couldn't the automatic binding generator stuff be wrapped into MonoDevelop itself?

Basically, it would be great to reduce the number of manual steps required to create (and more importantly) update a bound library for use.

It would be a really nice selling point to future customers to show how easy it is to use Objective-C code and integrate it into their projects. Download repo / compile correct static lib / auto-generate (most) of the ApiDefinition / some manual cleanup of ApiDefinition.cs / reference in project.

Thanks for reading :)

Posts

  • MigueldeIcazaMigueldeIcaza USXamarin Team Xamurai

    Thanks for the feedback. We will look into improving both the tools and the documentation to avoid the pitfalls.

    The problem with the tool you found (parse.exe from monomac/src and the fork that you found on stampsy/monotouch-binding-generator) is that it is not reliable. It is merely a helper tool that gets some of the tedious work done, but the output is incorrect, it requires a human editor to adjust and review.

    It is really a quick and dirty tool, which in the hands of seasoned binders can be very useful, but would be very confusing to new users, which would also, very likely, produce incorrect bindings.

  • JoshJosh USMember, Beta

    I would like to "second" everything that Will said above. I've created a couple of MonoTouch bindings to custom UI controls on github and had some difficulties myself. I have found that I sometimes need to modify the Objective C code in the library I am binding to in order for it to work properly, which defeats the purpose of binding. I'm sure if I had all the tribal knowledge about how to troubleshoot bindings that are crashing I could have avoided this. Perhaps if there were a document that had common problems observed at runtime with MT bindings it could give suggestions as to likely causes?

    Case in point: creating a MT binding to MBAlertView I used the same parser that Will referenced above. I was well aware that the bindings it generated aren't perfect. Anywhere where an objective C block was exposed I had to manually adjust that, but Xamarin documentation on how to do that was easy to follow in "Binding Objective-C Libraries".

    However, I found that when I passed C# delegates to the objective C code to function as callbacks for alert button taps, I got sigsegv crashes. I confirmed that everything worked perfectly when I invoked it from Objective C code.

    I spent time looking at the MT documentation on bindings trying to figure out what to do. Perhaps there was a solution there that I missed. I ended up adding NSLogs all over the place in MBAlertView source to try to track down the problem.

    I was eventually able to get a hacked up version of MBAlertView working. By the time I had hacked it up so badly I felt like I should have converted the whole thing to C#. However if there were a nice troubleshooting guide for MonoTouch bindings I might have been able to modify bindings and not hacked the source.

    If you have any insights into the particulars of my problem, it would be greatly appreciated. I have attached my MT solution including libMBAlertView.a file (built and lipo'd with i386, armv7 and armv7s). It is the non hacked up version of MBAlertView that fails.

    Thanks,

    Josh

  • AlexSotoAlexSoto MXXamarin Team Xamurai
    edited February 2013

    Hello @Josh.

    First of all, thanks a lot for all your feedback it helps us to improve.

    I binded MBAlertView and now you can find it here. about modifying Objective-C source you are right mosts of Objective-C libs out there should work out of the box with our tooling but due to the nature of Objective-C (weakly typed) sometimes this is not true.

    The problem you had binding Objective-C blocks its due to the developer its not following the standard pattern when using blocks so just as you I had to manually tweak the library just a bit (2 blocks declarations to be precise)

    Developer is using block:(id)block instead of block:(void (^)())block so with this minor change the library is now working as expected.

    Thank you again and Happy Coding!!

    Alex

  • JoshJosh USMember, Beta

    Alex,

    Thanks so much for your help.

    Like I said, I'd love to see a "Troubleshooting MonoTouch Bindings" page that describes common pitfalls like this. I'm sure that a large percentage of the time people create custom bindings it is to use projects they found on GitHub that may or may not have been coded perfectly to Objective C standards but still execute in the Objective C world.

    Such a document might have saved me many hours of time.

    Anyway, thanks again for you help I really do appreciate it.

    Josh

  • wskwwskw USMember, Beta ✭✭

    You guys should just buy this and integrate it into Xamarin Studio:

    http://www.razum.si/automagical/

  • vbelletvbellet USMember, Beta ✭✭

    I couldn't agree more with this post, Indeed in my opinion it's one of the most annoying drawback of using Xamarin ... indeed there is a bunch of components out there (http://www.cocoacontrols.com/controls) that take time and complexity to bind in C#.

    Anything that could help even if it's not the whole process would be great.

    The Xamarin component store tend to help here but as far as I see it, it will never replace a simple and coherent tool to do it yourself unless the Xamarin community is able to add to the components to the store without even knowing the author. is that possible ?

Sign In or Register to comment.