‹ Share Doc Home

Share Integration Guide

For the C++ version of cocos2d-x v3.x - (all other versions)

Overview

SDKBOX Share plugin provide an one stop solution for developers to share to all social platforms.

Currently SDKBOX Share supports share via twitter, facebook and SMS

Please make sure you create developer account on the following platforms

SDK Version

Integration

Open a terminal and use the following command to install the SDKBOX Share plugin. Make sure you setup the SDKBOX installer correctly.

$ sdkbox import share

You will also need to import SDKBOX facebook plugin if you want enable facebook share support

$ sdkbox import facebook

Facebook plugin have some extra integration steps, please click here

Important Notice

Please make sure the following settings in your project to make the plugin work well.

Disable App Transport Security

Adding the following entry to the info.plist file:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

It should look like this:

Disable Bitcode support

You have to turn off Bitcode support. If you don't, cocos2d-x will fail to build.

Set your game requires full screen

If your game doesn't support all screen orientations, you will need to check Requires full screen in Xcode. If you do not, your app will fail Apple's submission process.

Whitelist canOpenURL function

This setting depends on what plugins are in your project. You may need to add the required entry to the info.plist, under LSApplicationQueriesSchemes.

JSON Configuration

SDKBOX Installer will automatically inject a sample configuration to your res/sdkbox_config.json, that you have to modify it before you can use it for your own app

Here is an example of the Share configuration

    "android": {
        "Facebook": {
            "debug": false
        },
        "Share": {
            "platforms": {
                "Twitter": {
                    "params": {
                        "secret": "0mxHbmO8QFHSLnfJVVbGTStjaW6IlcRC6xofSWeFecLcj4jsLn",
                        "key": "s5xddoPxy4xIbzAhqrecESSlW"
                    }
                },
                "Facebook": {},     //support facebook share
                "SMS": {},          //support sms share
                "EMail": {}         //support email share
            }
        }
    },
    "ios": {
        "Facebook": {
            "debug": true
        },
        "Share": {
            "platforms": {
                "Twitter": {
                    "params": {
                        "secret": "0mxHbmO8QFHSLnfJVVbGTStjaW6IlcRC6xofSWeFecLcj4jsLn",
                        "key": "s5xddoPxy4xIbzAhqrecESSlW"
                    }
                },
                "Facebook": {},     //support facebook share
                "SMS": {},          //support sms share
                "EMail": {}         //support email share
            }
        }
    }

Twitte configuration

you need to replace <key>, <secret> item with your specific Twitter account.

Facebook configuration

you need to add a Facebook entry in the config

Setup iOS

#import <TwitterKit/TWTRKit.h>

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
    return [[Twitter sharedInstance] application:app openURL:url options:options];
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

    ...

    <key>CFBundleURLTypes</key>
    <array>

        ...

        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>twitterkit-(your-appkey)</string>
            </array>
        </dict>

        ...

    </array>

    <key>LSApplicationQueriesSchemes</key>
    <array>

        ...

        <string>twitter</string>
        <string>twitterauth</string>

        ...

    </array>

    ...

</dict>
</plist>

Usage

Initialize Share

Initialize the plugin where appropriate in your code. We recommend to do this in the AppDelegate::applicationDidFinishLaunching() or AppController:didFinishLaunchingWithOptions(). Make sure to include the appropriate headers:

#include "PluginShare/PluginShare.h"
AppDelegate::applicationDidFinishLaunching()
{
     sdkbox::PluginShare::init();
}

share content

After initialization you can begin to use the Share functionality:

sdkbox::SocialShareInfo info;
info.text = "#sdkbox(www.sdkbox.com) - the cure for sdk fatigue ";
info.title = "sdkbox";
//info.image = "path/to/image"
info.link = "http://www.sdkbox.com";
info.showDialog = false; //if you want share with dialog,set the value true

//sdkbox::SocialPlatform::Platform_Select will show platforms list, let user select which platform want to share
//sdkbox::SocialPlatform::Platform_Twitter will share with twitter directly
//sdkbox::SocialPlatform::Platform_Facebook will share with facebook directly
info.platform = sdkbox::SocialPlatform::Platform_Select;
sdkbox::PluginShare::share(info);

Native Share

you can use ios/andrid system native share:

sdkbox::SocialShareInfo info;
info.text = "#sdkbox(www.sdkbox.com) - the cure for sdk fatigue ";
info.title = "sdkbox";
//info.image = "path/to/image"
info.link = "http://www.sdkbox.com";
sdkbox::PluginShare::nativeShare(info);

// the follow property will be ignored in nativeShare
//info.showDialog = false;
//info.platform = sdkbox::SocialPlatform::Platform_Select;

sdkbox::PluginShare::nativeShare(info);

Note:

Catch Share events (optional)

This allows you to catch the Share events so that you can perform operations based upon responses. A simple example might look like this:

