Skip to content

Commit

Permalink
Merge pull request #25 from AppsFlyerSDK/RD-72648/updateIos6.4.4&more
Browse files Browse the repository at this point in the history
Rd 72648/update ios6.4.4&more
  • Loading branch information
GM-appsflyer authored Dec 12, 2021
2 parents 9e4e2f9 + a353a2a commit 584635f
Show file tree
Hide file tree
Showing 19 changed files with 123 additions and 40 deletions.
5 changes: 4 additions & 1 deletion AppsFlyerSDK/Source/AppsFlyerSDK/AppsFlyer_UPL.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
dependencies {
implementation 'com.android.installreferrer:installreferrer:1.0'
implementation 'com.appsflyer:af-android-sdk:6.4.2'
implementation 'com.appsflyer:af-android-sdk:6.4.3'
}
</insert>
</buildGradleAdditions>
Expand Down Expand Up @@ -61,6 +61,9 @@
return AppsFlyerLib.getInstance().getAppsFlyerUID(this);
}

public void afSetAdditionalData(Map&lt;String, Object&gt; customData) {
AppsFlyerLib.getInstance().setAdditionalData(customData);
}
</insert>
</gameActivityClassAdditions>
</root>
81 changes: 60 additions & 21 deletions AppsFlyerSDK/Source/AppsFlyerSDK/Private/AppsFlyerSDKBlueprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,16 @@ void UAppsFlyerSDKBlueprint::configure()
{
const UAppsFlyerSDKSettings *defaultSettings = GetDefault<UAppsFlyerSDKSettings>();
const bool isDebug = defaultSettings->bIsDebug;

const bool isAutoStart = defaultSettings->bEnableAutoStart;
#if PLATFORM_ANDROID
JNIEnv* env = FAndroidApplication::GetJavaEnv();
jmethodID appsflyer =
FJavaWrapper::FindMethod(env, FJavaWrapper::GameActivityClassID, "afStart", "(Ljava/lang/String;Z)V", false);
jstring key = env->NewStringUTF(TCHAR_TO_UTF8(*defaultSettings->appsFlyerDevKey));

FJavaWrapper::CallVoidMethod(env, FJavaWrapper::GameActivityThis, appsflyer, key, isDebug);
if(isAutoStart){
JNIEnv* env = FAndroidApplication::GetJavaEnv();
jmethodID appsflyer =
FJavaWrapper::FindMethod(env, FJavaWrapper::GameActivityClassID, "afStart", "(Ljava/lang/String;Z)V", false);
jstring key = env->NewStringUTF(TCHAR_TO_UTF8(*defaultSettings->appsFlyerDevKey));

FJavaWrapper::CallVoidMethod(env, FJavaWrapper::GameActivityThis, appsflyer, key, isDebug);
}

#elif PLATFORM_IOS
dispatch_async(dispatch_get_main_queue(), ^ {
Expand All @@ -151,7 +152,7 @@ void UAppsFlyerSDKBlueprint::configure()
if (!AppsFlyerIsEmptyValue(currencyCode)) {
[AppsFlyerLib shared].currencyCode = currencyCode;
}

FIOSCoreDelegates::OnOpenURL.AddStatic(&OnOpenURL);
UE4AFSDKDelegate *delegate = [[UE4AFSDKDelegate alloc] init];
delegate.onConversionDataSuccess = onConversionDataSuccess;
Expand All @@ -169,31 +170,41 @@ void UAppsFlyerSDKBlueprint::configure()
}

UE_LOG(LogAppsFlyerSDKBlueprint, Display, TEXT("AppsFlyer: UE4 ready"));

[[AppsFlyerLib shared] start];
[[NSNotificationCenter defaultCenter] addObserverForName: UIApplicationWillEnterForegroundNotification
object: nil
queue: nil
usingBlock: ^ (NSNotification * note) {
UE_LOG(LogAppsFlyerSDKBlueprint, Display, TEXT("UIApplicationWillEnterForegroundNotification"));
if(isAutoStart){
[[AppsFlyerLib shared] start];
}];
[[NSNotificationCenter defaultCenter] addObserverForName: UIApplicationWillEnterForegroundNotification
object: nil
queue: nil
usingBlock: ^ (NSNotification * note) {
UE_LOG(LogAppsFlyerSDKBlueprint, Display, TEXT("UIApplicationWillEnterForegroundNotification"));
[[AppsFlyerLib shared] start];
}];
}
}
});
#endif
}

