iOS SDK (Cocos2d-x)

1. Introduction

This document describes the steps to install SmartBeat for iOS on Cocos2d-x.
The tested Cocos2d-x (C/C++) versions are 2.1.4, 2.1.5, 2.2, 2.2.3, 3.1.1, 3.2, and Cocos2d-JS versions are 3.7, 3.8, 3.13.1.

The languages supported by this SDK on Cocos2d-x are C/C++ and JavaScript.
The target iOS version is 6.0 or later.

2. Initialize

Step1:SDK Installation

  • CocoaPods
  • Manual Installation
Add the Podfile using the command below.

pod 'SmartBeatPlus-bitcode'

* When using 'SmartBeatPlus-bitcode'、the device's IDFA will be used. If using IDFA is not desired, use 'SmartBeat-bitcode' instead. The audience function will be disabled if IDFA is not used.
* If you have disabled bitcode, please use the bitcode free version. (SmartBeat, SmartBeatPlus)

Next, execute the following commands:

$ pod install
$ pod update

When necessary, the 'pod update' command may be used to update the SDK to the latest version.

Also, When loading the SmartBeat header file, use SmartBeatPlus/SmartBeat.h in place of SmartBeatFramework/SmartBeat.h

//#import <SmartBeatFramework/SmartBeat.h>
#import <SmartBeatPlus/SmartBeat.h>
Download SmartBeat SDK from below and unzip it.

Download SDKs in other formats here .

Copy SmartBeatFramework.framework to any folder.
Start the Xcode and select a target you want to use. And in the Build Phases tab, expand the Link Binary With Libraries section, press the “+ button”, then press “Add Other....” In the dialog box that appears, go to the framework's location and select SmartBeatFramework.framework.

Example: Xcode 8.3.x

In addition, you will need to add the following standard frameworks.

  • SystemConfiguration.framework
  • CoreTelephony.framework
  • CoreGraphics.framework
  • OpenGLES.framework (Only needed if you are using OpenGL ES screen capture functionality)
  • AdSupport.framework (Must be present when using the audience function)
  • libz.tbd or libz.dylib (SDK Version 1.20 and up)

Step2:Set API key

Import the SmartBeat header in your application delegate's implementation file (AppDelegate.m):

#import < SmartBeatPlus/SmartBeat.h>

* If using the CocoaPods library 'SmartBeat-bitcode', or when using manual installation, use <SmartBeatFramework/SmartBeat.h> instead.

Start SmartBeat in your AppDelegate's application:didFinishLaunchingWithOptions: method.
You can get API key in your SmartBeat web console (>Settings > General Settings > API key for this app)

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [SmartBeat startWithApiKey:@"API Key"];
    //your code

Step3:Duplicate user count prevention

SDK Version 1.29 and up

No additional steps are necessary when using SDK Versions 1.29 and later. Duplicate users are determined automatically. Because of this, unwanted increases in MAU(Monthly Active Users) will be suppressed even if an applications is repeatedly re-installed. (Commonly referred to as a "reset marathon")

Step4:Audience feature settings

By using IDFA, it's possible to understand the gender and age distribution of your users.

  • CocoaPods
  • Manual Install
In Step1, if 'SmartBeatPlus-bitcode' was specified in Podfile, then no additional steps are necessary
Add SmartBeatIdfa.framework

Like Step1, in the Build Phases tab in the Xcode, expand the Link Binary With Libraries section, press the “+ button”, then press “Add Other....” in the dialog box that appears, go to the framework's location and select SmartBeatIdfa.framework.

* Both SmartBeatFramework.framework and SmartBeatIdfa.framework should be added.

sb_idfa_framework

Add linker flags

Select a suitable target in the Xcode, and in the Build Phases tab, add the following into the Other Linker Flags list.

-force_load /PathToParentDirOfFramework/SmartBeatIdfa.framework/SmartBeatIdfa

linker_flags

3. How to get errors in Cocos2d-JS

SDK version 1.21 and up

You can get the JavaScript errors in Cocos2d-JS by enabling JavaScript binding in the following steps.
* Please follow the steps below after importing the SDK into your project according to the contents of Section 2.
* This function is supported in Cocos2d-x v3.7 and up.
* The following steps are not necessary for applications that do not use JavaScript.

  • CocoaPods
  • Manual Installation