#include "PluginShare/PluginShare.h"
class SListener : public sdkbox::ShareListener {
public:
    virtual void onShareState(const sdkbox::SocialShareResponse& response) {
        switch (response.state) {
            case sdkbox::SocialShareState::SocialShareStateNone: {
                CCLOG("SharePlugin::onShareState none");
                break;
            }
            case sdkbox::SocialShareState::SocialShareStateUnkonw: {
                CCLOG("SharePlugin::onShareState unkonw");
                break;
            }
            case sdkbox::SocialShareState::SocialShareStateBegin: {
                CCLOG("SharePlugin::onShareState begin");
                break;
            }
            case sdkbox::SocialShareState::SocialShareStateSuccess: {
                CCLOG("SharePlugin::onShareState success");
                break;
            }
            case sdkbox::SocialShareState::SocialShareStateFail: {
                CCLOG("SharePlugin::onShareState fail, error:%s", response.error.c_str());
                break;
            }
            case sdkbox::SocialShareState::SocialShareStateCancelled: {
                CCLOG("SharePlugin::onShareState cancelled");
                break;
            }
            case sdkbox::SocialShareStateSelectShow: {
                CCLOG("SharePlugin::onShareState show pancel %d", response.platform);
                break;
            }
            case sdkbox::SocialShareStateSelectCancelled: {
                CCLOG("SharePlugin::onShareState show pancel cancelled %d", response.platform);
                break;
            }
            case sdkbox::SocialShareStateSelected: {
                CCLOG("SharePlugin::onShareState show pancel selected %d", response.platform);
                break;
            }
            default: {
                CCLOG("SharePlugin::onShareState");
                break;
            }
        }
    }
};
sdkbox::PluginShare::setListener(this);

API Reference

Methods

static bool init ( const char * jsonConfig = 0 ) ;

initialize the plugin instance.

static void setListener ( ShareListener * listener ) ;

Set listener to listen for share events

static ShareListener * getListener ( ) ;

Get the listener

static void removeListener ( ) ;

Remove the listener, and can't listen to events anymore

static void setSharePanelTitle ( const std::string & s ) ;

set custome share platform choose panel title, default is "Share to"

static void setSharePanelCancel ( const std::string & s ) ;

set custome share platform choose panel cancel button, default is "Cancel"

static void share ( const sdkbox::SocialShareInfo & info ) ;

Share content

static void nativeShare ( const sdkbox::SocialShareInfo & info ) ;

will use ios/android system share panel

IOS:
when trigger share success event, action name will pass by error in sdkbox::SocialShareResponse
Android:
share success event will trigger, but this is not real share success, just show share panel success
can't get real share success event on android
static void logoutTwitter ( ) ;
static void setFileProviderAuthorities ( const std::string & authority ) ;

Listeners

void onShareState ( const sdkbox::SocialShareResponse & response ) 

Notifies the delegate that share completion

Manual Integration

If the SDKBOX Installer fails to complete successfully, it is possible to integrate SDKBOX manually. If the installer complete successfully, please do not complete anymore of this document. It is not necessary.

These steps are listed last in this document on purpose as they are seldom needed. If you find yourself using these steps, please, after completing, double back and re-read the steps above for other integration items.

Manual Integration For iOS

Drag and drop the following frameworks from the plugins/ios folder of the Share bundle into your Xcode project, check Copy items if needed when adding frameworks:

sdkbox.framework

PluginShare.framework

TwitterCore.framework

TwitterKit.framework

TwitterKitResources.bundle -> TwitterKit.framework/TwitterKitResources.bundle

TwitterShareExtensionUIResources.bundle -> TwitterKit.framework/TwitterShareExtensionUIResources.bundle

add the following system frameworks, if you don't already have them:

Accounts.framework

CoreText.framework

CoreMedia.framework

CoreData.framework

Social.framework

GameController.framework

SystemConfiguration.framework

MediaPlayer.framework

MessageUI.framework

CoreMotion.framework

SafariServices.framework

Manual Integration For Android

SDKBOX supports three different kinds of Android projects command-line, eclipse and Android Studio.

Copy Files

Copy the following jar files from plugin/android/libs folder of this bundle into your project's /libs folder.

sdkbox.jar

PluginShare.jar

converter-gson-2.1.0.jar

gson-2.7.jar

okhttp-3.4.2.jar

okio-1.9.0.jar

picasso-2.5.2.jar

retrofit-2.1.0.jar

twitter-text-1.14.3.jar

tweet-composer

twitter-core

dependencies tag in file proj.android-studio/app/build.gradle

    dependencies {

        ...

        implementation 'com.twitter.sdk.android:twitter-core:3.1.1'
        implementation 'com.twitter.sdk.android:tweet-composer:3.1.1'

        ...

    }

Copy jni libs

