Loading view controller class and/or storyboard from static library

663 views
Skip to first unread message

Alex Itelman

unread,
Jun 14, 2015, 11:29:45 AM6/14/15
to rob...@googlegroups.com
Hi,

I'm trying to put my storyboard and/or view controller in objective-c static library and use it in my robovm app instead of the default storyboard.
I changed the storyboard name in the Info.plist.xml and I've added the static library to my robovm project and listed it in the robovm.xml under libs.
Also, other functions of my static library are working.
But the storyboard fails to load, and when I try to copy the storyboard to the robovm project and just leave the view controller in the library then it fails to find the view controller class with this error:
Unknown class MyViewController in Interface Builder file.
I've tried to add the storyboard and the view controller files to the Copy Files phase of the library, but it didn't help.

How can I make robovm find the view controller and/or the storyboard?

Thanks,
Alex.

Alex Itelman

unread,
Jun 15, 2015, 4:12:21 PM6/15/15
to rob...@googlegroups.com
I got it to work.
This way we have a totally native UI (storyboard + controller) with callbacks to our common BL java library passed to the ios side using Bro wrappers.
Without any hacks to robovm..
If anyone else is interested in using robovm this way, I can explain what we did in more detail.

Christopher Graham

unread,
Jun 15, 2015, 9:12:32 PM6/15/15
to rob...@googlegroups.com
I'd like to know more about your approach, Alex.

Alex Itelman

unread,
Jun 16, 2015, 1:56:38 AM6/16/15
to rob...@googlegroups.com
Glad you asked.

So, our main concern with using robovm to develop our iOS app was that the UI layer would have to be developed in java, and although robovm wraps the main iOS APIs, still there are stuff that you cannot do, and more importantly, if we want a truly experienced high-level iOS GUI developer to join our team, he wouldn't want to code in java and the java environment.

So what we did is:

High level:

1. Create an ios static lib containing our view controller storyboard, write all the UI logic in it.
2. Use the lib in the robovm project and pass it an API class containing callback functions to our java lib.
3. Create an ios app that also uses the same lib for quick and independant UI development, and pass the lib a mock of the API class.


In detail:

1. Create a normal robovm iOS app project
2. Create a static library project in Xcode: MyLib
3. Import the storyboard from the robovm project to MyLib (not copy, just reference, using Add Files to..)
4. Create a ViewController header and source files in MyLib, and link it to the storyboard in xcode.
5. Create an obj-c (or c++ would also be possible I guess) interface in MyLib, call it MyInterface, for example:

MyInterface.h:

@interface MyInterface : NSObject
@end

MyInterface.mm:

@implementation MyInterface : NSobject
@end

6. Define all callbacks types that you need in your api as blocks (or function pointers if you prefer), for example:

typedef UInt32 (^MyCallback(NSString * param));

7. Add a method that sets the callback in the interface (if you plan to have many callbacks you'll probably want to wrap the all in your own custom api class, and pass them all together, but lets keep it simple here), for example:

MyInterface.h:

+(void) SetMyCallback: (MyCallback) callback;

MyInterface.mm:

static MyCallback mCallback;

@implementation MyInterface : NSobject

+(void) SetMyCallback: (MyCallback) callback {
mCallback = callback;
}

@end

Also add a GetMyCallback method to the interface in a similar way.

8. In the robovm app create a wrapper class (using Bro) for your interface:

@NativeClass
public class MyInterface extends NSObject {
public static interface MyJavaCallback {
int javaCallback(String param);
}

@Method(selector = "SetMyCallback:")
private static native void nativeSetMyCallback(@Block Block1<String, Integer> callback);

public static void setMyCallback(final MyJavaCallback callback){
nativeSetMyCallback( new Block1<String, Integer>() {
@Override
public Integer invoke(String param){
return callback.javaCallback(param);
}
});
}
}

9. In the robovm app in Main.java, in the main method, before the call to UIApplication, add the intialization of the callback:

MyInterface.setMyCallback( ... );

10. In the ios view controller use the callback, for example:

ViewController.mm:

-(void) buttonClicked {
...
UInt32 result = [MyInterface GetMyCallback](@"param value");
...
}

11. Compile the static lib and put the output libMyLib.a in a libs folder in your robovm project (manually or with an automated script..).

12. In robovm.xml under add
<libs>
<lib>libs/libMyLib.a<lib>
</libs>

That's pretty much the basics..
Of course there's some more work to be done like:
If you want to pass more complex data structures between obj-c and java you'll need to wrap them using Bro.
If you're using any Frameworks in your lib you need to add them to your robovm.xml under <frameworks>
If you want to create an ios mock app that uses your static library you'll need to also import the storyboard into that, what we did is put the entire lib xcode project inside the mock app xcode project, that way when we build, they are both built. We had to do some magic in the project settings for it to work, but there are guides online for that, we just followed one.

If you're having trouble feel free to ask me anything.

Christopher Graham

unread,
Jun 16, 2015, 12:08:16 PM6/16/15
to rob...@googlegroups.com
A great explanation, thank-you.
Reply all
Reply to author
Forward
0 new messages