RoboVM Binding Project

2,445 views
Skip to first unread message

blueri...@gmail.com

unread,
Sep 14, 2013, 8:32:55 PM9/14/13
to rob...@googlegroups.com
I have just created a working binding for MoPub, which includes AdMob, iAd, MMedia, InMobi, Chartboost, RevMob and other ads.

Now lets assume I have three RoboVM iOS projects and all should use MoPub.
How can I share the code of MoPub between all three projects?

Can I create a forth iOS "binding project" which contains the MoPub library and binding code and then link this binding project in my other three projects?
Is this a good idea or not? Or do you plan to create a new Eclipse binding project type?

Thanks in advance

Mario Zechner

unread,
Sep 15, 2013, 6:37:50 AM9/15/13
to rob...@googlegroups.com
I don't think a binding project is necessary. Link your MoPub project to your other three projects as usual. Then make sure the robovm.xml of each of the three projects also links to the native library in the MoPub project. You can use relative paths to specify the native library (which is awesome, thanks Niklas!)

blueri...@gmail.com

unread,
Sep 15, 2013, 1:34:15 PM9/15/13
to rob...@googlegroups.com
Thanks this works great!

I want to make my bindings public so everyone can profit from it but before I need to fix a small problem with my delegate binding.
I've created the following binding:

and I'm using it like this:

interstitial = MPInterstitialAdController.getAdController("xxxx");

interstitial.setDelegate(new MPInterstitialAdControllerDelegate.Adapter() {

@Override

public void didFailToLoadAd(MPInterstitialAdController interstitial) {

interstitial.loadAd();

}


@Override

public void didDisappear(MPInterstitialAdController interstitial) {

interstitial.loadAd();

}


@Override

public void didExpire(MPInterstitialAdController interstitial) {

interstitial.loadAd();

}

});