Copy and overwrite all the folders from plugin/android/jni to your <project_root>/jni/ directory.

Edit AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<activity
    android:name="com.twitter.sdk.android.core.identity.OAuthActivity"
    android:configChanges="orientation|screenSize"
    android:excludeFromRecents="true"
    android:exported="false" />

<service
    android:name="com.twitter.sdk.android.tweetcomposer.TweetUploadService"
    android:enabled="true"
    android:exported="false" />

Edit Android.mk

Edit <project_root>/jni/Android.mk to:

Add additional requirements to LOCAL_WHOLE_STATIC_LIBRARIES:

LOCAL_WHOLE_STATIC_LIBRARIES += PluginShare
LOCAL_WHOLE_STATIC_LIBRARIES += sdkbox

Add a call to:

$(call import-add-path,$(LOCAL_PATH))

before any import-module statements.

Add additional import-module statements at the end:

$(call import-module, ./sdkbox)
$(call import-module, ./pluginshare)

This means that your ordering should look similar to this:

$(call import-add-path,$(LOCAL_PATH))
$(call import-module, ./sdkbox)
$(call import-module, ./pluginshare)

Note: It is important to make sure these statements are above the existing $(call import-module,./prebuilt-mk) statement, if you are using the pre-built libraries.

Modify Application.mk (Cocos2d-x v3.0 to v3.2 only)

Edit <project_root>/jni/Application.mk to make sure APP_STL is defined correctly. If Application.mk contains APP_STL := c++_static, it should be changed to:

APP_STL := gnustl_static

Modify AppActivity.java

Plugin >= 2.4.0.3

  1. Find the AppActivity.java
find . -name "AppActivity.java"
  1. Replace extends Cocos2dxActivity with extends com.sdkbox.plugin.SDKBoxActivity

Example of the directory where the AppActivity.java file is located:

cpp
  - proj.android/src/org/cocos2dx/cpp/AppActivity.java
  - proj.android-studio/app/src/org/cocos2dx/cpp/AppActivity.java
  - proj.android/app/src/org/cocos2dx/cpp/AppActivity.java ( from cocos2d-x 3.17)

lua
  - frameworks/runtime-src/proj.android/src/org/cocos2dx/lua/AppActivity.java
  - frameworks/runtime-src/proj.android-studio/app/src/org/cocos2dx/lua/AppActivity.java
  - frameworks/runtime-src/proj.android/app/src/org/cocos2dx/lua/AppActivity.java (from cocos2d-x 3.17)

js
  - frameworks/runtime-src/proj.android/src/org/cocos2dx/javascript/AppActivity.java
  - frameworks/runtime-src/proj.android/app/src/org/cocos2dx/javascript/AppActivity.java ( from cocos2d-x 3.17)

Plugin < 2.4.0.3

Note: When using Cocos2d-x from source, different versions have Cocos2dxActivity.java in a different location. One way to find the location is to look in proj.android/project.properties. Example: android.library.reference.1=../../cocos2d-x/cocos/platform/android/java

In this case, Cocos2dxActivity.java should be located at:

../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
onLoadNativeLibraries();
SDKBox.init(this);
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          if(!SDKBox.onActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
          }
    }
    @Override
    protected void onStart() {
          super.onStart();
          SDKBox.onStart();
    }
    @Override
    protected void onStop() {
          super.onStop();
          SDKBox.onStop();
    }
    @Override
    protected void onResume() {
          super.onResume();
          SDKBox.onResume();
    }
    @Override
    protected void onPause() {
          super.onPause();
          SDKBox.onPause();
    }
    @Override
    public void onBackPressed() {
          if(!SDKBox.onBackPressed()) {
            super.onBackPressed();
          }
    }

Proguard (optional)

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# share
-keep class com.share.** { *; }
-dontwarn com.share.**


# cocos2d-x
-keep public class org.cocos2dx.** { *; }
-dontwarn org.cocos2dx.**
-keep public class com.chukong.** { *; }
-dontwarn com.chukong.**

#sdkbox
-keep public class com.sdkbox.** { *; }
-dontwarn com.sdkbox.**

#twitter
-keep public com.twitter.sdk.android.** { *; }

Note: Proguard only works with Release builds (i.e cocos run -m release) debug builds do not invoke Proguard rules.

Notice

if you got this error:

Unknown source file : UNEXPECTED TOP-LEVEL EXCEPTION:
Unknown source file : com.android.dex.DexException: Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoVersionImpl;

maybe your project have multi android-support-v4.jar, you can remove the duplicate one and just keep one.

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.sdkbox.test.app.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
  1. check AndroidManifest.xml, replace com.sdkbox.test.app.fileprovider with your self authorities, usualy use your.app.bundleid.customstring

  2. pass your self authorities to sdkbox social share, e.g.

   sdkbox::PluginShare::setFileProviderAuthorities("your.app.bundleid.customstring");