Recent iOS plugin tutorial -- something missing

First of all thanks for the tutorial on how to build a simple iOS plugin, Rob Miracle.  I have a bit of point of confusion. If I wanted to “render” loosely a view on top of the corona canvas, rather than just passing a message to Corona, how would that be done?

For example, I have tried to to simply add my own viewController and that does not seem to do anything.  Any ideas?

I managed to pop a view for an iTunes Picker (because the one included with Corona Plugins is buggy) :

static int showPicker( lua\_State \*L ) { myMusicPlayer = NULL; void \*platformContext = CoronaLuaGetContext( L ); id\<CoronaRuntime\> runtime = (id\<CoronaRuntime\>)platformContext; UIViewController \*root = runtime.appViewController; // Création du média picker myController \*c = [[myController alloc] init]; [c setRuntime:runtime]; if (CoronaLuaIsListener( L, 1, "mediaPicker" )) { [c setListener:CoronaLuaNewRef( L, 1 )]; } else { [c setListener:NULL]; } [root.view addSubview:c.view]; [c showNativePicker]; return 0; }

Interesting, do you mind if I ask some questions?  Maybe the fog in front of my eyes will lift a bit.

1 - id<CoronaRuntime> runtime = (id<CoronaRuntime>)platformContext;  should mean (in C++) create an id template class object ready to store a CoronaRuntime type, call it runtime and assign the value pointed by platformContext (after casting it into an id<CoronaRuntime> type).  Am I bonkers?  

2 - is platformContext a pointer to a void?  Why?

3 - I am not aware of setListener, setRuntime, showNativePicker. I admit I am not much of a Cocoa person, but what are those?

Paolo, I’m not a Cocoa developer too, I just find a sample code on the Internet (how to display an itunes picker) and adapt it to Corona. For example, I needed a UIViewController to call addSubview, so I dug in some Corona Enterprise samples and find the code to get the context, to get the runtime, to get the root view… Yes, the context is a void pointer, it means it has no type and I don’t know (and don’t care :)) why, it was part of the sample I copy/pasted. For the listener, it was part of a Corona sample too, it allows to register and call a callback (the Lua function is passed to the native showPicker function as the 1st parameter, this is why the code use 1 as the index).

Deconstructing your solution: the part for getting the to the Corona root view (and therefore allowing adding subviews) definitely works and here it is in isolation.  You only need to remember to include CoronaRuntime header via #import “CoronaRuntime.h”.

void \*platformContext = CoronaLuaGetContext( L ); id\<CoronaRuntime\> runtime = (id\<CoronaRuntime\>)platformContext; UIViewController \*root = runtime.appViewController;

So that’s that for a view controller.  I have also found that, using Objective C you can find the top most controller in your hierarchy and present your own view controller to that.  That works too but I prefer what you came up with on the basis that hopefully you are getting the correct view controller at all times, irrespective of what happens in the underlying Corona app.  

For the three methods mentioned (setListener, setRuntime, showNativePicker), they are not methods in the class UIViewController (and in fact my XCode gives me a nice red blob and insults me in 3 languages).  They would not even compile so I was wondering if they work in your case and how comes.  You might have added those methods to UIViewController class somehow?

I just have this imports:

#import "AppCoronaDelegate.h" #import "CoronaRuntime.h" #import "CoronaLua.h" #import "mediapicker.h" #import \<AVFoundation/AVPlayer.h\>

I still get a warning that those three methods do no exist in my UIViewController.  Go figure.

Haaaa OK sorry!!

These are mine, from the myController class, which will create/open the mediaplayer and get the messages. There methods are storing references to the runtime and the Lua call back function to call when the user select a song in the media player picker.

I believe you need to adapt this to your need (I don’t know what kind of view you need to create). If there is no callback/messages to get, I believe you can just ignore these lines.

Ok so from the LUA side you add a Runtime listener called “XYZ” and you can check that the listener exists on the native side.  Great, therefore all that is missing is how to pass a message to the listener (some sort of position 1 on the LUA stack).  But I believe that that part is covered in the generic plugin template that was used in the tutorial.  I haven’t checked.  Ok so this is helpful.  

