OpenAphid-Engine 0.2 was shipped with a new binding system which can bridge JavaScript functions to Objective-C methods on demand. It’s useful for games to integrate analytics services, monetization solutions, and social services, etc. In this tutorial, we’ll go through the binding system by demonstrating how to integrate Google Analytics iOS SDK into OpenAphid-Engine.
How to Access Objective-C Methods in JavaScript
The OABindingProtocol
protocol, defined in OABindingProtocol.h, defines a method bindSelectors:
that you can implement in your Objective-C classes to expose their methods to the JavaScript environment. To make a method valid for export, its return type and all argument types must be the supported types below:
Type Conversion of Return Value from Objective-C to JavaScript
Objective-C | JavaScript |
---|---|
void | undefined |
nil or NSNull | null |
primitive numeric types (int, float, double, etc) | number |
NSNumber | number |
NSString | string |
NSArray | array |
NSDictionary | object |
Type Conversion of Argument Value from JavaScript to Objective-C
JavaScript | Objective-C |
---|---|
undefined | nil or NSNull |
null | nil or NSNull |
number | primitive number or NSNumber |
string | NSString |
array | NSArray |
object except array | NSDictionary |
For any method to export, it must be explicitly declared in the implementation of bindSelectors:
in your Objective-C class. For example, the snippet below exports [DatastoreBinding saveString:]
to JavaScript environment as int saveString(string)
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#import "OABindingProtocol"
@interface DatastoreBinding : NSObject <OABindingProtocol>
@end
@implementation DatastoreBinding
- (BOOL) saveString:(NSString*)content
{
[_myDatastore save:content];
}
#pragma OABindingProtocol
- (void) bindSelectors:(OABindingMap*)bindingMap
{
[bindingMap bindSelector:@selector(saveString:) forName:@"saveString"];
}
@end
The binding object need be injected into JavaScript via setScriptBinding:name:iOSOnly:
method of OAGLViewController:
1
2
3
4
5
6
7
8
9
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//...
[self.viewController.glViewController setScriptBinding:[[[DatastoreBinding alloc] init] autorelease]
name:@"datastore"
iOSOnly:YES
];
//...
}
OpenAphid-Engine injects an instance of DatastoreBinding
as a JavaScript object of [object DynamicBinding]
into JavaScript environment. And its name is datastore
. The iOSOnly
argument manages the namespace which contains the injected object. If it’s YES
, then the injected object can be accessed via aphid.extios.datastore
; otherwise it can be accessed via aphid.ext.datastore
.
Notes: the
iOSOnly
argument is actually designed for future compliance when OpenAphid-Engine supports both iOS and Android.
Integration with Google Analytics in Boilerplate-iOS
Let’s see a more concrete example about integrating Google Analytics in Boilerplate-iOS.
After adding Google Analytics iOS SDK into the Xcode project by following its official instructions. We create an Objective-C object to describe the binding in OAGoogleAnalyticsBinding.h:
1
2
@interface OAGoogleAnalyticsBinding : NSObject <OABindingProtocol>
@end
Then we add implementations of several methods in OAGoogleAnalyticsBinding.m that we want to invoke in JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@implementation OAGoogleAnalyticsBinding
//...
- (void) startTrackerWithAccountID:(NSString*)accountID despatchPeriod:(int)period
{
[[GANTracker sharedTracker] startTrackerWithAccountID:accountID dispatchPeriod:period delegate:nil];
}
- (BOOL)trackPageview:(NSString *)pageURL
{
return [[GANTracker sharedTracker] trackPageview:pageURL withError:NULL];
}
//...
The binding of the methods should be declared in the bindSelectors:
method:
1
2
3
4
5
6
7
8
9
10
11
12
- (void)bindSelectors:(OABindingMap *)bindingMap
{
[bindingMap bindSelector:@selector(startTrackerWithAccountID:despatchPeriod:)
forName:@"startTracker"];
//...
[bindingMap bindSelector:@selector(trackPageview:)
forName:@"trackPageView"];
//...
}
Then we can inject it into JavaScript as following code inside OAAppDelegate.m:
1
2
3
4
5
6
7
8
9
10
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//...
[self.viewController.glViewController setScriptBinding:[[OAGoogleAnalyticsBinding new] autorelease]
name:@"gat"
iOSOnly:NO];
//...
}
** Updates at 07-09-2012: **
iOSOnly
has been changed fromYES
toNO
to match its Android version.
Now we can use Google Analytics in JavaScript to track the user’s behavior in games:
1
2
3
var gat = aphid.ext.gat; //Google Analytics is injected as aphid.ext.gat
gat.startTracker("UA-31741840-1", 10); //start a tracker
gat.trackPageView("main.js"); //track a page view
** Updates at 07-09-2012: ** Since
iOSOnly
has been set toNO
, the JavaScript namespace forgat
is switched toaphid.ext
fromaphid.extios
We’re going to integrate more services into Boilerplate-iOS, and make it be a better starter kit for game development with OpenAphid-Engine.
If you have better ideas, please feel free to contact us via openaphid@gmail.com
or raise an issue in our github repositories.