Adding SmartBeatJSBinding to the Podfile

Add the Podfile using the command below.

pod 'SmartBeatJSBinding-bitcode'

Next, execute the following commands:

$ pod install
$ pod update

* If you want to disable bitcode, "SmartBeatJSBinding" can be used instead of "SmartBeatJSBinding-bitcode".

Add SmartBeatJSBinding.framework

Copy SmartBeatJSBinding.framework to any folder.
Start Xcode and select the target. Click "+" on "General" -> "Linked Frameworks and Libraries" and select SmartBeatJSBinding.framework from "Add Other" to add it.

Registering SmartBeatJSBinding

Open the project folder frameworks/runtime-src/Classes/AppDelegate.cpp and add the following code.

#include <SmartBeatJSBinding/SmartBeatJSBinding.h>

In AppDelegate::applicationDidFinishLaunching(), add the following code before the sc->start() call.

bool AppDelegate::applicationDidFinishLaunching()
{
    ...
    sc->addRegisterCallback(...);
    sc->addRegisterCallback(...);
    ...
    sc->addRegisterCallback(SmartBeat::registerSmartBeatJSBinding); //ここを追加
    sc->start();
    ...
}

4. Extra functions

You can activate extra functions by calling APIs in Application.

Calling the API from the non-main thread

When calling the SBLog, leaveBreadcrumb and logException APIs from non-main threads would cause memory allocations within the SmartBeat API to not be released until thread termination. For long running threads, please surround such calls with an @autoreleasepool.

- (void)threadfunc:(id)argument
{
    while (YES) {
        @autoreleasepool {
            ...
            SBLog(@"log message");
            ...
        }
    }
}

4.1 Screenshots function

When this function is activated, you can get some application’s screenshots just before crash occurs. SmartBeat SDK keeps latest screenshot and send them to SmartBeat Server when a crash occurs.
* This feature is only supported on devices registered in the whitelist. See section 5.

How to activate

To begin, install SmartBeatGLESCapture using the instructions below.

  • CocoaPods
  • Manual Install

Add SmartBeatPlusGLESCapture-bitcode to your Podfile as shown below.

pod 'SmartBeatPlus-bitcode'
pod 'SmartBeatPlusGLESCapture-bitcode'

* When using SmartBeat-bitcode, add SmartBeatGLESCapture-bitcode.
* If you are not using bitcode, you may use SmartBeatPlusGLESCapture instead of SmartBeatPlusGLESCapture-bitcode.

Next, apply the settings using the following commands.

$ pod install
$ pod update
Add SmartBeatGLESCapture.framework

Like Step1, in the Build Phases tab in the Xcode, expand the Link Binary With Libraries section, press the “+ button”, then press “Add Other....” in the dialog box that appears, go to the framework's location and select SmartBeatGLESCapture.framework.

* Both SmartBeatFramework.framework and SmartBeatGLESCapture.framework should be added.

If you want to enable the screenshot feature in Cocos2d-x, first, you need to set up SmartBeatFramework to be referenced from the cocos2dx workspace.
<In version2.x>
On Xcode, select the cocos2dx target in the cocos2dx.xcodeproj workspace, select the "Build Settings" tab, and open "Framework Search Paths" included in "Search Paths". Add the SmartBeatFramework.framework that you added in Step 1.
<In versioon 3.x>
On Xcode, select the cocos2dx iOS target in the cocos2d_libs.xcodeproj workspace, select the Build Settings tab, and open the Framework Search Paths included in Search Paths. Add the SmartBeatFramework.framework that you added in Step 1.

cocos_ios_2

<In version 2.x>

For example, if you copy SmartBeatFramework.framework to a subfolder under "external" in the root folder of cocos2dx, the path should be "$(SRCROOT)/... /.. /external" and set it as recursive.

<In version 3.x>

For example, if you have copied the SmartBeatFramework.framework under the project folder </cocos2d/external/, set the path to "$(SRCROOT)/. /external" and set it as recursive.

cocos_ios_2