void UAppsFlyerSDKBlueprint::start() {
const UAppsFlyerSDKSettings *defaultSettings = GetDefault<UAppsFlyerSDKSettings>();
const bool isDebug = defaultSettings->bIsDebug;
#if PLATFORM_ANDROID
JNIEnv* env = FAndroidApplication::GetJavaEnv();
jmethodID start = FJavaWrapper::FindMethod(env,
FJavaWrapper::GameActivityClassID,
"afStartLaunch",
"()V", false);
FJavaWrapper::CallVoidMethod(env, FJavaWrapper::GameActivityThis, start);
jmethodID start =
FJavaWrapper::FindMethod(env, FJavaWrapper::GameActivityClassID, "afStart", "(Ljava/lang/String;Z)V", false);
jstring key = env->NewStringUTF(TCHAR_TO_UTF8(*defaultSettings->appsFlyerDevKey));

FJavaWrapper::CallVoidMethod(env, FJavaWrapper::GameActivityThis, start, key, isDebug);
#elif PLATFORM_IOS
dispatch_async(dispatch_get_main_queue(), ^ {
static id observer;
[[AppsFlyerLib shared] start];
if (!observer) {
observer = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillEnterForegroundNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
UE_LOG(LogAppsFlyerSDKBlueprint, Display, TEXT("UIApplicationWillEnterForegroundNotification"));
[[AppsFlyerLib shared] start];
}];
}
});
#endif
}
Expand Down Expand Up @@ -311,4 +322,32 @@ void UAppsFlyerSDKBlueprint::setRemoteNotificationsToken(const TArray<uint8>& to
#endif
}

