diff --git a/Assets/Adjust/Native/Editor/Dependencies.xml b/Assets/Adjust/Native/Editor/Dependencies.xml
index e810465d..4a585d05 100644
--- a/Assets/Adjust/Native/Editor/Dependencies.xml
+++ b/Assets/Adjust/Native/Editor/Dependencies.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/Assets/Adjust/Native/iOS/AdjustUnity.mm b/Assets/Adjust/Native/iOS/AdjustUnity.mm
index aebcaac7..d11eb5df 100644
--- a/Assets/Adjust/Native/iOS/AdjustUnity.mm
+++ b/Assets/Adjust/Native/iOS/AdjustUnity.mm
@@ -346,16 +346,7 @@ void _AdjustSetPushToken(const char* pushToken) {
void _AdjustProcessDeeplink(const char* deeplink) {
if (deeplink != NULL) {
NSString *strDeeplink = [NSString stringWithUTF8String:deeplink];
- NSURL *urlDeeplink;
- if ([NSString instancesRespondToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) {
- urlDeeplink = [NSURL URLWithString:[strDeeplink stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
- } else {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- urlDeeplink = [NSURL URLWithString:[strDeeplink stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
- }
-#pragma clang diagnostic pop
-
+ NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink];
ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink];
[Adjust processDeeplink:deeplink];
}
@@ -381,6 +372,13 @@ void _AdjustGetAttribution(AdjustDelegateAttributionGetter callback) {
addValueOrEmpty(dictionary, @"costType", attribution.costType);
addValueOrEmpty(dictionary, @"costAmount", attribution.costAmount);
addValueOrEmpty(dictionary, @"costCurrency", attribution.costCurrency);
+
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:attribution.jsonResponse
+ options:0
+ error:nil];
+ NSString *strJsonResponse = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
+ addValueOrEmpty(dictionary, @"jsonResponse", strJsonResponse);
+
NSData *dataAttribution = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
@@ -719,16 +717,7 @@ void _AdjustVerifyAppStorePurchase(const char* transactionId,
void _AdjustProcessAndResolveDeeplink(const char* deeplink, AdjustDelegateResolvedDeeplinkCallback callback) {
if (deeplink != NULL) {
NSString *strDeeplink = [NSString stringWithUTF8String:deeplink];
- NSURL *urlDeeplink;
- if ([NSString instancesRespondToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) {
- urlDeeplink = [NSURL URLWithString:[strDeeplink stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
- } else {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- urlDeeplink = [NSURL URLWithString:[strDeeplink stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
- }
-#pragma clang diagnostic pop
-
+ NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink];
ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink];
[Adjust processAndResolveDeeplink:deeplink withCompletionHandler:^(NSString * _Nullable resolvedLink) {
// TODO: nil checks
diff --git a/Assets/Adjust/Native/iOS/AdjustUnityDelegate.mm b/Assets/Adjust/Native/iOS/AdjustUnityDelegate.mm
index 9ffe284a..4de69a0f 100644
--- a/Assets/Adjust/Native/iOS/AdjustUnityDelegate.mm
+++ b/Assets/Adjust/Native/iOS/AdjustUnityDelegate.mm
@@ -124,6 +124,14 @@ - (void)adjustAttributionChangedWannabe:(ADJAttribution *)attribution {
forKey:@"costCurrency"
toDictionary:dictionary];
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:attribution.jsonResponse
+ options:0
+ error:nil];
+ NSString *strJsonResponse = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
+ [self addValueOrEmpty:strJsonResponse
+ forKey:@"jsonResponse"
+ toDictionary:dictionary];
+
NSData *dataAttribution = [NSJSONSerialization dataWithJSONObject:dictionary
options:0
error:nil];
diff --git a/Assets/Adjust/Scripts/AdjustAndroid.cs b/Assets/Adjust/Scripts/AdjustAndroid.cs
index 8653bea2..b4d6d6cf 100644
--- a/Assets/Adjust/Scripts/AdjustAndroid.cs
+++ b/Assets/Adjust/Scripts/AdjustAndroid.cs
@@ -8,7 +8,7 @@ namespace AdjustSdk
#if UNITY_ANDROID
public class AdjustAndroid
{
- private const string sdkPrefix = "unity5.0.7";
+ private const string sdkPrefix = "unity5.1.0";
private static bool isDeferredDeeplinkOpeningEnabled = true;
private static AndroidJavaClass ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust");
private static AndroidJavaObject ajoCurrentActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic("currentActivity");
@@ -721,7 +721,8 @@ private class AttributionChangedListener : AndroidJavaProxy
{
private Action callback;
- public AttributionChangedListener(Action pCallback) : base("com.adjust.sdk.OnAttributionChangedListener")
+ public AttributionChangedListener(Action pCallback)
+ : base("com.adjust.sdk.OnAttributionChangedListener")
{
this.callback = pCallback;
}
@@ -735,47 +736,56 @@ public void onAttributionChanged(AndroidJavaObject ajoAttribution)
return;
}
- if (ajoAttribution == null)
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
- this.callback(null);
- return;
- }
-
- AdjustAttribution adjustAttribution = new AdjustAttribution();
- string trackerName = ajoAttribution.Get(AdjustUtils.KeyTrackerName);
- adjustAttribution.TrackerName = trackerName == "" ? null : trackerName;
- string trackerToken = ajoAttribution.Get(AdjustUtils.KeyTrackerToken);
- adjustAttribution.TrackerToken = trackerToken == "" ? null : trackerToken;
- string network = ajoAttribution.Get(AdjustUtils.KeyNetwork);
- adjustAttribution.Network = network == "" ? null : network;
- string campaign = ajoAttribution.Get(AdjustUtils.KeyCampaign);
- adjustAttribution.Campaign = campaign == "" ? null : campaign;
- string adgroup = ajoAttribution.Get(AdjustUtils.KeyAdgroup);
- adjustAttribution.Adgroup = adgroup == "" ? null : adgroup;
- string creative = ajoAttribution.Get(AdjustUtils.KeyCreative);
- adjustAttribution.Creative = creative == "" ? null : creative;
- string clickLabel = ajoAttribution.Get(AdjustUtils.KeyClickLabel);
- adjustAttribution.ClickLabel = clickLabel == "" ? null : clickLabel;
- string costType = ajoAttribution.Get(AdjustUtils.KeyCostType);
- adjustAttribution.CostType = costType == "" ? null : costType;
- using (AndroidJavaObject ajoCostAmount = ajoAttribution.Get(AdjustUtils.KeyCostAmount))
- {
- if (ajoCostAmount == null)
+ try
{
- adjustAttribution.CostAmount = null;
+ if (ajoAttribution == null)
+ {
+ if (callback != null)
+ {
+ callback.Invoke(null);
+ }
+ return;
+ }
+
+ AdjustAttribution adjustAttribution = new AdjustAttribution
+ {
+ TrackerName = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyTrackerName)),
+ TrackerToken = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyTrackerToken)),
+ Network = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyNetwork)),
+ Campaign = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCampaign)),
+ Adgroup = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyAdgroup)),
+ Creative = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCreative)),
+ ClickLabel = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyClickLabel)),
+ CostType = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCostType)),
+ CostCurrency = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCostCurrency)),
+ FbInstallReferrer = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer))
+ };
+
+ using (AndroidJavaObject ajoCostAmount = ajoAttribution.Get(AdjustUtils.KeyCostAmount))
+ {
+ adjustAttribution.CostAmount = ajoCostAmount != null ? ajoCostAmount.Call("doubleValue") : (double?)null;
+ }
+
+ string jsonResponse = ajoAttribution.Get(AdjustUtils.KeyJsonResponse);
+ var jsonResponseNode = JSON.Parse(jsonResponse);
+ if (jsonResponseNode != null && jsonResponseNode.AsObject != null)
+ {
+ adjustAttribution.JsonResponse = new Dictionary();
+ AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse);
+ }
+
+ if (callback != null)
+ {
+ callback.Invoke(adjustAttribution);
+ }
}
- else
+ catch (Exception)
{
- double costAmount = ajoCostAmount.Call("doubleValue");
- adjustAttribution.CostAmount = costAmount;
+ // JSON response reading failed.
}
- }
- string costCurrency = ajoAttribution.Get(AdjustUtils.KeyCostCurrency);
- adjustAttribution.CostCurrency = costCurrency == "" ? null : costCurrency;
- string fbInstallReferrer = ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer);
- adjustAttribution.FbInstallReferrer = fbInstallReferrer == "" ? null : fbInstallReferrer;
-
- this.callback(adjustAttribution);
+ });
}
}
@@ -783,7 +793,8 @@ private class DeferredDeeplinkListener : AndroidJavaProxy
{
private Action callback;
- public DeferredDeeplinkListener(Action pCallback) : base("com.adjust.sdk.OnDeferredDeeplinkResponseListener")
+ public DeferredDeeplinkListener(Action pCallback)
+ : base("com.adjust.sdk.OnDeferredDeeplinkResponseListener")
{
this.callback = pCallback;
}
@@ -797,8 +808,15 @@ public bool launchReceivedDeeplink(AndroidJavaObject deeplink)
return isDeferredDeeplinkOpeningEnabled;
}
- string strDeeplink = deeplink.Call("toString");
- callback(strDeeplink);
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ string strDeeplink = deeplink != null ? deeplink.Call("toString") : null;
+ if (callback != null)
+ {
+ callback.Invoke(strDeeplink);
+ }
+ });
+
return isDeferredDeeplinkOpeningEnabled;
}
}
@@ -821,39 +839,40 @@ public void onEventTrackingSucceeded(AndroidJavaObject eventSuccessData)
return;
}
- if (eventSuccessData == null)
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
- this.callback(null);
- return;
- }
-
- AdjustEventSuccess adjustEventSuccess = new AdjustEventSuccess();
- string adid = eventSuccessData.Get(AdjustUtils.KeyAdid);
- adjustEventSuccess.Adid = adid == "" ? null : adid;
- string message = eventSuccessData.Get(AdjustUtils.KeyMessage);
- adjustEventSuccess.Message = message == "" ? null : message;
- string timestamp = eventSuccessData.Get(AdjustUtils.KeyTimestamp);
- adjustEventSuccess.Timestamp = timestamp == "" ? null : timestamp;
- string eventToken = eventSuccessData.Get(AdjustUtils.KeyEventToken);
- adjustEventSuccess.EventToken = eventToken == "" ? null : eventToken;
- string callbackId = eventSuccessData.Get(AdjustUtils.KeyCallbackId);
- adjustEventSuccess.CallbackId = callbackId == "" ? null : callbackId;
- try
- {
- using (AndroidJavaObject ajoJsonResponse = eventSuccessData.Get(AdjustUtils.KeyJsonResponse))
+ try
{
- string jsonResponseString = ajoJsonResponse.Call("toString");
- adjustEventSuccess.BuildJsonResponseFromString(jsonResponseString);
+ AdjustEventSuccess adjustEventSuccess = new AdjustEventSuccess
+ {
+ Adid = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyAdid)),
+ Message = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyMessage)),
+ Timestamp = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyTimestamp)),
+ EventToken = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyEventToken)),
+ CallbackId = AdjustUtils.GetValueOrEmptyToNull(eventSuccessData.Get(AdjustUtils.KeyCallbackId))
+ };
+
+ using (AndroidJavaObject ajoJsonResponse = eventSuccessData.Get(AdjustUtils.KeyJsonResponse))
+ {
+ if (ajoJsonResponse != null)
+ {
+ string jsonResponseString = ajoJsonResponse.Call("toString");
+ adjustEventSuccess.BuildJsonResponseFromString(jsonResponseString);
+ }
+ }
+
+ if (callback != null)
+ {
+ callback.Invoke(adjustEventSuccess);
+ }
}
- }
- catch (Exception)
- {
- // JSON response reading failed.
- // Native Android SDK should send empty JSON object if none available as of v4.12.5.
- // Native Android SDK added special logic to send Unity friendly values as of v4.15.0.
- }
-
- this.callback(adjustEventSuccess);
+ catch (Exception)
+ {
+ // JSON response reading failed.
+ // Native Android SDK should send empty JSON object if none available as of v4.12.5.
+ // Native Android SDK added special logic to send Unity friendly values as of v4.15.0.
+ }
+ });
}
}
@@ -875,40 +894,41 @@ public void onEventTrackingFailed(AndroidJavaObject eventFailureData)
return;
}
- if (eventFailureData == null)
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
- this.callback(null);
- return;
- }
-
- AdjustEventFailure adjustEventFailure = new AdjustEventFailure();
- string adid = eventFailureData.Get(AdjustUtils.KeyAdid);
- adjustEventFailure.Adid = adid == "" ? null : adid;
- string message = eventFailureData.Get(AdjustUtils.KeyMessage);
- adjustEventFailure.Message = message == "" ? null : message;
- adjustEventFailure.WillRetry = eventFailureData.Get(AdjustUtils.KeyWillRetry);
- string timestamp = eventFailureData.Get(AdjustUtils.KeyTimestamp);
- adjustEventFailure.Timestamp = timestamp == "" ? null : timestamp;
- string eventToken = eventFailureData.Get(AdjustUtils.KeyEventToken);
- adjustEventFailure.EventToken = eventToken == "" ? null : eventToken;
- string callbackId = eventFailureData.Get(AdjustUtils.KeyCallbackId);
- adjustEventFailure.CallbackId = callbackId == "" ? null : callbackId;
- try
- {
- using (AndroidJavaObject ajoJsonResponse = eventFailureData.Get(AdjustUtils.KeyJsonResponse))
+ try
{
- string jsonResponseString = ajoJsonResponse.Call("toString");
- adjustEventFailure.BuildJsonResponseFromString(jsonResponseString);
+ AdjustEventFailure adjustEventFailure = new AdjustEventFailure
+ {
+ Adid = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyAdid)),
+ Message = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyMessage)),
+ Timestamp = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyTimestamp)),
+ EventToken = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyEventToken)),
+ CallbackId = AdjustUtils.GetValueOrEmptyToNull(eventFailureData.Get(AdjustUtils.KeyCallbackId)),
+ WillRetry = eventFailureData.Get(AdjustUtils.KeyWillRetry)
+ };
+
+ using (AndroidJavaObject ajoJsonResponse = eventFailureData.Get(AdjustUtils.KeyJsonResponse))
+ {
+ if (ajoJsonResponse != null)
+ {
+ string jsonResponseString = ajoJsonResponse.Call("toString");
+ adjustEventFailure.BuildJsonResponseFromString(jsonResponseString);
+ }
+ }
+
+ if (callback != null)
+ {
+ callback.Invoke(adjustEventFailure);
+ }
}
- }
- catch (Exception)
- {
- // JSON response reading failed.
- // Native Android SDK should send empty JSON object if none available as of v4.12.5.
- // Native Android SDK added special logic to send Unity friendly values as of v4.15.0.
- }
-
- this.callback(adjustEventFailure);
+ catch (Exception)
+ {
+ // JSON response reading failed.
+ // Native Android SDK should send empty JSON object if none available as of v4.12.5.
+ // Native Android SDK added special logic to send Unity friendly values as of v4.15.0.
+ }
+ });
}
}
@@ -916,7 +936,8 @@ private class SessionTrackingSucceededListener : AndroidJavaProxy
{
private Action callback;
- public SessionTrackingSucceededListener(Action pCallback) : base("com.adjust.sdk.OnSessionTrackingSucceededListener")
+ public SessionTrackingSucceededListener(Action pCallback)
+ : base("com.adjust.sdk.OnSessionTrackingSucceededListener")
{
this.callback = pCallback;
}
@@ -930,35 +951,38 @@ public void onSessionTrackingSucceeded(AndroidJavaObject sessionSuccessData)
return;
}
- if (sessionSuccessData == null)
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
- this.callback(null);
- return;
- }
-
- AdjustSessionSuccess adjustSessionSuccess = new AdjustSessionSuccess();
- string adid = sessionSuccessData.Get(AdjustUtils.KeyAdid);
- adjustSessionSuccess.Adid = adid == "" ? null : adid;
- string message = sessionSuccessData.Get(AdjustUtils.KeyMessage);
- adjustSessionSuccess.Message = message == "" ? null : message;
- string timestamp = sessionSuccessData.Get(AdjustUtils.KeyTimestamp);
- adjustSessionSuccess.Timestamp = timestamp == "" ? null : timestamp;
- try
- {
- using (AndroidJavaObject ajoJsonResponse = sessionSuccessData.Get(AdjustUtils.KeyJsonResponse))
+ try
{
- string jsonResponseString = ajoJsonResponse.Call("toString");
- adjustSessionSuccess.BuildJsonResponseFromString(jsonResponseString);
+ AdjustSessionSuccess adjustSessionSuccess = new AdjustSessionSuccess
+ {
+ Adid = AdjustUtils.GetValueOrEmptyToNull(sessionSuccessData.Get(AdjustUtils.KeyAdid)),
+ Message = AdjustUtils.GetValueOrEmptyToNull(sessionSuccessData.Get(AdjustUtils.KeyMessage)),
+ Timestamp = AdjustUtils.GetValueOrEmptyToNull(sessionSuccessData.Get(AdjustUtils.KeyTimestamp))
+ };
+
+ using (AndroidJavaObject ajoJsonResponse = sessionSuccessData.Get(AdjustUtils.KeyJsonResponse))
+ {
+ if (ajoJsonResponse != null)
+ {
+ string jsonResponseString = ajoJsonResponse.Call("toString");
+ adjustSessionSuccess.BuildJsonResponseFromString(jsonResponseString);
+ }
+ }
+
+ if (callback != null)
+ {
+ callback.Invoke(adjustSessionSuccess);
+ }
}
- }
- catch (Exception)
- {
- // JSON response reading failed.
- // Native Android SDK should send empty JSON object if none available as of v4.12.5.
- // Native Android SDK added special logic to send Unity friendly values as of v4.15.0.
- }
-
- this.callback(adjustSessionSuccess);
+ catch (Exception)
+ {
+ // JSON response reading failed.
+ // Native Android SDK should send empty JSON object if none available as of v4.12.5.
+ // Native Android SDK added special logic to send Unity friendly values as of v4.15.0.
+ }
+ });
}
}
@@ -966,7 +990,8 @@ private class SessionTrackingFailedListener : AndroidJavaProxy
{
private Action callback;
- public SessionTrackingFailedListener(Action pCallback) : base("com.adjust.sdk.OnSessionTrackingFailedListener")
+ public SessionTrackingFailedListener(Action pCallback)
+ : base("com.adjust.sdk.OnSessionTrackingFailedListener")
{
this.callback = pCallback;
}
@@ -980,36 +1005,39 @@ public void onSessionTrackingFailed(AndroidJavaObject sessionFailureData)
return;
}
- if (sessionFailureData == null)
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
- this.callback(null);
- return;
- }
-
- AdjustSessionFailure adjustSessionFailure = new AdjustSessionFailure();
- string adid = sessionFailureData.Get(AdjustUtils.KeyAdid);
- adjustSessionFailure.Adid = adid == "" ? null : adid;
- string message = sessionFailureData.Get(AdjustUtils.KeyMessage);
- adjustSessionFailure.Message = message == "" ? null : message;
- adjustSessionFailure.WillRetry = sessionFailureData.Get(AdjustUtils.KeyWillRetry);
- string timestamp = sessionFailureData.Get(AdjustUtils.KeyTimestamp);
- adjustSessionFailure.Timestamp = timestamp == "" ? null : timestamp;
- try
- {
- using (AndroidJavaObject ajoJsonResponse = sessionFailureData.Get(AdjustUtils.KeyJsonResponse))
+ try
{
- string jsonResponseString = ajoJsonResponse.Call("toString");
- adjustSessionFailure.BuildJsonResponseFromString(jsonResponseString);
+ AdjustSessionFailure adjustSessionFailure = new AdjustSessionFailure
+ {
+ Adid = AdjustUtils.GetValueOrEmptyToNull(sessionFailureData.Get(AdjustUtils.KeyAdid)),
+ Message = AdjustUtils.GetValueOrEmptyToNull(sessionFailureData.Get(AdjustUtils.KeyMessage)),
+ Timestamp = AdjustUtils.GetValueOrEmptyToNull(sessionFailureData.Get(AdjustUtils.KeyTimestamp)),
+ WillRetry = sessionFailureData.Get(AdjustUtils.KeyWillRetry)
+ };
+
+ using (AndroidJavaObject ajoJsonResponse = sessionFailureData.Get(AdjustUtils.KeyJsonResponse))
+ {
+ if (ajoJsonResponse != null)
+ {
+ string jsonResponseString = ajoJsonResponse.Call("toString");
+ adjustSessionFailure.BuildJsonResponseFromString(jsonResponseString);
+ }
+ }
+
+ if (callback != null)
+ {
+ callback.Invoke(adjustSessionFailure);
+ }
}
- }
- catch (Exception)
- {
- // JSON response reading failed.
- // Native Android SDK should send empty JSON object if none available as of v4.12.5.
- // Native Android SDK added special logic to send Unity friendly values as of v4.15.0.
- }
-
- this.callback(adjustSessionFailure);
+ catch (Exception)
+ {
+ // JSON response reading failed.
+ // Native Android SDK should send empty JSON object if none available as of v4.12.5.
+ // Native Android SDK added special logic to send Unity friendly values as of v4.15.0.
+ }
+ });
}
}
@@ -1017,7 +1045,8 @@ private class GoogleAdIdReadListener : AndroidJavaProxy
{
private Action callback;
- public GoogleAdIdReadListener(Action pCallback) : base("com.adjust.sdk.OnGoogleAdIdReadListener")
+ public GoogleAdIdReadListener(Action pCallback)
+ : base("com.adjust.sdk.OnGoogleAdIdReadListener")
{
this.callback = pCallback;
}
@@ -1031,7 +1060,13 @@ public void onGoogleAdIdRead(string adid)
return;
}
- this.callback(adid);
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (callback != null)
+ {
+ callback.Invoke(adid);
+ }
+ });
}
}
@@ -1039,7 +1074,8 @@ private class VerificationResultListener : AndroidJavaProxy
{
private Action callback;
- public VerificationResultListener(Action pCallback) : base("com.adjust.sdk.OnPurchaseVerificationFinishedListener")
+ public VerificationResultListener(Action pCallback)
+ : base("com.adjust.sdk.OnPurchaseVerificationFinishedListener")
{
this.callback = pCallback;
}
@@ -1053,18 +1089,36 @@ public void onVerificationFinished(AndroidJavaObject ajoVerificationInfo)
return;
}
- if (ajoVerificationInfo == null)
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
- this.callback(null);
- return;
- }
-
- AdjustPurchaseVerificationResult purchaseVerificationResult = new AdjustPurchaseVerificationResult();
- purchaseVerificationResult.VerificationStatus = ajoVerificationInfo.Get(AdjustUtils.KeyVerificationStatus);
- purchaseVerificationResult.Code = ajoVerificationInfo.Get(AdjustUtils.KeyCode);
- purchaseVerificationResult.Message = ajoVerificationInfo.Get(AdjustUtils.KeyMessage);
-
- this.callback(purchaseVerificationResult);
+ try
+ {
+ if (ajoVerificationInfo == null)
+ {
+ if (callback != null)
+ {
+ callback.Invoke(null);
+ }
+ return;
+ }
+
+ AdjustPurchaseVerificationResult purchaseVerificationResult = new AdjustPurchaseVerificationResult
+ {
+ VerificationStatus = ajoVerificationInfo.Get(AdjustUtils.KeyVerificationStatus),
+ Code = ajoVerificationInfo.Get(AdjustUtils.KeyCode),
+ Message = AdjustUtils.GetValueOrEmptyToNull(ajoVerificationInfo.Get(AdjustUtils.KeyMessage))
+ };
+
+ if (callback != null)
+ {
+ callback.Invoke(purchaseVerificationResult);
+ }
+ }
+ catch (Exception)
+ {
+ // Handle potential errors during the verification process
+ }
+ });
}
}
@@ -1072,7 +1126,8 @@ private class DeeplinkResolutionListener : AndroidJavaProxy
{
private Action callback;
- public DeeplinkResolutionListener(Action pCallback) : base("com.adjust.sdk.OnDeeplinkResolvedListener")
+ public DeeplinkResolutionListener(Action pCallback)
+ : base("com.adjust.sdk.OnDeeplinkResolvedListener")
{
this.callback = pCallback;
}
@@ -1086,7 +1141,13 @@ public void onDeeplinkResolved(string resolvedLink)
return;
}
- this.callback(resolvedLink);
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (callback != null)
+ {
+ callback.Invoke(resolvedLink);
+ }
+ });
}
}
@@ -1094,7 +1155,8 @@ private class AdidReadListener : AndroidJavaProxy
{
private Action callback;
- public AdidReadListener(Action pCallback) : base("com.adjust.sdk.OnAdidReadListener")
+ public AdidReadListener(Action pCallback)
+ : base("com.adjust.sdk.OnAdidReadListener")
{
this.callback = pCallback;
}
@@ -1108,7 +1170,13 @@ public void onAdidRead(string adid)
return;
}
- this.callback(adid);
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (callback != null)
+ {
+ callback.Invoke(adid);
+ }
+ });
}
}
@@ -1116,7 +1184,8 @@ private class AttributionReadListener : AndroidJavaProxy
{
private Action callback;
- public AttributionReadListener(Action pCallback) : base("com.adjust.sdk.OnAttributionReadListener")
+ public AttributionReadListener(Action pCallback)
+ : base("com.adjust.sdk.OnAttributionReadListener")
{
this.callback = pCallback;
}
@@ -1130,47 +1199,56 @@ public void onAttributionRead(AndroidJavaObject ajoAttribution)
return;
}
- if (ajoAttribution == null)
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
- this.callback(null);
- return;
- }
-
- AdjustAttribution adjustAttribution = new AdjustAttribution();
- string trackerName = ajoAttribution.Get(AdjustUtils.KeyTrackerName);
- adjustAttribution.TrackerName = trackerName == "" ? null : trackerName;
- string trackerToken = ajoAttribution.Get(AdjustUtils.KeyTrackerToken);
- adjustAttribution.TrackerToken = trackerToken == "" ? null : trackerToken;
- string network = ajoAttribution.Get(AdjustUtils.KeyNetwork);
- adjustAttribution.Network = network == "" ? null : network;
- string campaign = ajoAttribution.Get(AdjustUtils.KeyCampaign);
- adjustAttribution.Campaign = campaign == "" ? null : campaign;
- string adgroup = ajoAttribution.Get(AdjustUtils.KeyAdgroup);
- adjustAttribution.Adgroup = adgroup == "" ? null : adgroup;
- string creative = ajoAttribution.Get(AdjustUtils.KeyCreative);
- adjustAttribution.Creative = creative == "" ? null : creative;
- string clickLabel = ajoAttribution.Get(AdjustUtils.KeyClickLabel);
- adjustAttribution.ClickLabel = clickLabel == "" ? null : clickLabel;
- string costType = ajoAttribution.Get(AdjustUtils.KeyCostType);
- adjustAttribution.CostType = costType == "" ? null : costType;
- using (AndroidJavaObject ajoCostAmount = ajoAttribution.Get(AdjustUtils.KeyCostAmount))
- {
- if (ajoCostAmount == null)
+ try
{
- adjustAttribution.CostAmount = null;
+ if (ajoAttribution == null)
+ {
+ if (callback != null)
+ {
+ callback.Invoke(null);
+ }
+ return;
+ }
+
+ AdjustAttribution adjustAttribution = new AdjustAttribution
+ {
+ TrackerName = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyTrackerName)),
+ TrackerToken = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyTrackerToken)),
+ Network = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyNetwork)),
+ Campaign = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCampaign)),
+ Adgroup = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyAdgroup)),
+ Creative = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCreative)),
+ ClickLabel = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyClickLabel)),
+ CostType = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCostType)),
+ CostCurrency = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyCostCurrency)),
+ FbInstallReferrer = AdjustUtils.GetValueOrEmptyToNull(ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer))
+ };
+
+ using (AndroidJavaObject ajoCostAmount = ajoAttribution.Get(AdjustUtils.KeyCostAmount))
+ {
+ adjustAttribution.CostAmount = ajoCostAmount != null ? ajoCostAmount.Call("doubleValue") : (double?)null;
+ }
+
+ string jsonResponse = ajoAttribution.Get(AdjustUtils.KeyJsonResponse);
+ var jsonResponseNode = JSON.Parse(jsonResponse);
+ if (jsonResponseNode != null && jsonResponseNode.AsObject != null)
+ {
+ adjustAttribution.JsonResponse = new Dictionary();
+ AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, adjustAttribution.JsonResponse);
+ }
+
+ if (callback != null)
+ {
+ callback.Invoke(adjustAttribution);
+ }
}
- else
+ catch (Exception)
{
- double costAmount = ajoCostAmount.Call("doubleValue");
- adjustAttribution.CostAmount = costAmount;
+ // JSON response reading failed.
}
- }
- string costCurrency = ajoAttribution.Get(AdjustUtils.KeyCostCurrency);
- adjustAttribution.CostCurrency = costCurrency == "" ? null : costCurrency;
- string fbInstallReferrer = ajoAttribution.Get(AdjustUtils.KeyFbInstallReferrer);
- adjustAttribution.FbInstallReferrer = fbInstallReferrer == "" ? null : fbInstallReferrer;
-
- this.callback(adjustAttribution);
+ });
}
}
@@ -1178,7 +1256,8 @@ private class AmazonAdIdReadListener : AndroidJavaProxy
{
private Action callback;
- public AmazonAdIdReadListener(Action pCallback) : base("com.adjust.sdk.OnAmazonAdIdReadListener")
+ public AmazonAdIdReadListener(Action pCallback)
+ : base("com.adjust.sdk.OnAmazonAdIdReadListener")
{
this.callback = pCallback;
}
@@ -1192,7 +1271,13 @@ public void onAmazonAdIdRead(string amazonAdId)
return;
}
- this.callback(amazonAdId);
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (callback != null)
+ {
+ callback.Invoke(amazonAdId);
+ }
+ });
}
}
@@ -1201,7 +1286,8 @@ private class SdkVersionReadListener : AndroidJavaProxy
private Action callback;
private string sdkPrefix;
- public SdkVersionReadListener(Action pCallback, string sdkPrefix) : base("com.adjust.sdk.OnSdkVersionReadListener")
+ public SdkVersionReadListener(Action pCallback, string sdkPrefix)
+ : base("com.adjust.sdk.OnSdkVersionReadListener")
{
this.callback = pCallback;
this.sdkPrefix = sdkPrefix;
@@ -1216,7 +1302,13 @@ public void onSdkVersionRead(string sdkVersion)
return;
}
- this.callback(this.sdkPrefix + "@" + sdkVersion);
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (callback != null)
+ {
+ callback.Invoke(this.sdkPrefix + "@" + sdkVersion);
+ }
+ });
}
}
@@ -1224,7 +1316,8 @@ private class IsEnabledListener : AndroidJavaProxy
{
private Action callback;
- public IsEnabledListener(Action pCallback) : base("com.adjust.sdk.OnIsEnabledListener")
+ public IsEnabledListener(Action pCallback)
+ : base("com.adjust.sdk.OnIsEnabledListener")
{
this.callback = pCallback;
}
@@ -1238,7 +1331,13 @@ public void onIsEnabledRead(bool isEnabled)
return;
}
- this.callback(isEnabled);
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (callback != null)
+ {
+ callback.Invoke(isEnabled);
+ }
+ });
}
}
@@ -1246,7 +1345,8 @@ private class LastDeeplinkListener : AndroidJavaProxy
{
private Action callback;
- public LastDeeplinkListener(Action pCallback) : base("com.adjust.sdk.OnLastDeeplinkReadListener")
+ public LastDeeplinkListener(Action pCallback)
+ : base("com.adjust.sdk.OnLastDeeplinkReadListener")
{
this.callback = pCallback;
}
@@ -1260,14 +1360,14 @@ public void onLastDeeplinkRead(AndroidJavaObject ajoLastDeeplink)
return;
}
- if (ajoLastDeeplink == null)
- {
- this.callback(null);
- }
- else
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
- this.callback(ajoLastDeeplink.Call("toString"));
- }
+ string deeplink = ajoLastDeeplink != null ? ajoLastDeeplink.Call("toString") : null;
+ if (callback != null)
+ {
+ callback.Invoke(deeplink);
+ }
+ });
}
}
}
diff --git a/Assets/Adjust/Scripts/AdjustAttribution.cs b/Assets/Adjust/Scripts/AdjustAttribution.cs
index dad2d92f..261f2ad9 100644
--- a/Assets/Adjust/Scripts/AdjustAttribution.cs
+++ b/Assets/Adjust/Scripts/AdjustAttribution.cs
@@ -15,6 +15,7 @@ public class AdjustAttribution
public string CostType { get; set; }
public double? CostAmount { get; set; }
public string CostCurrency { get; set; }
+ public Dictionary JsonResponse { get; set; }
// Android only
public string FbInstallReferrer { get; set; }
@@ -49,6 +50,14 @@ public AdjustAttribution(string jsonString)
}
this.CostCurrency = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyCostCurrency);
this.FbInstallReferrer = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyFbInstallReferrer);
+
+ string jsonResponseString = AdjustUtils.GetJsonString(jsonNode, AdjustUtils.KeyJsonResponse);
+ var jsonResponseNode = JSON.Parse(jsonResponseString);
+ if (jsonResponseNode != null && jsonResponseNode.AsObject != null)
+ {
+ this.JsonResponse = new Dictionary();
+ AdjustUtils.WriteJsonResponseDictionary(jsonResponseNode.AsObject, this.JsonResponse);
+ }
}
public AdjustAttribution(Dictionary dicAttributionData)
diff --git a/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs
new file mode 100644
index 00000000..26157f36
--- /dev/null
+++ b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class AdjustThreadDispatcher : MonoBehaviour
+{
+ private static readonly Queue executionQueue = new Queue();
+ private static AdjustThreadDispatcher instance;
+
+ public static void RunOnMainThread(Action action)
+ {
+ if (action == null)
+ {
+ return;
+ }
+
+ lock (executionQueue)
+ {
+ executionQueue.Enqueue(action);
+ }
+ }
+
+ private void Update()
+ {
+ while (executionQueue.Count > 0)
+ {
+ Action action;
+ lock (executionQueue)
+ {
+ action = executionQueue.Dequeue();
+ }
+ if (action != null)
+ {
+ action.Invoke();
+ }
+ }
+ }
+
+ [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+ private static void Initialize()
+ {
+ if (instance == null)
+ {
+ GameObject obj = new GameObject("AdjustThreadDispatcher");
+ instance = obj.AddComponent();
+ DontDestroyOnLoad(obj);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs.meta b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs.meta
new file mode 100644
index 00000000..fe68f179
--- /dev/null
+++ b/Assets/Adjust/Scripts/AdjustThreadDispatcher.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 068759bba95d0411895637c9165b2f99
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Adjust/Scripts/AdjustUtils.cs b/Assets/Adjust/Scripts/AdjustUtils.cs
index 0925de4a..6793be98 100644
--- a/Assets/Adjust/Scripts/AdjustUtils.cs
+++ b/Assets/Adjust/Scripts/AdjustUtils.cs
@@ -350,6 +350,11 @@ public static Dictionary GetSkanUpdateDataDictionary(string skan
return skanUpdateDataDictionary;
}
+ public static string GetValueOrEmptyToNull(string value)
+ {
+ return string.IsNullOrEmpty(value) ? null : value;
+ }
+
#if UNITY_ANDROID
public static AndroidJavaObject TestOptionsMap2AndroidJavaObject(Dictionary testOptionsMap, AndroidJavaObject ajoCurrentActivity)
{
diff --git a/Assets/Adjust/Scripts/AdjustiOS.cs b/Assets/Adjust/Scripts/AdjustiOS.cs
index 05065b9a..1b4c398c 100644
--- a/Assets/Adjust/Scripts/AdjustiOS.cs
+++ b/Assets/Adjust/Scripts/AdjustiOS.cs
@@ -8,7 +8,7 @@ namespace AdjustSdk
#if UNITY_IOS
public class AdjustiOS
{
- private const string sdkPrefix = "unity5.0.7";
+ private const string sdkPrefix = "unity5.1.0";
// app callbacks as method parameters
private static List> appIsEnabledGetterCallbacks;
@@ -694,192 +694,345 @@ public static void TrackSubsessionEnd(string testingArgument = null)
// MonoPInvokeCallback methods as method parameters
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateIsEnabledGetter))]
- private static void IsEnabledGetterMonoPInvoke(bool isEnabled) {
- if (appIsEnabledGetterCallbacks != null)
+ private static void IsEnabledGetterMonoPInvoke(bool isEnabled)
+ {
+ if (appIsEnabledGetterCallbacks == null)
+ {
+ return;
+ }
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
foreach (Action callback in appIsEnabledGetterCallbacks)
{
- callback(isEnabled);
+ if (callback != null)
+ {
+ callback.Invoke(isEnabled);
+ }
}
appIsEnabledGetterCallbacks.Clear();
- }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttributionGetter))]
- private static void AttributionGetterMonoPInvoke(string attribution) {
- if (appAttributionGetterCallbacks != null)
+ private static void AttributionGetterMonoPInvoke(string attribution)
+ {
+ if (appAttributionGetterCallbacks == null)
+ {
+ return;
+ }
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
foreach (Action callback in appAttributionGetterCallbacks)
{
- callback(new AdjustAttribution(attribution));
+ if (callback != null)
+ {
+ callback.Invoke(new AdjustAttribution(attribution));
+ }
}
appAttributionGetterCallbacks.Clear();
- }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateAdidGetter))]
- private static void AdidGetterMonoPInvoke(string adid) {
- if (appAdidGetterCallbacks != null)
+ private static void AdidGetterMonoPInvoke(string adid)
+ {
+ if (appAdidGetterCallbacks == null)
+ {
+ return;
+ }
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
foreach (Action callback in appAdidGetterCallbacks)
{
- callback(adid);
+ if (callback != null)
+ {
+ callback.Invoke(adid);
+ }
}
appAdidGetterCallbacks.Clear();
- }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateIdfaGetter))]
- private static void IdfaGetterMonoPInvoke(string idfa) {
- if (appIdfaGetterCallbacks != null)
+ private static void IdfaGetterMonoPInvoke(string idfa)
+ {
+ if (appIdfaGetterCallbacks == null)
+ {
+ return;
+ }
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
foreach (Action callback in appIdfaGetterCallbacks)
{
- callback(idfa);
+ if (callback != null)
+ {
+ callback.Invoke(idfa);
+ }
}
appIdfaGetterCallbacks.Clear();
- }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateIdfvGetter))]
- private static void IdfvGetterMonoPInvoke(string idfv) {
- if (appIdfvGetterCallbacks != null)
+ private static void IdfvGetterMonoPInvoke(string idfv)
+ {
+ if (appIdfvGetterCallbacks == null)
{
- foreach (Action callback in appIdfaGetterCallbacks)
+ return;
+ }
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ foreach (Action callback in appIdfvGetterCallbacks)
{
- callback(idfv);
+ if (callback != null)
+ {
+ callback.Invoke(idfv);
+ }
}
appIdfvGetterCallbacks.Clear();
- }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateLastDeeplinkGetter))]
- private static void LastDeeplinkGetterMonoPInvoke(string lastDeeplink) {
- if (appLastDeeplinkGetterCallbacks != null)
+ private static void LastDeeplinkGetterMonoPInvoke(string lastDeeplink)
+ {
+ if (appLastDeeplinkGetterCallbacks == null)
+ {
+ return;
+ }
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
foreach (Action callback in appLastDeeplinkGetterCallbacks)
{
- callback(lastDeeplink);
+ if (callback != null)
+ {
+ callback.Invoke(lastDeeplink);
+ }
}
appLastDeeplinkGetterCallbacks.Clear();
- }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateSdkVersionGetter))]
- private static void SdkVersionGetterMonoPInvoke(string sdkVersion) {
- if (appSdkVersionGetterCallbacks != null)
+ private static void SdkVersionGetterMonoPInvoke(string sdkVersion)
+ {
+ if (appSdkVersionGetterCallbacks == null)
+ {
+ return;
+ }
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
foreach (Action callback in appSdkVersionGetterCallbacks)
{
- callback(sdkPrefix + "@" + sdkVersion);
+ if (callback != null)
+ {
+ callback.Invoke(sdkPrefix + "@" + sdkVersion);
+ }
}
appSdkVersionGetterCallbacks.Clear();
- }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttCallback))]
- private static void AttCallbackMonoPInvoke(int status) {
- if (appAttCallbacks != null)
+ private static void AttCallbackMonoPInvoke(int status)
+ {
+ if (appAttCallbacks == null)
+ {
+ return;
+ }
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
{
foreach (Action callback in appAttCallbacks)
{
- callback(status);
+ if (callback != null)
+ {
+ callback.Invoke(status);
+ }
}
appAttCallbacks.Clear();
- }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegatePurchaseVerificationCallback))]
- private static void PurchaseVerificationCallbackMonoPInvoke(string verificationResult) {
- if (appPurchaseVerificationCallback != null)
+ private static void PurchaseVerificationCallbackMonoPInvoke(string verificationResult)
+ {
+ if (appPurchaseVerificationCallback == null)
{
- appPurchaseVerificationCallback(new AdjustPurchaseVerificationResult(verificationResult));
- appPurchaseVerificationCallback = null;
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (appPurchaseVerificationCallback != null)
+ {
+ appPurchaseVerificationCallback.Invoke(new AdjustPurchaseVerificationResult(verificationResult));
+ appPurchaseVerificationCallback = null;
+ }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateVerifyAndTrackCallback))]
- private static void VerifyAndTrackCallbackMonoPInvoke(string verificationResult) {
- if (appVerifyAndTrackCallback != null)
+ private static void VerifyAndTrackCallbackMonoPInvoke(string verificationResult)
+ {
+ if (appVerifyAndTrackCallback == null)
{
- appVerifyAndTrackCallback(new AdjustPurchaseVerificationResult(verificationResult));
- appVerifyAndTrackCallback = null;
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (appVerifyAndTrackCallback != null)
+ {
+ appVerifyAndTrackCallback.Invoke(new AdjustPurchaseVerificationResult(verificationResult));
+ appVerifyAndTrackCallback = null;
+ }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateResolvedDeeplinkCallback))]
- private static void ResolvedDeeplinkCallbackMonoPInvoke(string deeplink) {
- if (appResolvedDeeplinkCallback != null)
+ private static void ResolvedDeeplinkCallbackMonoPInvoke(string deeplink)
+ {
+ if (appResolvedDeeplinkCallback == null)
{
- appResolvedDeeplinkCallback(deeplink);
- appResolvedDeeplinkCallback = null;
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (appResolvedDeeplinkCallback != null)
+ {
+ appResolvedDeeplinkCallback.Invoke(deeplink);
+ appResolvedDeeplinkCallback = null;
+ }
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateSkanErrorCallback))]
- private static void SkanErrorCallbackMonoPInvoke(string error) {
- if (appSkanErrorCallback != null)
+ private static void SkanErrorCallbackMonoPInvoke(string error)
+ {
+ if (appSkanErrorCallback == null)
{
- appSkanErrorCallback(error);
- appSkanErrorCallback = null;
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (appSkanErrorCallback != null)
+ {
+ appSkanErrorCallback.Invoke(error);
+ appSkanErrorCallback = null;
+ }
+ });
}
// MonoPInvokeCallback methods as subscriptions
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateAttributionCallback))]
- private static void AttributionCallbackMonoPInvoke(string attribution) {
- if (appAttributionCallback != null)
+ private static void AttributionCallbackMonoPInvoke(string attribution)
+ {
+ if (appAttributionCallback == null)
{
- appAttributionCallback(new AdjustAttribution(attribution));
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ appAttributionCallback(new AdjustAttribution(attribution));
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateSessionSuccessCallback))]
- private static void SessionSuccessCallbackMonoPInvoke(string sessionSuccess) {
- if (appSessionSuccessCallback != null)
+ private static void SessionSuccessCallbackMonoPInvoke(string sessionSuccess)
+ {
+ if (appSessionSuccessCallback == null)
{
- appSessionSuccessCallback(new AdjustSessionSuccess(sessionSuccess));
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ appSessionSuccessCallback(new AdjustSessionSuccess(sessionSuccess));
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateSessionFailureCallback))]
- private static void SessionFailureCallbackMonoPInvoke(string sessionFailure) {
- if (appSessionFailureCallback != null)
+ private static void SessionFailureCallbackMonoPInvoke(string sessionFailure)
+ {
+ if (appSessionFailureCallback == null)
{
- appSessionFailureCallback(new AdjustSessionFailure(sessionFailure));
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ appSessionFailureCallback(new AdjustSessionFailure(sessionFailure));
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateEventSuccessCallback))]
- private static void EventSuccessCallbackMonoPInvoke(string eventSuccess) {
- if (appEventSuccessCallback != null)
+ private static void EventSuccessCallbackMonoPInvoke(string eventSuccess)
+ {
+ if (appEventSuccessCallback == null)
{
- appEventSuccessCallback(new AdjustEventSuccess(eventSuccess));
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ appEventSuccessCallback(new AdjustEventSuccess(eventSuccess));
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateEventFailureCallback))]
- private static void EventFailureCallbackMonoPInvoke(string eventFailure) {
- if (appEventFailureCallback != null)
+ private static void EventFailureCallbackMonoPInvoke(string eventFailure)
+ {
+ if (appEventFailureCallback == null)
{
- appEventFailureCallback(new AdjustEventFailure(eventFailure));
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ appEventFailureCallback(new AdjustEventFailure(eventFailure));
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateDeferredDeeplinkCallback))]
- private static void DeferredDeeplinkCallbackMonoPInvoke(string deeplink) {
- if (appDeferredDeeplinkCallback != null)
+ private static void DeferredDeeplinkCallbackMonoPInvoke(string deeplink)
+ {
+ if (appDeferredDeeplinkCallback == null)
{
- appDeferredDeeplinkCallback(deeplink);
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ appDeferredDeeplinkCallback(deeplink);
+ });
}
[AOT.MonoPInvokeCallback(typeof(AdjustDelegateSkanUpdatedCallback))]
- private static void SkanUpdatedCallbackMonoPInvoke(string skanData) {
- if (appSkanUpdatedCallback != null)
+ private static void SkanUpdatedCallbackMonoPInvoke(string skanData)
+ {
+ if (appSkanUpdatedCallback == null)
{
- appSkanUpdatedCallback(AdjustUtils.GetSkanUpdateDataDictionary(skanData));
+ return;
}
+
+ AdjustThreadDispatcher.RunOnMainThread(() =>
+ {
+ if (appSkanUpdatedCallback != null)
+ {
+ appSkanUpdatedCallback.Invoke(AdjustUtils.GetSkanUpdateDataDictionary(skanData));
+ }
+ });
}
}
#endif
diff --git a/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs b/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs
index 7d39e3c2..753630f4 100644
--- a/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs
+++ b/Assets/Adjust/Scripts/Editor/AdjustEditorPreprocessor.cs
@@ -11,11 +11,11 @@
namespace AdjustSdk
{
- #if UNITY_2018_1_OR_NEWER
+#if UNITY_2018_1_OR_NEWER
public class AdjustEditorPreprocessor : IPreprocessBuildWithReport
- #else
+#else
public class AdjustEditorPreprocessor : IPreprocessBuild
- #endif
+#endif
{
public int callbackOrder
{
@@ -24,24 +24,24 @@ public int callbackOrder
return 0;
}
}
- #if UNITY_2018_1_OR_NEWER
+#if UNITY_2018_1_OR_NEWER
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{
OnPreprocessBuild(report.summary.platform, string.Empty);
}
- #endif
+#endif
public void OnPreprocessBuild(BuildTarget target, string path)
{
if (target == BuildTarget.Android)
{
- #if UNITY_ANDROID
+#if UNITY_ANDROID
RunPostProcessTasksAndroid();
- #endif
+#endif
}
}
- #if UNITY_ANDROID
+#if UNITY_ANDROID
private static void RunPostProcessTasksAndroid()
{
var isAdjustManifestUsed = false;
@@ -117,9 +117,16 @@ private static bool AddURISchemes(XmlDocument manifest)
}
Debug.Log("[Adjust]: Start addition of URI schemes");
- var intentRoot = manifest.DocumentElement.SelectSingleNode("/manifest/application/activity[@android:name='com.unity3d.player.UnityPlayerActivity']", GetNamespaceManager(manifest));
+ // Check if user has defined a custom Android activity name.
+ string androidActivityName = "com.unity3d.player.UnityPlayerActivity";
+ if (AdjustSettings.AndroidCustomActivityName.Length != 0)
+ {
+ androidActivityName = AdjustSettings.AndroidCustomActivityName;
+ }
+
+ var intentRoot = manifest.DocumentElement.SelectSingleNode("/manifest/application/activity[@android:name='"
+ + androidActivityName + "']", GetNamespaceManager(manifest));
var usedIntentFiltersChanged = false;
- var usedIntentFilters = GetIntentFilter(manifest);
foreach (var uriScheme in AdjustSettings.AndroidUriSchemes)
{
Uri uri;
@@ -141,54 +148,46 @@ private static bool AddURISchemes(XmlDocument manifest)
continue;
}
- if (!IsIntentFilterAlreadyExist(manifest, uri))
+ if (!DoesIntentFilterAlreadyExist(manifest, uri))
{
Debug.Log("[Adjust]: Adding new URI with scheme: " + uri.Scheme + ", and host: " + uri.Host);
+ var newIntentFilter = GetNewIntentFilter(manifest);
var androidSchemeNode = manifest.CreateElement("data");
AddAndroidNamespaceAttribute(manifest, "scheme", uri.Scheme, androidSchemeNode);
AddAndroidNamespaceAttribute(manifest, "host", uri.Host, androidSchemeNode);
- usedIntentFilters.AppendChild(androidSchemeNode);
- usedIntentFiltersChanged = true;
-
+ newIntentFilter.AppendChild(androidSchemeNode);
+ intentRoot.AppendChild(newIntentFilter);
Debug.Log(string.Format("[Adjust]: Android deeplink URI scheme \"{0}\" successfully added to your app's AndroidManifest.xml file.", uriScheme));
+ usedIntentFiltersChanged = true;
}
}
- if (usedIntentFiltersChanged && usedIntentFilters.ParentNode == null)
- {
- intentRoot.AppendChild(usedIntentFilters);
- }
-
return usedIntentFiltersChanged;
}
- private static XmlElement GetIntentFilter(XmlDocument manifest)
+ private static XmlElement GetNewIntentFilter(XmlDocument manifest)
{
- var xpath = "/manifest/application/activity/intent-filter[data/@android:scheme and data/@android:host]";
- var intentFilter = manifest.DocumentElement.SelectSingleNode(xpath, GetNamespaceManager(manifest)) as XmlElement;
- if (intentFilter == null)
- {
- const string androidName = "name";
- const string category = "category";
+ const string androidName = "name";
+ const string category = "category";
- intentFilter = manifest.CreateElement("intent-filter");
+ var intentFilter = manifest.CreateElement("intent-filter");
- var actionElement = manifest.CreateElement("action");
- AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.action.VIEW", actionElement);
- intentFilter.AppendChild(actionElement);
+ var actionElement = manifest.CreateElement("action");
+ AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.action.VIEW", actionElement);
+ intentFilter.AppendChild(actionElement);
- var defaultCategory = manifest.CreateElement(category);
- AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.DEFAULT", defaultCategory);
- intentFilter.AppendChild(defaultCategory);
+ var defaultCategory = manifest.CreateElement(category);
+ AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.DEFAULT", defaultCategory);
+ intentFilter.AppendChild(defaultCategory);
+
+ var browsableCategory = manifest.CreateElement(category);
+ AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.BROWSABLE", browsableCategory);
+ intentFilter.AppendChild(browsableCategory);
- var browsableCategory = manifest.CreateElement(category);
- AddAndroidNamespaceAttribute(manifest, androidName, "android.intent.category.BROWSABLE", browsableCategory);
- intentFilter.AppendChild(browsableCategory);
- }
return intentFilter;
}
- private static bool IsIntentFilterAlreadyExist(XmlDocument manifest, Uri link)
+ private static bool DoesIntentFilterAlreadyExist(XmlDocument manifest, Uri link)
{
var xpath = string.Format("/manifest/application/activity/intent-filter/data[@android:scheme='{0}' and @android:host='{1}']", link.Scheme, link.Host);
return manifest.DocumentElement.SelectSingleNode(xpath, GetNamespaceManager(manifest)) != null;
@@ -363,6 +362,6 @@ private static XmlNamespaceManager GetNamespaceManager(XmlDocument manifest)
namespaceManager.AddNamespace("android", "http://schemas.android.com/apk/res/android");
return namespaceManager;
}
- #endif
-}
+#endif
+ }
}
diff --git a/Assets/Adjust/Scripts/Editor/AdjustSettings.cs b/Assets/Adjust/Scripts/Editor/AdjustSettings.cs
index 6953ce24..b4d620b7 100644
--- a/Assets/Adjust/Scripts/Editor/AdjustSettings.cs
+++ b/Assets/Adjust/Scripts/Editor/AdjustSettings.cs
@@ -38,6 +38,8 @@ public class AdjustSettings : ScriptableObject
private string[] _iOSUniversalLinksDomains = new string[0];
[SerializeField]
private string[] androidUriSchemes = new string[0];
+ [SerializeField]
+ private string _androidCustomActivityName;
public static AdjustSettings Instance
{
@@ -182,5 +184,11 @@ public static string[] AndroidUriSchemes
get { return Instance.androidUriSchemes; }
set { Instance.androidUriSchemes = value; }
}
+
+ public static string AndroidCustomActivityName
+ {
+ get { return Instance._androidCustomActivityName; }
+ set { Instance._androidCustomActivityName = value; }
+ }
}
}
diff --git a/Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs b/Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs
index bde2addd..0bafe024 100644
--- a/Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs
+++ b/Assets/Adjust/Scripts/Editor/AdjustSettingsEditor.cs
@@ -20,6 +20,7 @@ public class AdjustSettingsEditor : Editor
SerializedProperty iOSUrlSchemes;
SerializedProperty iOSUniversalLinksDomains;
SerializedProperty androidUriSchemes;
+ SerializedProperty androidCustomActivityName;
void OnEnable()
{
@@ -36,6 +37,7 @@ void OnEnable()
iOSUrlSchemes = serializedObject.FindProperty("_iOSUrlSchemes");
iOSUniversalLinksDomains = serializedObject.FindProperty("_iOSUniversalLinksDomains");
androidUriSchemes = serializedObject.FindProperty("androidUriSchemes");
+ androidCustomActivityName = serializedObject.FindProperty("_androidCustomActivityName");
}
public override void OnInspectorGUI()
{
@@ -92,6 +94,15 @@ public override void OnInspectorGUI()
true);
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
+ EditorGUILayout.LabelField("ANDROID ACTIVITY NAME:", darkerCyanTextFieldStyles);
+ EditorGUI.indentLevel += 1;
+ EditorGUILayout.PropertyField(androidCustomActivityName,
+ new GUIContent("Custom Android Activity Name",
+ "In case you are using custom activity instead of the default Unity activity " +
+ "(com.unity3d.player.UnityPlayerActivity), please specify it's full name."),
+ true);
+ EditorGUI.indentLevel -= 1;
+ EditorGUILayout.Space();
EditorGUILayout.LabelField("DEEP LINKING:", darkerCyanTextFieldStyles);
EditorGUI.indentLevel += 1;
EditorGUILayout.PropertyField(iOSUrlIdentifier,
diff --git a/Assets/Adjust/package.json b/Assets/Adjust/package.json
index e5d96d98..a4fdff35 100644
--- a/Assets/Adjust/package.json
+++ b/Assets/Adjust/package.json
@@ -1,6 +1,6 @@
{
"name": "com.adjust.sdk",
- "version": "5.0.7",
+ "version": "5.1.0",
"unity": "2019.4",
"displayName": "Adjust",
"license": "MIT",
diff --git a/Assets/Test/Scripts/CommandExecutor.cs b/Assets/Test/Scripts/CommandExecutor.cs
index a51dd732..308ec989 100644
--- a/Assets/Test/Scripts/CommandExecutor.cs
+++ b/Assets/Test/Scripts/CommandExecutor.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using UnityEngine;
+using Newtonsoft.Json;
namespace AdjustSdk.Test
{
@@ -368,6 +369,15 @@ private void Config()
_testLibrary.AddInfoToSend("cost_amount", attribution.CostAmount.ToString());
_testLibrary.AddInfoToSend("cost_currency", attribution.CostCurrency);
_testLibrary.AddInfoToSend("fb_install_referrer", attribution.FbInstallReferrer);
+ var updatedJsonResponse = new Dictionary(attribution.JsonResponse);
+#if UNITY_IOS
+ updatedJsonResponse.Remove("fb_install_referrer");
+ if (updatedJsonResponse.TryGetValue("cost_amount", out var costAmount) && costAmount is IConvertible)
+ {
+ updatedJsonResponse["cost_amount"] = string.Format("{0:0.00}", System.Convert.ToDouble(costAmount));
+ }
+#endif
+ _testLibrary.AddInfoToSend("json_response", JsonConvert.SerializeObject(updatedJsonResponse));
_testLibrary.SendInfoToServer(localExtraPath);
});
}
@@ -959,6 +969,15 @@ private void AttributionGetter()
_testLibrary.AddInfoToSend("cost_amount", attribution.CostAmount.ToString());
_testLibrary.AddInfoToSend("cost_currency", attribution.CostCurrency);
_testLibrary.AddInfoToSend("fb_install_referrer", attribution.FbInstallReferrer);
+ var updatedJsonResponse = new Dictionary(attribution.JsonResponse);
+#if UNITY_IOS
+ updatedJsonResponse.Remove("fb_install_referrer");
+ if (updatedJsonResponse.TryGetValue("cost_amount", out var costAmount) && costAmount is IConvertible)
+ {
+ updatedJsonResponse["cost_amount"] = string.Format("{0:0.00}", System.Convert.ToDouble(costAmount));
+ }
+#endif
+ _testLibrary.AddInfoToSend("json_response", JsonConvert.SerializeObject(updatedJsonResponse));
_testLibrary.SendInfoToServer(localExtraPath);
});
}
diff --git a/Assets/Test/TestApp/TestApp.cs b/Assets/Test/TestApp/TestApp.cs
index 38595621..d832c737 100644
--- a/Assets/Test/TestApp/TestApp.cs
+++ b/Assets/Test/TestApp/TestApp.cs
@@ -11,11 +11,11 @@ public class TestApp : MonoBehaviour
#if UNITY_ANDROID
private const string PORT = ":8443";
private const string PROTOCOL = "https://";
- private const string IP = "192.168.86.99";
+ private const string IP = "192.168.8.207";
#elif UNITY_IOS
private const string PORT = ":8080";
private const string PROTOCOL = "http://";
- private const string IP = "192.168.86.99";
+ private const string IP = "192.168.8.207";
private TestLibraryiOS _testLibraryiOS;
#else
private const string PORT = ":8080";
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 73e5c4ea..9672bd96 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,18 @@
+### Version 5.1.0 (28th February 2025)
+#### Added
+- Added `JsonResponse` to `AdjustAttribution` where every key-value pair sent by the backend as part of the attribution response can be found.
+- Added the ability to specify the name of custom Android activity which you might be using instead of the default `com.unity3d.player.UnityPlayerActivity` (https://github.com/adjust/unity_sdk/issues/273).
+
+#### Changed
+- Switched to adding `` per specified Android URI scheme instead of adding them all as `` entries to the same intent filter (https://github.com/adjust/unity_sdk/issues/266).
+- Moved execution of all the C# callbacks into the main Unity thread (https://github.com/adjust/unity_sdk/issues/277, https://github.com/adjust/unity_sdk/issues/310).
+
+#### Native SDKs
+- [iOS@v5.1.1][ios_sdk_v5.1.1]
+- [Android@v5.1.0][android_sdk_v5.1.0]
+
+---
+
### Version 5.0.7 (4th February 2025)
#### Added
- Added sending of the additional parameter to improve troubleshooting of `SKAdNetwork` related issues.
@@ -1369,6 +1384,7 @@ Kudos to [Ivan](https://github.com/MatkovIvan) and [Evgeny](https://github.com/e
[ios_sdk_v5.0.0]: https://github.com/adjust/ios_sdk/tree/v5.0.0
[ios_sdk_v5.0.1]: https://github.com/adjust/ios_sdk/tree/v5.0.1
[ios_sdk_v5.1.0]: https://github.com/adjust/ios_sdk/tree/v5.1.0
+[ios_sdk_v5.1.1]: https://github.com/adjust/ios_sdk/tree/v5.1.1
[android_sdk_v3.5.0]: https://github.com/adjust/android_sdk/tree/v3.5.0
[android_sdk_v4.1.0]: https://github.com/adjust/android_sdk/tree/v4.1.0
diff --git a/VERSION b/VERSION
index 00433367..831446cb 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.0.7
+5.1.0