Next, add the code before and after the presentRenderbuffer call.
<In version 2.x>
Open /cocos2dx/platform/ios/EAGLView.mm and modify it as shown below.
<In version 3.x>
Open /cocos/platform/ios/CCEAGLView.mm and modify it as shown below.

First, add the following Import statement.

#import <SmartBeatPlus/SmartBeat.h>

Call the API (beforePresentRenderbuffer / afterPresentRenderbuffer) before and after the presentRenderbuffer as shown below.

cocos_ios_4

When building with Xcode6 or later, add the following code to "resizeFromLayer:layer" in /cocos2dx/platform/ios/CCES2Render.m.
* There is no problem to add this code even if you are building with Xcode5.

- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer
{
    //Xcode6 + Additional codes for iOS8
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer_);
    // Allocate color buffer backing based on the current layer size
    glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer_);

In addition, for Cocos2d-x 3.7 and up, add the following code to FrameBuffer::clearAllFBOs() in /cocos/renderer/CCFrameBuffer.cpp.

void FrameBuffer::clearAllFBOs()
{
    //Additional code for Cocos2d-x 3.7 and up
    GLint currentFrameBuffer;
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFrameBuffer);

    for (auto fbo : _frameBuffers)
    {
        //Additional code for Cocos2d-x 3.7 and up
        fbo->_fbo = currentFrameBuffer;

        fbo->clearFBO();
    }
}
Additional API

Devices may be arbitrarily added to the whitelist using the API below.

[[SmartBeat shared] whiteListModelForOpenGLES:モデル名];

Where Model Name is the string extracted from sysctlbyname when specifying hw.machine.

4.2 Logging

SDK version 1.20 and up

Logs will be gathered internally, and not output to the device log.
*As of iOS 10, even if enabled, the section 3.5 Include NSLog feature will not function. This feature is recommended as an alternative.
* The most recent 64KB or 500 lines of log will be included in crash reports.
* If the Section 3.5 Include NSLog feature is enabled, on iOS prior to version 10, the data from this feature will not be used, and NSLog data will be included in the crash report.

How to activate

Output logs using the following API calls.

■ Objective-C
SBLog("String: %@, Integer: %d", "text", 1);

Alternatively,

va_list args;
va_start(args, format);
SBLogv(format, args);
va_end(args);

* For notes on calling from threads other than the main thread, see here.

■ JavaScript
SmartBeat.log('message');

4.3 Include NSLog

SmartBeat can also include LogCat with crash/exception data.
(Please call this API in AppController.mm that you edited in Section 2, Step 2.)
* As of iOS 10, even if enabled, this section's NSLog feature will not function. Section 4.2 Logging is recommended as an alternative.
* The most recent 64KB or 500 lines of log will be included in crash reports.
* If this feature is enabled, on iOS prior to version 10, the data from the section 3.4 Logging feature will not be used, and NSLog data will be included in the crash report.

How to activate
■ Objective-C
[[SmartBeat shared] enableNSLog];
■ JavaScript

There is no corresponding function in JavaScript.

4.4 Set user identifier

If your application provides a user ID for each user, you can include it with crash/exception data. That help you find specific user’s errors by using this user ID on the SmartBeat web console.

How to activate

In order to set user ID, call the API below:

■ Objective-C
[[SmartBeat shared] setUserId:@"user001"];
■ JavaScript
SmartBeat.setUserId('user001');

4.5 Add Extra data

You have another option to add extra custom information into the crash/exception reports. This will help you reproduce and fix errors. (e.g. user’s entering parameters, API return values etc.)

How to activate

In order to set a couple of a key and a value with crash data, call the API below:
The values will be overwritten by new one which has the same key.

■ Objective-C
NSMutableDictionary *extraData = [NSMutableDictionary dictionary];
[extraData setObject:@"value1" forKey:@"key1"];
[extraData setObject:@"value2" forKey:@"key2"];
[[SmartBeat shared] setExtraData:extraData];

Only the NSString type of data can be seved.

■ JavaScript
SmartBeat.addExtraData('key1', 'value1');
SmartBeat.addExtraData('key2', 'value2');

4.6 Breadcrumb function

