Cocos2D-X is a cross platform game development framework that runs on iOS, Android and other devices. But even we can do anything related to a game with cocos, we will sometimes need to get access to platform specific APIs, like Facebook SDK, Admob or iAds.
In those cases we will need to implement those features using the device native language (Objective-C for iPhone or Java for Android). And while Cocos2D-X is a great engine, it lacks of tutorials... so today I am going to talk on how to communicate Objective-C with C++.
The process should be easy. As an example, I'll show a native iOS alert message from Cocos2D-X. In order to do this, follow these steps:
- Create a cpp file and a .h file. Call them iOsHelper.cpp and iOsHelper.h. These will be our bridge to Objective-C.
- An important detail: Click the iOsHelper.cpp file and in the "Identity and type" window on Xcode (normally at the top right of the screen), choose Objective C++ source as the type.
- Define the body of the h and the cpp files. It will be:
#import "iOSHelper.h"
#import "iOSHelper_objc.h"
namespace iOSBridge{
void iOSHelper::ShowAlert()
{
[iOSHelper_objc ShowAlert];
}
}
and
#ifndef FightNow_iOSHelper_h
#define FightNow_iOSHelper_h
namespace iOSBridge{
class iOSHelper {
public:
void ShowAlert();
};
}
#endif
- Now create an Objective-C class called iOSHelper_objc
@interface iOSHelper_objc : NSObject
+(void) ShowAlert;
@end
and
#import "iOSHelper_objc.h"
@implementation iOSHelper_objc
+(void) ShowAlert{
UIAlertView *alertDialog;
alertDialog = [[UIAlertView alloc]
initWithTitle:@"You!"
message:@"I know what you did!"
delegate:nil
cancelButtonTitle: @"OK"
otherButtonTitles: nil];
[alertDialog show];
[alertDialog release];
}
@end
Note that what we are doing is call the Objective-C function from a C++ class. This C++ class can be called from any of our Cocos2DX scenes for instance, so we are done :-)
As commented below (thanks guys for the comments) we need to instance the iOs "bridge" from our C++ class. One way to do it is the following:
Type* instanceName = [Type new];
[instanceName methodName:parameter];
[instanceName release];
As commented below (thanks guys for the comments) we need to instance the iOs "bridge" from our C++ class. One way to do it is the following:
Type* instanceName = [Type new];
[instanceName methodName:parameter];
[instanceName release];
Now you would probably want to handle what was the option chosen by the user right? In order to do this you might use callbacks, you can find a post about them in my colleague Xavier's blog post :-)
Hey, feel free to follow me on twitter if you are interested on discussing about Cocos2DX and game development :-) @jboschaiguade
This is very useful, I already know how to use C++ combined with Java(through JNI) and now with this part I can connect with Objc, thanks.
ReplyDeleteglad to hear it helped. Information about how to implement callbacks from objective-c to c++ again is missing, but might write about it in the near future.
ReplyDeleteI don't know anything about JNI yet... would be cool to learn about it.
Hello Jesús Bosch. I have a project in cocos2d-x and I wanna connect to facebook and twitter and post my score on my wall. But I don't know how to do it ! Can you share me some solution ?? Thank a lot
DeleteOne thing, you forget to say how we can call this ShowAlert from a Cocos2d-x file, like for a Scene, for example:
ReplyDeleteiOSBridge::iOSHelper::ShowAlert();
How I can call this ShowAlert using the HelloWorld template of Cocos2d-x for Xcode
To be able to call the ShowAlert() method from the iOSHelper class you need an instance of it (since method is non-static).
ReplyDeleteBut how I can call a static method?
ReplyDeletetry to avoid static methods if possible, or you don't have good reasons to use them. The article is updated and shows how to create the instance.
DeleteJB
Hello Jesus , i'm having a problem with environment when i add this class , the problem is with the class iOSHelper_objc , because when you create automaticly the xcode import the Foundation.h , when its compiled i received a lot of errors in classes of cocos2dx , like NsString and others.
ReplyDeleteWhem i comment the Import of FOundation , start to give me errors about syntax of the class iOSHelper_objc
Do you have some problem like this? i made a search about the error , a lot of people have some simillar error , but dont resolved.
Thanks!
Jesus, very good blog post. Easy to read and it works :) I was wondering if you could help me make a modification to it? ShowAlert in iOSHelper_objc is class method. What if I wanted to a invoke an instance method? Is this possible?
ReplyDeleteGustavo, have both non-header files end with .mm. Solves the problem :)
ReplyDeleteAm trying to invoke the helper from game scene with this code
ReplyDeleteiosHelper::showNetworkAlert;
am getting error as "Call to non-sttic member function without an object argument"
kindly help
Charanya - this is what I used to make it work.
ReplyDeleteiOSBridge::iOSHelper * bridge = new iOSBridge::iOSHelper();
bridge->ShowAlert();
very useful !!!
ReplyDeletethanks a lot ^^