But those callback methods never get called! Is my binding faulty or how I use it? (just for reference: I've copied most of the UINavigationControllerDelegate in the RoboVM cocoatouch source for my binding)

Thanks!

Niklas Therning

unread,
Sep 16, 2013, 3:05:55 AM9/16/13
to blueri...@gmail.com, rob...@googlegroups.com
First of all, great work!

Does the app crash? Or nothing happens? The problem could be that your delegate gets GCed before it's being called. Delegate properties are usually weak in CocoaTouch so the controller doesn't retain the delegate. When the Java peer is GCed it will be released by the Java side and since the controller never retained it it will be deallocated on the ObjC side. In order to test if this is the problem you could assign your delegate to a static field in the current class. That should prevent it from ever being GCed.

The long term fix is to add a call in the setDelegate() method in the controller:

  this.addStrongRef(delegate)

this will create a strong reference from the controller instance to the delegate so that the delegate never gets GCed on the Java side before the controller is deallocated on the ObjC side.

I really need to document things like this...


--
You received this message because you are subscribed to the Google Groups "RoboVM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robovm+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

blueri...@gmail.com

unread,
Sep 16, 2013, 8:17:54 AM9/16/13
to rob...@googlegroups.com
Thank you. I've added addStrongRef to the setDelegate method but unfortunately it doesn't change anything. The delegate methods don't get called.

I also tried to directly create a new instance of the interface but this gives me the following error in my testing project "picwords":

Exception in thread "main" java.lang.ClassCastException: com.blueriver.picwords.RobovmLauncher$1 cannot be cast to org.robovm.objc.ObjCObject

at org.robovm.bindings.mopub.MPInterstitialAdController.setDelegate(MPInterstitialAdController.java)



I'm also getting another crash that only happens every second time I use my show method:

Exception in thread "main" java.lang.NoSuchMethodError: org.robovm.objc.block.VoidBlock$Marshaler.toObject(Ljava/lang/Class;JZ)Ljava/lang/Object;

at org.robovm.bindings.mopub.MPInterstitialAdController.objc_show(Native Method)

at org.robovm.bindings.mopub.MPInterstitialAdController.show(MPInterstitialAdController.java)


Sometimes the interstitial ad gets shown, sometimes it crashes with this error. Am I missing a specific marshaler annotation?


Please take a look at the binding code, I've made it now publicly visible: https://github.com/BlueRiverInteractive/robovm-ios-bindings

Thanks!

blueri...@gmail.com

unread,
Sep 21, 2013, 2:30:00 PM9/21/13
to rob...@googlegroups.com, blueri...@gmail.com
Hi Niklas,

You were right. The delegate seems to be GCed. I've added this.addStrongRef((ObjCObject) delegate); to the setDelegate method and also made my delegate a static field. Nevertheless, when I call getDelegate the return is always null. 
Other methods like setKeywords(String) and getKeywords() work without any problem. 

Can you image what is wrong?

Thanks!

Niklas Therning

unread,
Sep 30, 2013, 9:37:35 AM9/30/13
to blueri...@gmail.com, rob...@googlegroups.com
Hi,

I think I may have found one problem with your binding code. You're using the same delegate selector for both the getter and setter. It should be "delegate" for the getter and "setDelegate:" for the setter. What you're doing now is to essentially call the getter in setDelegate(). All your other properties have the same problem. The setter for a property foo is called "setFoo:" and the getter is called "foo" (unless the property has an explicit setter/getter name in the ObjC header file). See the getter/setter for the delegate property in UIWebView for an example: https://github.com/robovm/robovm/blob/master/cocoatouch/src/main/java/org/robovm/cocoatouch/uikit/UIWebView.java

blueri...@gmail.com

unread,
Oct 10, 2013, 4:35:23 PM10/10/13
to rob...@googlegroups.com
Thank you very much! This solved my problems of the delegate not being available!
Everything works great now, just run my Sample class if you want to try it: https://github.com/BlueRiverInteractive/robovm-ios-bindings/blob/master/mopub/src/org/robovm/bindings/mopub/Sample.java (I still have to update the other classes but Interstitials do work in this sample)

But I still get the following error when I use the show() method in an libgdx application. I've removed all functionality from the libgdx app and just run the same code as in the sample but it crashes:

Exception in thread "main" java.lang.NoSuchMethodError: org.robovm.objc.block.VoidBlock$Marshaler.toObject(Ljava/lang/Class;JZ)Ljava/lang/Object;

at org.robovm.bindings.mopub.MPInterstitialAdController.objc_show(Native Method)

at org.robovm.bindings.mopub.MPInterstitialAdController.show(MPInterstitialAdController.java)

at com.blueriver.game.RobovmLauncher$1.didLoadAd(RobovmLauncher.java)

at org.robovm.bindings.mopub.MPInterstitialAdControllerDelegate$Callbacks.didLoadAd(MPInterstitialAdControllerDelegate.java)

at org.robovm.cocoatouch.uikit.UIApplication.UIApplicationMain(Native Method)

at org.robovm.cocoatouch.uikit.UIApplication.main(UIApplication.java)

at com.blueriver.game.RobovmLauncher.main(RobovmLauncher.java)


What does this error mean and how can I solve it?


Am Sonntag, 15. September 2013 02:32:55 UTC+2 schrieb blueri...@gmail.com:

blueri...@gmail.com

unread,
Oct 10, 2013, 5:39:31 PM10/10/13
to rob...@googlegroups.com
Ok, I could nail down the problem. 
AdMob and MillennialMedia use a special type of UIViewController in conjunction with InterfaceBuilder. When used with a normal UIViewController (like in the Sample) everything works fine. But LibGdx is using OpenGLES Surface and a special GLKViewController. It seems that this combination doesn't work for RoboVM and results in a crash. 
I could image that this is because RoboVM still doesn't support all of OpenGL and InterfaceBuilder? I've tried a native iOS app with the same configuration and it works without any crash.

As a workaround for now, I'm using a second UIViewController just for those interstitials.


Am Sonntag, 15. September 2013 02:32:55 UTC+2 schrieb blueri...@gmail.com:

CremaGames Studios

unread,
Oct 15, 2013, 6:37:51 AM10/15/13
to rob...@googlegroups.com
I'm facing the same problem when making the bindings for AdColony (a video ad company). I'm getting the NoSuchMethodError on the playVideoAd method

Exception in thread "main" java.lang.NoSuchMethodError: org.robovm.objc.block.VoidBlock$Marshaler.toObject(Ljava/lang/Class;JZ)Ljava/lang/Object;

I can't use the workaround of creating a new UIViewController beacuse the AdColony SDK doesn't let you that option :/

Niklas Therning

unread,
Oct 19, 2013, 5:07:19 AM10/19/13
to CremaGames Studios, rob...@googlegroups.com
I need to see the bindings in order to figure out what's going on here. Can you put them online somewhere?


--

CremaGames Studios

unread,
Oct 19, 2013, 8:50:05 AM10/19/13
to rob...@googlegroups.com, CremaGames Studios
The AdColony bindings are included in BlueRiver project now, you can check it here: https://github.com/BlueRiverInteractive/robovm-ios-bindings

With a RoboVM project the code works OK, but with a LibGDX one it crashes with the error.

Niklas Therning

unread,
Oct 20, 2013, 5:29:28 AM10/20/13
to CremaGames Studios, rob...@googlegroups.com
Sounds weird that it works outside of libgdx. Which version of RoboVM are you using with libgdx?

Guillermo Andrades

unread,
Oct 20, 2013, 6:31:23 AM10/20/13
to rob...@googlegroups.com, CremaGames Studios
Latest nighltlies on both LibGDX and Robo.

The same error happens with AdMob when you try to show an intersitial or with MoPub or even with GameCenter when showing the login dialog. It seems that every time you (or a library) calls presentViewController the app crash and always with the same error. If you change the rootViewController to a new one the presentViewController works fine.

blueri...@gmail.com

unread,
Oct 20, 2013, 9:18:35 AM10/20/13
to rob...@googlegroups.com
I assume it has something to do with that libGDX uses a GKViewController instead of a normal UIViewController.


Am Sonntag, 15. September 2013 02:32:55 UTC+2 schrieb blueri...@gmail.com:

Niklas Therning

unread,
Oct 23, 2013, 12:13:58 PM10/23/13
to blueri...@gmail.com, rob...@googlegroups.com
You could be right. Maybe a way forward is to make the smallest possible app that uses GKViewController without involving libgdx and see if you can get it to work? Then we can see if we can find out how to fix the libgdx RoboVM backend.


--

Ficus Frenzy

unread,
Dec 15, 2013, 5:44:55 AM12/15/13
to rob...@googlegroups.com
Hi,

I get mopub's test banner visible, but when I click on banner the application crashes with exception:

Exception in thread "main" java.lang.NoSuchMethodError: org.robovm.objc.block.VoidBlock$Marshaler.toObject(Ljava/lang/Class;JZ)Ljava/lang/Object;

at org.robovm.cocoatouch.uikit.UIApplication.UIApplicationMain(Native Method)  

at org.robovm.cocoatouch.uikit.UIApplication.main(UIApplication.java)

at org.robovm.bindings.mopub.sample.Sample.main(Sample.java)


I'm using latest robovm and latest bindings from address above (no libgdx, just testing robovm and mopub bindings).
Has anyone managed to get this bindings to work.

Thanks.

Eric Nondahl

unread,
Dec 20, 2013, 10:04:27 AM12/20/13
to rob...@googlegroups.com
I am also seeing the VoidBlock trace when using UIViewController presentModalViewController:animated: inside a third party library, with libdx (if it matters.)


Exception in thread "main" java.lang.NoSuchMethodError: org.robovm.objc.block.VoidBlock$Marshaler.toObject(Ljava/lang/Class;JZ)Ljava/lang/Object;
at org.robovm.bindings.uservoice.UserVoice.objc_presentUserVoiceForum(Native Method)

Why is java trying to call a .toObject method that does not exist, according to the VoidBlock source? Anyone have a reliable workaround for this? or know the root cause of that VoidBlock trace?

Thanks

Eric Nondahl

unread,
Dec 20, 2013, 2:14:15 PM12/20/13
to rob...@googlegroups.com
I have found the cause of this issue, at least for me.

I took Niklas' suggestion and tried to create the simplest app that demonstrated the issue. Started with the generic robovm app from the doc. Added a GLKViewController as the root view controller and presented another VC. Surprisingly, no issues with the openGL view controllers like LibGDX uses, and presenting modally through the current robovm interface.

I then noticed that the SDK I was connecting was calling this deprecated method of UIViewController: presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated

When I make a simple RoboVM app that calls that deprecated method on iOS7, lo and behold, the stack trace:

Exception in thread "main" java.lang.NoSuchMethodError: org.robovm.objc.block.VoidBlock$Marshaler.toObject(Ljava/lang/Class;JZ)Ljava/lang/Object;

If you see this VoidBlock issue, I suggest checking for deprecated iOS method calls. It would be nice if the stack trace was a little bit less cryptic here, but I understand this is early developement :)

