Adding (Objective-C) code to my game

Adding (Objective-C) code to my game
0

#1

does any one know how I could add Amazon Mobile Ads SDK to my app ? they use cocoapods for iOS, but im not sure how to go about doing this or where to implement the objective-c code (They don’t have a c++ SDK) would it be in the AppController files or RootViewController?


#2

The easy way to implement Obj-C code is add cpp header and obj-c code files:
Amazon.h:

class Amazon {
public:
//1!
bool someAmazonMethod(bool someParam);

//2!
bool someComplexMethod(int someParam);

//3!
void someMethodWithObjCBlock();
void setSomeCallback(const std::function<void(void)> &callback);
private:
//3!
std::function<void(void)> m_callback;
};

and Amazon.mm

#include "Amazon.h"
#import "Some Obj-C framework.h"

//2!
@interface objcHelper: NSObject  {
    
}
+(objcHelper*)sharedInstance;
+(void)dispose;
-(BOOL)someMethod(int someParam);

@end

@implementation objcHelper

static objcHelper* m_objcHelper = nil;

+(objcHelper*)sharedInstance {
    if (nil == m_objcHelper) {
        m_objcHelper = [[objcHelper alloc] init];
    }
    return m_objcHelper;
}

+(void)dispose {
    [[objcHelper sharedInstance] removeObserver];
}

-(BOOL)someMethod(int someParam) {
   return [someFramework someMethod: someParam];
}

@end

Amazon::Amazon():m_callback(nullptr) {

}

Amazon::~Amazon() {
  [objcHelper dispose];
}

//1!
bool Amazon::someAmazonMethod(bool someParam) {
   return [SomeFramework someMethod];
}

//2!
bool Amazon::someComplexMethod(int someParam) {
  objcHelper* helper = [objcHelper sharedInstance];
  return [helper someMethod: someParam];
}

//3!

void Amazon::someMethodWithObjCBlock() {
  someObjCObject.onSomeServiceAutenticationComplete = ^(void) {
        if (nullptr != m_callback) {
            m_callback();
        }
    };
   [someObjCObject autenticateUser];
}
void Amazon::setSomeCallback(const std::function<void(void)> &callback) {
  m_callback = callback;
}
  1. The easy way - just call some obj-c method on some obj-c object. Return Result;
  2. Sometime compiler wont let to use complex obj-c classes or you need more complex logic (f.e. if framework requires set some delegate methods), then you can use obj-c singleton technique;
  3. If you need to receive some delayed results (from server, long calculations etc), which implement via obj-c block, you can call your c++ std::function inside block body and pass some return params;

I think thats all you need to know to implement almost any obj-c framework in cocos2d-x game.


#3

thank you very much!!


#4

This is the best response to this question I have ever seen. It’s simple and clean.


#5

quick question do .mm files compile for android ? I want to do something like this in my game scene

void HelloWorld::ShowInterstitial()
{
if(ios){
// call objective-c method from objective-c class that loads interstitial
}
if(android){
// call java code with jni
}
}


#6

Use an #ifdef instead


#7

Ok but will .mm compile in android studio ?


#8

I will not.

See my example for runtime permission (mainly Android). This uses different files in the Classes folder for different platforms. You have to go this way…


#9

How would it be possible then to compile my helloworld scene(where all my gameplay is) on Android, if I have to call an objective-c method in that class, but in order to do that it has to be .mm?


#10

.mm file compiled on iOS or Mac.
Move code that you need to C++ and use it for all platforms except web.


#11

fellow cocos2d-x member helped me with this solution
Well - it is abstract class involved here:

  1. some PlatformProtocol.h
class PlatformProtocol {
public:
virtual void doInAppPurchase() = 0;
};

then, Platform-android.h:

#include "PlatformProtocol.h"

class Platform: public PlatformProtocol {
public:
virtual void doInAppPurchase() override;
};

Platform-android.cpp:

#include "Platform-android.h"

Platform::doInAppPurchase() {
//do android code stuff here
}

then, Platform-ios.hpp:

#include "PlatformProtocol.h"

class Platform: public PlatformProtocol {
public:
virtual void doInAppPurchase() override;
};

Platform-ios.mm:

#import "Platform-ios.h"

Platform::doInAppPurchase() {
//do ios obj-c code stuff here
}
  1. And then,
    Platform.h:
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
#include "Platform-ios.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "Platform-android.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
//class for win32
#elif CC_TARGET_PLATFORM == CC_PLATFORM_LINUX
//class for linux
#endif
  1. And in your source code:
#include "Platform.h"

Platform *p = //new, getInstance, watever you declare in PlatformProtocol and implemented 
//in Platform class, and then
p->doInAppPurchase();

#12

It’s way too much header files. Did you see my example on github? I use one header file and one cpp file for each platform. So you don’t need an abstract class.


#13

yes i looked at it but I don’t see the code to determine if its ios or android ? and no .mm file ?
I need a .mm file in order to call objective-c method, but .mm file will not compile on android so that is the problem im facing , im trying to see how I could make it work with your example @mars3142 do i need to include these statements anywhere in your code ?

#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
#include "Platform-ios.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "Platform-android.h"

#14

Why should I use this preprocessor statements within the header file?

I included only the platform depending file within the build configuration. For Android you will see it in the Android.mk file - today I use cmake for that, but that’s similar. In XCode I only include my iOS file - it could be a cpp or mm file.

Look everywhere in the cocos source. They are using this scheme for every platform specific code. It’s best practice of doing it this way.


#15

when you say “in Xcode I only include my iOS file” is there an equivalent do android.mk ? or where do you inlcude the permission-ios.cpp at since you have all these in your classes folder ?
[Permission-android.cpp]
[Permission-desktop.cpp]
[Permission-ios.cpp]
[Permission.h]