All I need to figure out is how to store reference to the view I create outside the method “::show()” in the corona plugin project.  That is because I want to implement hide and destroy methods as well as several show methods that show ads in different positions.  I might be able to edit the class variables to store a pointer to the view.  At least there is some sort of progress.

Very helpful thanks.

I managed to pop a view for an iTunes Picker (because the one included with Corona Plugins is buggy) :

static int showPicker( lua\_State \*L ) { myMusicPlayer = NULL; void \*platformContext = CoronaLuaGetContext( L ); id\<CoronaRuntime\> runtime = (id\<CoronaRuntime\>)platformContext; UIViewController \*root = runtime.appViewController; // Création du média picker myController \*c = [[myController alloc] init]; [c setRuntime:runtime]; if (CoronaLuaIsListener( L, 1, "mediaPicker" )) { [c setListener:CoronaLuaNewRef( L, 1 )]; } else { [c setListener:NULL]; } [root.view addSubview:c.view]; [c showNativePicker]; return 0; }

Interesting, do you mind if I ask some questions?  Maybe the fog in front of my eyes will lift a bit.

1 - id<CoronaRuntime> runtime = (id<CoronaRuntime>)platformContext;  should mean (in C++) create an id template class object ready to store a CoronaRuntime type, call it runtime and assign the value pointed by platformContext (after casting it into an id<CoronaRuntime> type).  Am I bonkers?  

2 - is platformContext a pointer to a void?  Why?

3 - I am not aware of setListener, setRuntime, showNativePicker. I admit I am not much of a Cocoa person, but what are those?

Paolo, I’m not a Cocoa developer too, I just find a sample code on the Internet (how to display an itunes picker) and adapt it to Corona. For example, I needed a UIViewController to call addSubview, so I dug in some Corona Enterprise samples and find the code to get the context, to get the runtime, to get the root view… Yes, the context is a void pointer, it means it has no type and I don’t know (and don’t care :)) why, it was part of the sample I copy/pasted. For the listener, it was part of a Corona sample too, it allows to register and call a callback (the Lua function is passed to the native showPicker function as the 1st parameter, this is why the code use 1 as the index).

Deconstructing your solution: the part for getting the to the Corona root view (and therefore allowing adding subviews) definitely works and here it is in isolation.  You only need to remember to include CoronaRuntime header via #import “CoronaRuntime.h”.

void \*platformContext = CoronaLuaGetContext( L ); id\<CoronaRuntime\> runtime = (id\<CoronaRuntime\>)platformContext; UIViewController \*root = runtime.appViewController;

So that’s that for a view controller.  I have also found that, using Objective C you can find the top most controller in your hierarchy and present your own view controller to that.  That works too but I prefer what you came up with on the basis that hopefully you are getting the correct view controller at all times, irrespective of what happens in the underlying Corona app.  

For the three methods mentioned (setListener, setRuntime, showNativePicker), they are not methods in the class UIViewController (and in fact my XCode gives me a nice red blob and insults me in 3 languages).  They would not even compile so I was wondering if they work in your case and how comes.  You might have added those methods to UIViewController class somehow?

I just have this imports:

#import "AppCoronaDelegate.h" #import "CoronaRuntime.h" #import "CoronaLua.h" #import "mediapicker.h" #import \<AVFoundation/AVPlayer.h\>

I still get a warning that those three methods do no exist in my UIViewController.  Go figure.

Haaaa OK sorry!!

These are mine, from the myController class, which will create/open the mediaplayer and get the messages. There methods are storing references to the runtime and the Lua call back function to call when the user select a song in the media player picker.

I believe you need to adapt this to your need (I don’t know what kind of view you need to create). If there is no callback/messages to get, I believe you can just ignore these lines.

Ok so from the LUA side you add a Runtime listener called “XYZ” and you can check that the listener exists on the native side.  Great, therefore all that is missing is how to pass a message to the listener (some sort of position 1 on the LUA stack).  But I believe that that part is covered in the generic plugin template that was used in the tutorial.  I haven’t checked.  Ok so this is helpful.  

All I need to figure out is how to store reference to the view I create outside the method “::show()” in the corona plugin project.  That is because I want to implement hide and destroy methods as well as several show methods that show ads in different positions.  I might be able to edit the class variables to store a pointer to the view.  At least there is some sort of progress.

Very helpful thanks.