void UAppsFlyerSDKBlueprint::setAdditionalData(TMap <FString, FString> customData) {

#if PLATFORM_ANDROID
JNIEnv* env = FAndroidApplication::GetJavaEnv();
jmethodID setAdditionalData = FJavaWrapper::FindMethod(env,
FJavaWrapper::GameActivityClassID,
"afSetAdditionalData",
"(Ljava/util/Map;)V", false);
jclass mapClass = env->FindClass("java/util/HashMap");
jmethodID mapConstructor = env->GetMethodID(mapClass, "<init>", "()V");
jobject map = env->NewObject(mapClass, mapConstructor);
jmethodID putMethod = env->GetMethodID(mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
for (const TPair<FString, FString>& pair : customData) {
env->CallObjectMethod(map, putMethod, env->NewStringUTF(TCHAR_TO_UTF8(*pair.Key)), env->NewStringUTF(TCHAR_TO_UTF8(*pair.Value)));
}
FJavaWrapper::CallVoidMethod(env, FJavaWrapper::GameActivityThis, setAdditionalData, map);
return;
#elif PLATFORM_IOS
dispatch_async(dispatch_get_main_queue(), ^ {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
for (const TPair<FString, FString>& pair : customData) {
[dictionary setValue:pair.Value.GetNSString() forKey:pair.Key.GetNSString()];
}
[[AppsFlyerLib shared] setAdditionalData:dictionary];
});
#else
return;
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ UAppsFlyerSDKSettings::UAppsFlyerSDKSettings(const FObjectInitializer& ObjectIni
, bIsDebug(false)
, currencyCode("")
, bDisableSKAdNetwork(false)
, bEnableAutoStart(true)
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ class APPSFLYERSDK_API UAppsFlyerSDKBlueprint : public UBlueprintFunctionLibrary
UFUNCTION(BlueprintCallable, Category = AppsFlyerSDK, DisplayName = "Set AppsFlyerSDK Remote Notifications Token")
static void setRemoteNotificationsToken(const TArray<uint8>& token);


UFUNCTION(BlueprintCallable, Category = AppsFlyerSDK, DisplayName = "AppsFlyerSDK add custom data to events in the payload")
static void setAdditionalData(TMap <FString, FString> customData);

};
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,8 @@ class UAppsFlyerSDKSettings : public UObject
// Disable SKAdNetwork
UPROPERTY(Config, EditAnywhere, config, Category = "AppsFlyer", meta = (DisplayName = "Disable SKAdNetwork(Only iOS)"))
bool bDisableSKAdNetwork;

// Enable AppsFlyerSDK automatic start
UPROPERTY(Config, EditAnywhere, config, Category = "AppsFlyer", meta = (DisplayName = "Automatically start the AppsFlyer SDK"))
bool bEnableAutoStart;
};
Binary file not shown.
1 change: 1 addition & 0 deletions Demo/Config/DefaultEngine.ini
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ appleAppID=1427570452
bIsDebug=True
bDisableSKAdNetwork=False
currencyCode=GBP
bEnableAutoStart=False

[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]
PackageName=com.appsflyer.ue4template
Expand Down
Binary file modified Demo/Content/Actor123_Blueprint.uasset
Binary file not shown.
Binary file modified Demo/Content/ThirdPersonCPP/Maps/ThirdPersonExampleMap.umap
Binary file not shown.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Unreal AppsFlyer Plugin

v6.4.2
v6.4.4

🛠 In order for us to provide optimal support, we would kindly ask you to submit any issues to support@appsflyer.com

Expand All @@ -17,18 +17,20 @@ v6.4.2
- [Setup](#setup)
- [Guides & API](/docs/Guides.md)
- [Init SDK](/docs/Guides.md#init-sdk)
- [Start](/docs/Guides.md#start)
- [Log Event](/docs/Guides.md#inappevent)
- [Get AppsFlyerUID](/docs/Guides.md#appsflyeruid)
- [Set Custom User Id](/docs/Guides.md#customid)
- [Uninstall tracking](/docs/Guides.md#uninstall)
- [Set Additional Data](/docs/Guides.md#setAdditionalData)
- [DeepLinking](/docs/Guides.md#deeplinking)
- [Demo](#demo)


### <a id="plugin-build-for"> This plugin is built for

- iOS AppsFlyerSDK **v6.4.2**
- Android AppsFlyerSDK **v6.4.2**
- iOS AppsFlyerSDK **v6.4.4**
- Android AppsFlyerSDK **v6.4.3**


## <a id="installation">📲Installation
Expand Down
55 changes: 42 additions & 13 deletions docs/Guides.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,44 @@
## Table of content

- [Init SDK](#init-sdk)
- [Start](#start)
- [Log Event](#inappevent)
- [Get AppsFlyerUID](#appsflyeruid)
- [Set Custom User Id](#customid)
- [Uninstall tracking](#uninstall)
- [iOS Uninstall](#iOSUninstall)
- [Android Uninstall](#androidUninstall)
- [Set Additional Data](#setAdditionalData)
- [DeepLinking](#deeplinking)
- [Deferred Deep Linking (Get Conversion Data)](#deferred-deep-linking)
- [Direct Deeplinking](#handle-deeplinking)
- [Android Deeplink Setup](#android-deeplink)
- [iOS Deeplink Setup](#ios-deeplink)
- [Demo](#demo)


## <a id="init-sdk"> Init SDK

<img src="./ScreenShots/ProjectSettings2.png" width="650">

* **dev key** - Found under App Settings in your AppsFlyer Dashboard.
* **app id** - app id from the itunes store (without the 'id' prefix)
* **is debug** - Used to dub to AppsFlyer SDK. (Development Only!)
* **Dev key** - Found under App Settings in your AppsFlyer Dashboard.
* **App id** - app id from the itunes store (without the 'id' prefix)
* **Is debug** - Used to dub to AppsFlyer SDK. (Development Only!). Once this is set up the AppsFlyer SDK can log all Installs and Sessions.

* **Currency Code (only iOS)** - Defines the app currency method

* **Disable SKAdNetwork(Only iOS)** - Disable SKAdNetwork sessions

* **Automatically start the AppsFlyer SDK** - When set to true, the SDK will be sending a session automatically (before Blueprint events). If set to false, it's the developer responsability to call the start API from the Blueprint.

## <a id="start"> Start

* Starts the SDK by sending the session to the server.

* As a default, the start method is being called automatically once the app is being launch.

* If needed, this setting can be disabled in the Plugin settings, and the developer can call the start method under the blueprint. When doing so, the SDK will send a session on every background-foreground transition.
<img src="./ScreenShots/autoStartOff.png" width="400">

Once this is set up the AppsFlyer SDK can log all **Installs** and **Sessions**.

## <a id="inappevent"> Log Event


Expand All @@ -53,10 +67,15 @@ To receive unique AppsFlyer ID per app installation you can use this blueprint:

Setting your own Custom ID enables you to cross-reference your own unique ID with AppsFlyer’s user ID and the other devices’ IDs. This ID is available in AppsFlyer CSV reports along with postbacks APIs for cross-referencing with you internal IDs.

**IMPORTANT**: If you want to have CUID in the install record, you need to set it before SDK send out first launch. If implemented as per screenshot above it will happen before the launch is sent. For more details please check out this articles: [iOS](https://support.appsflyer.com/hc/en-us/articles/207032066-iOS-SDK-integration-for-developers#additional-apis) and [Android](https://support.appsflyer.com/hc/en-us/articles/207032126-Android-SDK-integration-for-developers#additional-apis-set-customer-user-id).

<img src="./ScreenShots/CustomUserId.png" width="1100">

**IMPORTANT**: In order for the user ID to be define in the first SDK session, please follow these steps:

1. Set the `Automatically start the AppsFlyer SDK` flag under the plugin setting to false.
<img src="./ScreenShots/autoStartOff.png" width="500">

2. Call the `Set Custom User ID` API before the call to the `Start` API under the Blueprint:

## <a id="uninstall"> Uninstall

AppsFlyer uses silent push notifications, once a day, to verify if an app is still installed on a given device. If there is no response, an uninstall is recorded, and it's attributed to the media source that originally brought the user.
Expand All @@ -70,25 +89,21 @@ First, make sure to read the relevant information regarding [uninstall feature i
1. To support remote notification in IOS follow the [official unreal docs](https://docs.unrealengine.com/4.27/en-US/SharingAndReleasing/Mobile/LocalNotifications).

Don't forget to [download, compile and run Unreal Engine from the source](https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/DownloadingSourceCode) .

<img src="./ScreenShots/buildingFromSource.png" width="1100">

Find more information in the



2. After the Unreal engine is running, open the Unreal IDE and go to settings > platforms -> iOS -> enable the remote notification support checkbox.

<img src="./ScreenShots/iOSenableRemoteNotification.png" width="1100">


3. Under the setting -> Maps & Mods -> Game instance -> change the instance class to PlatformGameInstance

<img src="./ScreenShots/gameInstance.png" width="1100">


4. Configure the nodes under the relevant blueprint:

<img src="./ScreenShots/nodeEvents.png" width="1100">

- **Register for remote notification** Will show a pop-up to the user from the OS, asking permission for remote notification
Expand Down Expand Up @@ -127,10 +142,24 @@ For Android make sure to complete the steps in the [following article](https://s
```

4. Same nodes could be used (as in iOS) for Android under the relevant blueprint (no API call needed).

<img src="./ScreenShots/nodeEvents.png" width="1100">


## <a id="setAdditionalData"> Set Additional Data

Use to add custom key-value pairs to the payload of each event, including installs. These values will appear in raw-data reports.

<img src="./ScreenShots/setAdditionalData.png" width="500">


**IMPORTANT** In order for the additional data to be included in the first SDK session, please follow these steps:

1. Set the `Automatically start the AppsFlyer SDK` under the plugin setting to false.
<img src="./ScreenShots/autoStartOff.png" width="500">

2. Call the `setAdditionalData` API before the call to the `Start` API:
<img src="./ScreenShots/setAdditionalDataBeforeStart.png" width="500">

## <a id="deeplinking"> Deep Linking

![alt text](https://massets.appsflyer.com/wp-content/uploads/2018/03/21101417/app-installed-Recovered.png "")
Expand Down
4 changes: 2 additions & 2 deletions docs/RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Release type: **Major** / Minor / Hotfix
* void afSetCustomerUserId(String id)
* void void afLogEvent(String eventName, Map<String, Object> eventValues)

- Android SDK to v4.9.0
- Android SDK to v6.4.3

- iOS SDK to v4.9.0
- iOS SDK to v6.4.4

Binary file modified docs/ScreenShots/ProjectSettings2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/ScreenShots/autoStartOff.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/ScreenShots/autoStartOn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/ScreenShots/disableAutoStart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/ScreenShots/setAdditionalData.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/ScreenShots/setAdditionalDataBeforeStart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/ScreenShots/startManually.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 584635f

Please sign in to comment.