Use of the breadcrumb feature makes it possible to know what status changes and operations occured leading up to an error.
Typical operations and status change events are automatically recorded Also, using an API from the app side allows recording of app specific status changes and operations.
Additionally, breadcrumb text can be up to 140 characters in length, with additional metadata, and the most recent 128 will be retained.
* In the event more than 140 characters are supplied, only the leading 140 characters will be retained.
* In the event the total size of the breadcrumb exceeds 1KB, it will be recorded without the specified meta-data.

How to active

To drop an additional breadcrumb (Leave a record of it) location, call the API shown below.

■ Objective-C
[[SmartBeat shared] leaveBreadcrumb:@"game scene 1"];

Alternatively, metadata may also be attached using the API shown below.

NSDictionary *metas = @{@"key":@"value"};
[[SmartBeat shared] leaveBreadcrumb:@"game scene 1" withMetas:metas];

* Cautions for calling this API from threads other than the main thread may be found here.

■ JavaScript
SmartBeat.leaveBreadcrumb('game scene 1');

* Attaching metadata is not supported in JavaScript.

4.7 Disabling crash/exception report by default

SDK version 1.6 and up

You can disable reporting crash/exception by default using following API.

How to Activate

Instead of the API described in the Step2:Set API key, use the following API to enable/disable the API during initialization.

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    BOOL enableSmartBeat = NO; //NO to start in the disabled state.
    [SmartBeat startWithApiKey:@"API key" withEnabled:enableSmartBeat];
    //your code

Use following API to enable reporting crash/exception anytime it should be active.
To enable/disable, please set "SmartBeat startWithApiKey: withEnabled:" at every startup.

■ Objective-C

To enable

[[SmartBeat shared] enable];

To disable

[[SmartBeat shared] disable];

To get the status

BOOL enabled = [[SmartBeat shared] isEnabled];
■ JavaScript

To enable

SmartBeat.enable();

To disable

SmartBeat.disable();

To get the status

var enabled = SmartBeat.isEnabled();

4.8 JavaScript Exceptions

SDK version 1.21 and up

SmartBeat supports JavaScript errors that your application catches on Cocos2d-JS.

How to active
try {
    throw new Error();
} catch (e) {
    SmartBeat.logException(e);
}

4.9 Auto upload dSYMs

You can automatically upload dSYMs every build by using dSYM upload script in the Run Script section.

For more details on the script and how to use it, download the archive from here.

5. Resource usage

Resource requirements of the SmartBeat SDK:

Device Items Resource usage
w/o Screenshot function
Resource usage
w/ Screenshot function
iPhone5S
iOS7.0.4
Mem. usage
CPU usage
about 1.0MB up
no change
about 1.7MB up
ave. 2.3% up
iPhone4
iOS6.0.1
Mem. usage
CPU usage
about 1.0MB up
no change
about 1.3MB up
ave. 4.8% up

When screenshots function is active,
- memory usage increases based on pixels of screenshots.
- CPU usage increases due to processes of getting, encoding and sending screenshots.

6. Supports devices for OpenGL ES screenshot

Following devices are supported to take screenshot for OpenGL ES

Device name hw.machine SDK version
iPhone 4 iPhone3,1 iPhone3,2 iPhone3,3 1.19 -
iPhone 4S iPhone4,1 1.19 -
iPhone 5 iPhone5,1 iPhone5,2 1.19 -
iPhone 5C iPhone5,3 iPhone5,4 1.19 -
iPhone 5S iPhone6,1 iPhone6,2 1.19 -
iPhone 6S iPhone8,1 1.19 -
iPhone 6S Plus iPhone8,2 1.19 -
iPhone SE iPhone8,4 1.20 -
iPhone 7 iPhone9,1 iPhone9,3 1.23 -
iPhone 8 iPhone10,1 iPhone10,4 1.23 -
iPhone 8 Plus iPhone10,2 iPhone10,5 1.23 -
iPhone X iPhone10,3 iPhone10,6 1.23 -
iPad 2 iPad2,1 iPad2,2 iPad2,3 iPad2,4 1.19 -
iPad Mini (1st) iPad2,5 iPad2,6 iPad2,7 1.19 -
iPod Touch (5th) iPod5,1 1.19 -
iPod Touch (6th) iPod7,1 1.23 -