Tune 集成指南
For the Javascript version of cocos2d-x v3.x - (all other versions)
集成
在您确保正确安装了 SDKBOX installer 的情况下,运行下面的命令来集成 SDKBOX Tune 插件。
sdkbox import tune
重点注意事项
如果您升级到了 Xcode7, 则需要以下额外步骤来确保插件工作正常:
禁用应用程序安全传输策略
添加以下项到 plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
添加后的文件内容看起来就像这样:
禁止 Bitcode 支持
您必须禁止 Bitcode 的支持,否则将会编译失败。
游戏全屏配置
如果您的游戏不同时支持横竖屏,则必须在 Xcode 中选中 Requires full screen
,否则将不会通过 Apple 的审核。
canOpenURL 白名单
取决于您使用哪些插件。需要在 info.plist
的 LSApplicationQueriesSchemes
下添加名单。
关于 Creator 工程
Creator 导出工程会修改工程的配置, 这可能会影响 SDKBox 对工程的配置修改. 所以可以有以下做法(任选其一):
- 保存导出工程中的修改, 对于 SDKBox 来说可能有这些文件(mk, gradle, gradle.properties, AppDelegate.cpp, ...), 导出后再恢复对应该文件
- 在每一次 Creator 导出工程后, 重新 import 插件.
推荐第一种, 但是第一种的麻烦点在于, 对于第一次(或很久没接触的人)可能会有露掉某个文件 第二种, 很方便, 它的麻烦点在于, 如果你对工程有自己的修改, SDKBox 的重新 import 不能帮你恢复.
JSON 配置
SDKBOX Installer 将会自动在您的 sdkbox_config.json
中插入一份配置样例。请修改这份配置样例,使其能用于您自己的 app 。
对于一个 Tune 插件的配置样例,您需要将其中的 <TUNE id>
以及 <TUNE KEY>
替换成您特定的 Tune ID 帐号中的信息。
如下是一个添加 Tune
插件的配置样例:
"Tune":{
"id":"<TUNE ID>",
"key":"<TUNE KEY>",
"debug":false
}
使用
初始化 Tune
- 通过在您的代码合适的位置调用
init()
方法来初始化这个插件。我们建议您在app.js
中进行初始化。举例如下:
sdkbox.PluginTune.init();
- 修改
./frameworks/runtime-src/Classes/AppDelegate.cpp
文件,包含下列头文件:
#include "PluginTuneJS.hpp"
#include "PluginTuneJSHelper.h"
- 修改
./frameworks/runtime-src/Classes/AppDelegate.cpp
文件,添加如下内容:
sc->addRegisterCallback(register_all_PluginTuneJS);
sc->addRegisterCallback(register_all_PluginTuneJS_helper);
这将注册 Javascript 回调函数。
使用 Tune
在初始化之后,您可以开始使用 Tune 插件的功能了。Tune 使用 events 这个概念(就像 MAT Native Event Types__一样)。您可以在您需要的地方将 __events 记入日志,并且在稍后通过基于 web 的报告阅读器查看它们。Tune 在文档中为这些 events 提供一种结构。举例如下:
sdkbox.PluginTune.measureEventName("login");
sdkbox.PluginTune.measureEventId(0123456789);
var event = {};
event.eventName = "purchase";
event.refId = "RJ1357";
event.searchString = "sweet srisp red apples";
event.attribute1 = "srisp";
event.attribute2 = "red";
event.quantity = 3;
sdkbox.PluginTune.measureEvent(JSON.stringify(event));
捕捉 Tune 事件(可选)
您可以捕捉 Tune
事件,根据响应来执行操作。一个简单的例子如下:
sdkbox.PluginTune.setListener({
onEnqueuedAction: function(data) {},
onSucceed: function(data) {},
onFailed: function(data) {},
onReceiveDeeplink: function(data, timeout) {},
onFailDeeplink: function(errorString) {}
});
API Reference
Methods
sdkbox.PluginTune.setListener(listener);
set a listener to listen for event changes.
sdkbox.PluginTune.init();
init the instance.
sdkbox.PluginTune.setDebugMode(enable);
Specifies that the server responses should include debug information.
sdkbox.PluginTune.setAllowDuplicateRequests(allow);
Set to YES to allow duplicate requests to be registered with the MAT server.
// use checkForDeferredDeepLink()
sdkbox.PluginTune.checkForDeferredDeeplinkWithTimeout(timeout);
Check for a deferred deeplink entry point upon app installation. This is safe to call at every app launch, since the function does nothing unless this is the first launch.
sdkbox.PluginTune.checkForDeferredDeepLink();
Check for a deferred deeplink entry point upon app installation. This is safe to call at every app launch, since the function does nothing unless this is the first launch.
sdkbox.PluginTune.automateIapEventMeasurement(automate);
Enable automatic measurement of app store in-app-purchase events. When enabled, your code should not explicitly measure events for successful purchases related to StoreKit to avoid event duplication.
sdkbox.PluginTune.setFacebookEventLogging(logging, limit);
Set whether the MAT events should also be logged to the Facebook SDK. This flag is ignored if the Facebook SDK is not present.
sdkbox.PluginTune.setExistingUser(existingUser);
Set whether this is an existing user or a new one. This is generally used to distinguish users who were using previous versions of the app, prior to integration of the MAT SDK. The default is to assume a new user.
sdkbox.PluginTune.setAppleAdvertisingIdentifier(appleAdvertisingIdentifier,
adTrackingEnabled);
Set the Apple Advertising Identifier available in iOS 6.
sdkbox.PluginTune.setAppleVendorIdentifier(appleVendorIdentifier);
Set the Apple Vendor Identifier available in iOS 6.
sdkbox.PluginTune.setCurrencyCode(currencyCode);
Sets the currency code.
sdkbox.PluginTune.setJailbroken(jailbroken);
Sets the jailbroken device flag.
sdkbox.PluginTune.setPackageName(packageName);
Sets the package name (bundle identifier). Defaults to the Bundle Identifier of the app that is running the sdk.
sdkbox.PluginTune.setShouldAutoDetectJailbroken(autoDetect);
Specifies if the sdk should auto detect if the iOS device is jailbroken.
sdkbox.PluginTune.setShouldAutoGenerateAppleVendorIdentifier(autoGenerate);
Specifies if the sdk should pull the Apple Vendor Identifier from the device. Note that setting to false will clear any previously set value for the property.
// use setPackageName()
sdkbox.PluginTune.setSiteId(siteId);
Sets the site ID.
sdkbox.PluginTune.setTRUSTeId(tpid);
Set the TRUSTe Trusted Preference Identifier (TPID).
sdkbox.PluginTune.setUserEmail(userEmail);
Sets the user's email address.
sdkbox.PluginTune.setUserId(userId);
Sets the user ID.
sdkbox.PluginTune.setUserName(userName);
Sets the user's name.
sdkbox.PluginTune.setPhoneNumber(phoneNumber);
Sets the user's phone number.
sdkbox.PluginTune.setFacebookUserId(facebookUserId);
Set user's Facebook ID.
sdkbox.PluginTune.setTwitterUserId(twitterUserId);
Set user's Twitter ID.
sdkbox.PluginTune.setGoogleUserId(googleUserId);
Set user's Google ID.
sdkbox.PluginTune.setAge(userAge);
Sets the user's age.
sdkbox.PluginTune.setGender(userGender);
Sets the user's gender.
sdkbox.PluginTune.setLatitude(latitude, longitude);
Sets the user's location.
sdkbox.PluginTune.setLatitude(latitude, longitude, altitude);
Sets the user's location including altitude.
sdkbox.PluginTune.setAppAdTracking(enable);
Set app-level ad-tracking.
sdkbox.PluginTune.setPayingUser(isPayingUser);
Set whether the user is generating revenue for the app or not. If measureEvent is called with a non-zero revenue, this is automatically set to YES.
sdkbox.PluginTune.setPreloadData(preloadData);
Sets publisher information for attribution.
// use tuneId()
sdkbox.PluginTune.matId();
Get the MAT ID for this installation (mat_id).
sdkbox.PluginTune.tuneId();
Get the Tune ID for this installation.
sdkbox.PluginTune.openLogId();
Get the MAT log ID for the first app open (open_log_id).
sdkbox.PluginTune.isPayingUser();
Get whether the user is revenue-generating.
sdkbox.PluginTune.measureSession();
To be called when an app opens; typically in the AppDelegate::applicationWillEnterForeground() event.
sdkbox.PluginTune.measureEventName(eventName);
Record an event for an Event Name.
sdkbox.PluginTune.measureEventId(eventId);
Record an event by providing the equivalent Event ID defined on the MobileAppTracking dashboard.
sdkbox.PluginTune.measureEvent(event);
Record an event with a MATEvent.
sdkbox.PluginTune.setUseCookieTracking(enable);
Sets whether or not to use cookie based tracking.
sdkbox.PluginTune.setRedirectUrl(redirectUrl);
Sets a url to be used with app-to-app tracking so that the sdk can open the download (redirect) url. This is used in conjunction with the setTracking:advertiserId:offerId:publisherId:redirect: method.
sdkbox.PluginTune.startAppToAppTracking(targetAppPackageName,
targetAppAdvertiserId,
targetAdvertiserOfferId,
targetAdvertiserPublisherId,
shouldRedirect);
Start an app-to-app tracking session on the MAT server.
sdkbox.PluginTune.applicationDidOpenURL(urlString, sourceApplication);
Record the URL and Source when an application is opened via a URL scheme. This typically occurs during OAUTH or when an app exits and is returned to via a URL. The data will be sent to the HasOffers server when the next measureXXX method is called so that a Re-Engagement can be recorded.
sdkbox.PluginTune.setDeepLink(deepLinkUrl);
Record the URL and Source when an application is opened via a URL scheme.
Listeners
onEnqueuedAction(referenceId);
onSucceed(data);
onFailed(errorString);
onReceiveDeeplink(deeplink, timeout);
onMobileAppTrackerDidFailDeeplinkWithError(errorString);
手动集成
如果 SDKBOX 安装器 安装插件失败了,那么需要手动集成插件.如果安装器安装插件成功了,那么不需要,也没必要,按文档再手动集成一次.
下面列出的的步骤一般很少用到.如果你按下面的步骤完成了集成,请在完成集成后,再按步骤检查一次.
iOS 平台手动集成
拖拽下列 framework 从 Tune
插件包的 plugins/ios 目录到您的 Xcode 工程中,在添加 frameworks 的时候,请勾选 Copy items if needed
。
sdkbox.framework
PluginTune.framework
MobileAppTracker.framework
上面的 frameworks 依赖于其他 frameworks。如果您没有添加它们,您也需要添加下列这些系统 frameworks:
CoreTelephony.framework
Security.framework
SystemConfiguration.framework
AdSupport.framework
iAd.framework
MobileCoreServices.framework
StoreKit.framework
把 plugin/jsbindings
文件夹中所有的头文件和源文件都拷贝到你的工程的 Classes
文件夹中.
把刚刚拷贝的文件拖动到 Xcode 中或使用 File -> Add files to... 来添加.
Android 平台手动集成
拷贝文件
从插件安装包中的 plugin/android/libs
目录拷贝下列 jar 文件到您的工程的 proj.android/libs 目录。
PluginTune.jar
sdkbox.jar
MobileAppTracker-3.9.jar
-
如果你使用 cocos2d-x 源码,拷贝 jar 文件到:
Android command-line:
cocos2d/cocos/platform/android/java/libs
Android Studio:
cocos2d/cocos/platform/android/libcocos2dx/libs
-
如果你使用 cocos2d-js 或者 lua ,拷贝 jar 文件到:
Android command-line:
frameworks/cocos2d-x/cocos/platform/android/java/libs
Android Studio:
frameworks/cocos2d-x/cocos/platform/android/libcocos2dx/libs
-
如果你使用 cocos2d-x 预编译包,拷贝 jar 文件到:
Android command-line:
proj.android/libs
从 plugin/android/jni
目录拷贝 plugintune
以及 sdkbox
目录到您的工程的 proj.android/jni
目录。如果 sdkbox
目录在工程中已经存在,请覆盖它。
编辑 AndroidManifest.xml
在标签 application tag 上添加下列权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
使 hardware acceleration 属性生效。这一标签是一个在新版本 sdk 上的选项,不能用于2.3.3版本。
<android:hardwareAccelerated="true" />
application tag 也需要被创建:
<application ... >
<receiver android:name="com.mobileapptracker.Tracker">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
</application>
编辑 Android.mk
编辑 proj.android/jni/Android.mk
:
为 LOCAL_STATIC_LIBRARIES 添加额外的库:
LOCAL_STATIC_LIBRARIES += PluginTune
LOCAL_STATIC_LIBRARIES += sdkbox
在所有 import-module 语句之前添加一条 call 语句:
$(call import-add-path,$(LOCAL_PATH))
在最后添加额外的 import-module 语句:
$(call import-module, ./sdkbox)
$(call import-module, ./plugintune)
这意味着您的语句顺序看起来像是这样:
$(call import-add-path,$(LOCAL_PATH))
$(call import-module, ./sdkbox)
$(call import-module, ./plugintune)
Note: 如果您使用的是 cocos2d-x 预编译库,那么保证这些语句在已有的 $(call import-module,./prebuilt-mk)
语句之上非常重要。
编辑 Application.mk
(只限 Cocos2d-x v3.0 到 v3.2 版本)
编辑 proj.android/jni/Application.mk
保证 APP_STL 的定义正确。如果 Application.mk
包含了 APP_STL := c++_static
语句,那么这条语句应该被改为:
APP_STL := gnustl_static
把 plugin/jsbindings
文件夹中所有的头文件和源文件都拷贝到你的工程的 Classes
文件夹中.
把你刚刚拷贝的 .cpp
文件添加到 Android.mk
文件的的 LOCAL_SRC_FILES 项.比如
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp \
../../Classes/NewSourceFile.cpp
修改 AppActivity.java
插件版本 >= 2.4.0.3
- 找到 AppActivity.java 文件
find . -name "AppActivity.java"
- 把
extends Cocos2dxActivity
替换为extends com.sdkbox.plugin.SDKBoxActivity
以下是 AppActivity.java 不同版本的引擎所在的目录:
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)
插件版本 < 2.4.0.3
-
如果您使用 cocos2d-x 源代码,假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/ lib/Cocos2dxActivity.java
-
如果您使用 cocos2dx-x 预编译库, 假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:./src/org/cocos2dx/lib/Cocos2dxActivity.java
Note: 当你使用 cocos2d-x 源代码时,不同的版本中 Cocos2dxActivity.java
文件的位置也不同。一个确定该文件位置的方法是查看 proj.android/project.properties
。比如:
android.library.reference.1=../../cocos2d-x/cocos/platform/android/java
在这个例子中, Cocos2dxActivity.java
文件应该在如下位置:
../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
- 修改
Cocos2dxActivity.java
文件,导入如下包:
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
- 然后,修改
Cocos2dxActivity
类的onCreate(final Bundle savedInstanceState)
函数,添加一个调用语句SDKBox.init(this);
。添加的位置非常重要,必须在调用onLoadNativeLibraries();
之后。如下:
onLoadNativeLibraries();
SDKBox.init(this);
-
最后, 我需要提供合适的 overrides 方法的代码。这里有一些约定如下。
-
如果这个被列出的方法没有在
SDKBox
中定义,那么__定义它__。 -
如果这个被列出的方法已经被定义在
SDKBox
中,那么请调用这个在SDKBox
中的__同名方法__。
-
@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 (release模式下可选)
- 编辑
project.properties
文件, 指定一个Proguard
配置文件。比如:
proguard.config=proguard.cfg
- 编辑这个配置文件,加入如下内容:
-keep public class com.mobileapptracker.** {
public *;
}
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
Note: Proguard 只能工作在 Release 模式下 (比如: cocos run -m release
) debug 模式下不会触发 Proguard。
修改 AppActivity.java
插件版本 >= 2.4.0.3
- 找到 AppActivity.java 文件
find . -name "AppActivity.java"
- 把
extends Cocos2dxActivity
替换为extends com.sdkbox.plugin.SDKBoxActivity
以下是 AppActivity.java 不同版本的引擎所在的目录:
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)
插件版本 < 2.4.0.3
-
如果您使用 cocos2d-x 源代码,假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/ lib/Cocos2dxActivity.java
-
如果您使用 cocos2dx-x 预编译库, 假设您在
proj.android
目录下,那么您可以在如下位置找到Cocos2dxActivity.java
文件:./src/org/cocos2dx/lib/Cocos2dxActivity.java
Note: 当你使用 cocos2d-x 源代码时,不同的版本中 Cocos2dxActivity.java
文件的位置也不同。一个确定该文件位置的方法是查看 proj.android/project.properties
。比如:
android.library.reference.1=../../cocos2d-x/cocos/platform/android/java
在这个例子中, Cocos2dxActivity.java
文件应该在如下位置:
../../cocos2d-x/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
- 修改
Cocos2dxActivity.java
文件,导入如下包:
import android.content.Intent;
import com.sdkbox.plugin.SDKBox;
- 然后,修改
Cocos2dxActivity
类的onCreate(final Bundle savedInstanceState)
函数,添加一个调用语句SDKBox.init(this);
。添加的位置非常重要,必须在调用onLoadNativeLibraries();
之后。如下:
onLoadNativeLibraries();
SDKBox.init(this);
-
最后, 我需要提供合适的 overrides 方法的代码。这里有一些约定如下。
-
如果这个被列出的方法没有在
SDKBox
中定义,那么__定义它__。 -
如果这个被列出的方法已经被定义在
SDKBox
中,那么请调用这个在SDKBox
中的__同名方法__。
-
@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 (release模式下可选)
- 编辑
project.properties
文件, 指定一个Proguard
配置文件。比如:
proguard.config=proguard.cfg
- 编辑这个配置文件,加入如下内容:
-keep public class com.mobileapptracker.** {
public *;
}
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
Note: Proguard 只能工作在 Release 模式下 (比如: cocos run -m release
) debug 模式下不会触发 Proguard。