Eric Nondahl

unread,
Dec 20, 2013, 3:44:32 PM12/20/13
to rob...@googlegroups.com
I have to walk back my previous post a little. It seems that the situation is a bit more complicated. When I use the built-in robovm java UIViewController presentViewController(...) bridge method, it works fine. When an included static library calls the exact same objective c method, I am still seeing the VoidBlock trace.

blueri...@gmail.com

unread,
Dec 21, 2013, 7:42:37 PM12/21/13
to rob...@googlegroups.com
Seems like Marshaler.toObject() comes from marshalNativeToObject:
https://github.com/robovm/robovm/blob/2d415d32f008b782b9eebf44a0732a132aab8020/compiler/src/main/java/org/robovm/compiler/AbstractMethodCompiler.java

I think the problem is that if the void block completion parameter of UIVIewController.presentViewController() is NIL in a static library, RoboVM still tries to marshal that objc block to a java VoidBlock resulting in a crash.
Another possibility I can think of is that the void block is not NIL in the static library but gets deallocated before presentViewController is called.

Can you shed any light on this Niklas?

Niklas Therning

unread,
Dec 27, 2013, 1:57:04 AM12/27/13
to blueri...@gmail.com, rob...@googlegroups.com
Hi all, sorry for the late response. The NoSuchMethodError: org.robovm.objc.block.VoidBlock$Marshaler.toObject(...) exception means that a ObjC block is being marshaled from ObjC to Java. This is not supported in the current version of the ObjC-to-Java bridge, only the other way around (which is what the toNative() method does in VoidBlock.Marshaler).

