Corona Enterprise — iOS

The following resources go further in depth on using Corona Enterprise for iOS.

Getting Started

If you don't already have a native iOS development environment set up, please begin with the iOS Setup guide. This walks you through setting up a native development environment that's designed to work with Corona Enterprise.

In addition, we include a series of sample projects bundled with the Corona Enterprise download. Please inspect the extensive comments in the sample code to get started quickly.

Project Structure

To better understand how a Corona Enterprise for iOS project fits together, please review the Project Structure guide.

Development

Bridging Lua/C

To bridge Lua and C code, you'll use functionality made available by the Lua C API. This allows you to add libraries and functions in Lua that call directly into C.

Every function in the Lua C API takes the lua_State pointer L as its first argument. You can get access to the proper lua_State variable via an instance of the CoronaRuntime.

In order to use the Lua C API successfully, you must understand the Lua stack. This stack is different from a function call stack; it is designed to ease the marshalling of data across the Lua-C bridge. See here for more information.

Native APIs

The following are specific to Corona Enterprise for iOS:

  • CoronaDelegate — Your code must implement this protocol if you wish to add your own functions at the Lua layer. You can also intercept UIApplicationDelegate events via your implementation of this protocol.

  • CoronaRuntime — Key objects including the Lua state used by the Corona engine are accessible via this protocol. The Corona engine gives you access to this via the CoronaDelegate.

  • CoronaLuaIOS.h — Contains additional functions to help you bridge between Lua and native Obj-C code. This is meant to complement the set of cross-platform functions in CoronaLua.h.

  • Corona C Functions — This is a collection of C functions offered by the Corona engine which help you interact with Lua for Corona-specific patterns such as dispatching events.

Setting Orientation

To restrict Corona to specific orientations when using Corona Enterprise on iOS, you can use the orientation table in your project's build.settings. See Project Build Settings for more details.

Alternatively, you can edit the Info.plist file (App-Info.plist in the template app) and add a CoronaViewSupportedInterfaceOrientations array with options similar to UISupportedInterfaceOrientations. For example, to enable all orientations:

<key>CoronaViewSupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>

Sending Events to Runtime

All events in Corona are Lua tables. To make sending events to the global Runtime object, we've added a convenience utility function in CoronaLua.h called RuntimeDispatchEvent.

In the following Lua code, we create a custom event of type "delegate". In order for Corona to recognize the event as a Lua table, the name property of the Lua table must be set to the type of event:

local event = { name="delegate" }
Runtime:dispatchEvent( event )

We then translate this call into native code and send the event in the didLoadMain: method of CoronaDelegate:

@implementation MyCoronaDelegate

- (void)didLoadMain:(id<CoronaRuntime>)runtime
{
    lua_State *L = runtime.L;

    // DISPATCH CUSTOM EVENT
    // Create 'delegate' event
    const char kNameKey[] = "name";
    const char kValueKey[] = "delegate";
    lua_newtable( L );
    lua_pushstring( L, kValueKey );     // All events are Lua tables
    lua_setfield( L, -2, kNameKey );    // that have a 'name' property

    Corona::Lua::RuntimeDispatchEvent( L, -1 );
}

@end

Registering Custom Libraries

If you want to add your own library in Lua that wraps native C code, you should follow the standard Lua conventions as described in the Native C section of the Plugins guide.

Custom Lua Error Handling

You can register a custom Lua error handler by calling Corona::Lua::SetErrorHandler(). Your handler will override Corona's internal default error handler and it will be called any time a Lua error occurs at runtime.

static int MyTraceback( lua_State *L )
{
    lua_getfield(L, LUA_GLOBALSINDEX, "debug");
    if (!lua_istable(L, -1)) {
        lua_pop(L, 1);
        return 1;
    }
    lua_getfield(L, -1, "traceback");
    if (!lua_isfunction(L, -1)) {
        lua_pop(L, 2);
        return 1;
    }
    lua_pushvalue(L, 1);  // pass error message
    lua_pushinteger(L, 1);  // skip this function and traceback
    lua_call(L, 2, 1);  // call debug.traceback

    // Log result of calling debug.traceback()
    NSLog( @"[LUA ERROR]: %s", lua_tostring( L, -1 ) );

    return 1;
}

@implementation MyCoronaDelegate
- (void)willLoadMain:(id<CoronaRuntime>)runtime
{
    Corona::Lua::SetErrorHandler( MyTraceback );
}
@end

OpenGL Context Mismatch

Many third-party graphics libraries that use OpenGL will use their own OpenGL context. However, Corona performs its rendering on the main thread and does not expect the OpenGL context to change. Consequently, if you use certain graphics libraries, you may be inadvertently changing the OpenGL context which may cause issues with Corona rendering/updating properly.

To ensure your code is dealing with OpenGL properly, you should ensure that the OpenGL context changes are "balanced" as follows:

// 1. Save Corona's context
EAGLContext *context = nil;
context = [EAGLContext currentContext];

// 2. Call third-party library

// 3. Restore Corona's context
[EAGLContext setCurrentContext:context];

For example, if the interface for the third-party library is shown via a modal view controller, you would perform steps 1 and 2 in the presentViewController:animated:completion: call and then perform step 3 in the dismissViewControllerAnimated:completion: call.

Building for Devices

To build a Corona Enterprise project from Xcode, please follow Apple's guidelines here.