When you subclass UIViewController or some other class in the CocoaTouch bindings that has a method that takes a VoidBlock as parameter any call to a method on that class (like presentViewController()) from the ObjC side will be routed through Java and the RoboVM Bro framework will try to marshal the ObjC block to a Java VoidBlock. This fails since there's currently no toObject(...) method that can marshal ObjC blocks to VoidBlocks.

I've added an issue for it here: https://github.com/robovm/robovm/issues/235



--

Hai Nguyen

unread,
Jan 7, 2014, 5:04:18 AM1/7/14
to rob...@googlegroups.com
How to send sms with recipients and body? I have used MFMessageComposeViewController but not set recipients :(

ASM

unread,
Oct 13, 2014, 5:16:48 AM10/13/14
to rob...@googlegroups.com
I'm using robovm to develop iOS game while using Java.

I'm trying to use Mopub's ios-robovm-bindings (https://github.com/BlueRiverInteractive/robovm-ios-bindings/tree/master/mopub) to integrate inmobi banner ads to my app but with no luck so far.

I keep getting this message:

Oct 12 22:00:59 Asafs-iPhone IOSLauncher[5113] <Warning>: MOPUB: Looking for custom event class named InMobiBannerCustomEvent.
Oct 12 22:00:59 Asafs-iPhone IOSLauncher[5113] <Warning>: MOPUB: Requesting InMobi banner
Oct 12 22:00:59 Asafs-iPhone IOSLauncher[5113] <Warning>: MOPUB: Failed to create an inMobi Banner with invalid size {7.1806318e-37, 5.9439283e-15}

I already made changes in Mopub's web UI by entering a CUSTOM EVENT CLASS and CUSTOM EVENT CLASS DATA with inmobi my "app_id".

Do you know what else am I missing ? 

in addition that bindings supposed to work on other networks as well (such as applovin, revmob and more) but i couldn't integrate them as well.

I would greatly appreciate any help in working this problem.


On Sunday, September 15, 2013 2:32:55 AM UTC+2, blueri...@gmail.com wrote:
Reply all
Reply to author
Forward
0 new messages