diff --git a/Assets/Adjust/Android/AdjustAndroid.cs b/Assets/Adjust/Android/AdjustAndroid.cs index fdaa33ba..791afd6f 100644 --- a/Assets/Adjust/Android/AdjustAndroid.cs +++ b/Assets/Adjust/Android/AdjustAndroid.cs @@ -8,7 +8,7 @@ namespace com.adjust.sdk #if UNITY_ANDROID public class AdjustAndroid { - private const string sdkPrefix = "unity4.36.0"; + private const string sdkPrefix = "unity4.37.0"; private static bool launchDeferredDeeplink = true; private static AndroidJavaClass ajcAdjust = new AndroidJavaClass("com.adjust.sdk.Adjust"); private static AndroidJavaObject ajoCurrentActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic("currentActivity"); @@ -19,6 +19,7 @@ public class AdjustAndroid private static SessionTrackingFailedListener onSessionTrackingFailedListener; private static SessionTrackingSucceededListener onSessionTrackingSucceededListener; private static VerificationInfoListener onVerificationInfoListener; + private static DeeplinkResolutionListener onDeeplinkResolvedListener; public static void Start(AdjustConfig adjustConfig) { @@ -684,6 +685,14 @@ public static void VerifyPlayStorePurchase(AdjustPlayStorePurchase purchase, Act ajcAdjust.CallStatic("verifyPurchase", ajoPurchase, onVerificationInfoListener); } + public static void ProcessDeeplink(string url, Action resolvedLinkCallback) + { + onDeeplinkResolvedListener = new DeeplinkResolutionListener(resolvedLinkCallback); + AndroidJavaClass ajcUri = new AndroidJavaClass("android.net.Uri"); + AndroidJavaObject ajoUri = ajcUri.CallStatic("parse", url); + ajcAdjust.CallStatic("processDeeplink", ajoUri, ajoCurrentActivity, onDeeplinkResolvedListener); + } + // Used for testing only. public static void SetTestOptions(Dictionary testOptions) { @@ -1024,6 +1033,24 @@ public void onVerificationFinished(AndroidJavaObject verificationInfo) } } + private class DeeplinkResolutionListener : AndroidJavaProxy + { + private Action callback; + + public DeeplinkResolutionListener(Action pCallback) : base("com.adjust.sdk.OnDeeplinkResolvedListener") + { + this.callback = pCallback; + } + + public void onDeeplinkResolved(string resolvedLink) + { + if (callback != null) + { + callback(resolvedLink); + } + } + } + // Private & helper methods. private static bool IsAppSecretSet(AdjustConfig adjustConfig) { diff --git a/Assets/Adjust/Android/Test/adjust-test-library.aar b/Assets/Adjust/Android/Test/adjust-test-library.aar index c4b08c6e..3d024c92 100644 Binary files a/Assets/Adjust/Android/Test/adjust-test-library.aar and b/Assets/Adjust/Android/Test/adjust-test-library.aar differ diff --git a/Assets/Adjust/Android/adjust-android.jar b/Assets/Adjust/Android/adjust-android.jar index c07b4bfd..4bf3808f 100644 Binary files a/Assets/Adjust/Android/adjust-android.jar and b/Assets/Adjust/Android/adjust-android.jar differ diff --git a/Assets/Adjust/Test/CommandExecutor.cs b/Assets/Adjust/Test/CommandExecutor.cs index f75de0bb..395a6889 100644 --- a/Assets/Adjust/Test/CommandExecutor.cs +++ b/Assets/Adjust/Test/CommandExecutor.cs @@ -82,6 +82,7 @@ public void ExecuteCommand(Command command) case "trackAdRevenueV2": TrackAdRevenueV2(); break; case "getLastDeeplink": GetLastDeeplink(); break; case "verifyPurchase": VerifyPurchase(); break; + case "processDeeplink": ProcessDeeplink(); break; default: CommandNotFound(_command.ClassName, _command.MethodName); break; } } @@ -1010,6 +1011,12 @@ private void VerifyPurchase() #endif } + private void ProcessDeeplink() + { + var deeplink = _command.GetFirstParameterValue("deeplink"); + Adjust.processDeeplink(deeplink, DeeplinkResolvedCallback); + } + // helper methods private void VerificationInfoCallback(AdjustPurchaseVerificationInfo verificationInfo) @@ -1021,6 +1028,13 @@ private void VerificationInfoCallback(AdjustPurchaseVerificationInfo verificatio _testLibrary.SendInfoToServer(localExtraPath); } + private void DeeplinkResolvedCallback(string resolvedLink) + { + string localExtraPath = ExtraPath; + _testLibrary.AddInfoToSend("resolved_link", resolvedLink); + _testLibrary.SendInfoToServer(localExtraPath); + } + private void CommandNotFound(string className, string methodName) { TestApp.Log("Adjust Test: Method '" + methodName + "' not found for class '" + className + "'"); diff --git a/Assets/Adjust/Unity/Adjust.cs b/Assets/Adjust/Unity/Adjust.cs index fc7ef1dc..269adf7d 100644 --- a/Assets/Adjust/Unity/Adjust.cs +++ b/Assets/Adjust/Unity/Adjust.cs @@ -86,6 +86,7 @@ public class Adjust : MonoBehaviour private static Action skadUpdateConversionValueDelegate = null; private static Action skad4UpdateConversionValueDelegate = null; private static Action verificationInfoDelegate = null; + private static Action deeplinkResolutionDelegate = null; #endif void Awake() @@ -959,6 +960,28 @@ public static void verifyPlayStorePurchase( #endif } + public static void processDeeplink( + string url, + Action resolvedLinkDelegate, + string sceneName = "Adjust") + { + if (IsEditor()) + { + return; + } + +#if UNITY_IOS + Adjust.deeplinkResolutionDelegate = resolvedLinkDelegate; + AdjustiOS.ProcessDeeplink(url, sceneName); +#elif UNITY_ANDROID + AdjustAndroid.ProcessDeeplink(url, resolvedLinkDelegate); +#elif (UNITY_WSA || UNITY_WP8) + Debug.Log("[Adjust]: Deep link processing is only supported for Android and iOS platform."); +#else + Debug.Log(errorMsgPlatform); +#endif + } + #if UNITY_IOS public void GetNativeAttribution(string attributionData) { @@ -1178,6 +1201,22 @@ public void GetNativeVerificationInfo(string verificationInfoData) var verificationInfo = new AdjustPurchaseVerificationInfo(verificationInfoData); Adjust.verificationInfoDelegate(verificationInfo); } + + public void GetNativeResolvedLink(string resolvedLink) + { + if (IsEditor()) + { + return; + } + + if (Adjust.deeplinkResolutionDelegate == null) + { + Debug.Log("[Adjust]: Deep link reoslution delegate was not set."); + return; + } + + Adjust.deeplinkResolutionDelegate(resolvedLink); + } #endif private static bool IsEditor() diff --git a/Assets/Adjust/Unity/AdjustConfig.cs b/Assets/Adjust/Unity/AdjustConfig.cs index e3629d8e..d2994982 100644 --- a/Assets/Adjust/Unity/AdjustConfig.cs +++ b/Assets/Adjust/Unity/AdjustConfig.cs @@ -43,6 +43,7 @@ public class AdjustConfig internal bool? playStoreKidsAppEnabled; internal bool? allowSuppressLogLevel; internal bool? needsCost; + internal bool? readDeviceInfoOnceEnabled; internal bool launchDeferredDeeplink; internal AdjustLogLevel? logLevel; internal AdjustEnvironment environment; @@ -62,7 +63,6 @@ public class AdjustConfig internal string preinstallFilePath; internal bool? finalAndroidAttributionEnabled; internal string fbAppId; - internal bool? readDeviceInfoOnceEnabled; // iOS specific members internal bool? allowAdServicesInfoReading; internal bool? allowIdfaReading; diff --git a/Assets/Adjust/Unity/AdjustEvent.cs b/Assets/Adjust/Unity/AdjustEvent.cs index 7382beb0..f4e87ce3 100644 --- a/Assets/Adjust/Unity/AdjustEvent.cs +++ b/Assets/Adjust/Unity/AdjustEvent.cs @@ -15,6 +15,7 @@ public class AdjustEvent internal List callbackList; // iOS specific members internal string receipt; + internal string receiptBase64; internal bool isReceiptSet; // Android specific members internal string purchaseToken; @@ -81,6 +82,11 @@ public void setReceipt(string receipt) this.receipt = receipt; } + public void setReceiptBase64(string receiptBase64) + { + this.receiptBase64 = receiptBase64; + } + // Android specific methods public void setPurchaseToken(string purchaseToken) { diff --git a/Assets/Adjust/Windows/AdjustWindows.cs b/Assets/Adjust/Windows/AdjustWindows.cs index 4a798261..54e7ddac 100644 --- a/Assets/Adjust/Windows/AdjustWindows.cs +++ b/Assets/Adjust/Windows/AdjustWindows.cs @@ -17,7 +17,7 @@ namespace com.adjust.sdk { public class AdjustWindows { - private const string sdkPrefix = "unity4.36.0"; + private const string sdkPrefix = "unity4.37.0"; private static bool appLaunched = false; public static void Start(AdjustConfig adjustConfig) diff --git a/Assets/Adjust/iOS/ADJConfig.h b/Assets/Adjust/iOS/ADJConfig.h index d07993a5..e9b916e8 100644 --- a/Assets/Adjust/iOS/ADJConfig.h +++ b/Assets/Adjust/iOS/ADJConfig.h @@ -291,4 +291,9 @@ */ @property (nonatomic, assign) BOOL coppaCompliantEnabled; +/** + * @brief Enables caching of device ids to read it only once + */ +@property (nonatomic, assign) BOOL readDeviceInfoOnceEnabled; + @end diff --git a/Assets/Adjust/iOS/Adjust.h b/Assets/Adjust/iOS/Adjust.h index 361cd830..1bc08856 100644 --- a/Assets/Adjust/iOS/Adjust.h +++ b/Assets/Adjust/iOS/Adjust.h @@ -2,7 +2,7 @@ // Adjust.h // Adjust SDK // -// V4.36.0 +// V4.37.0 // Created by Christian Wellenbrock (@wellle) on 23rd July 2013. // Copyright (c) 2012-2021 Adjust GmbH. All rights reserved. // @@ -17,6 +17,8 @@ #import "ADJPurchase.h" #import "ADJPurchaseVerificationResult.h" +typedef void(^AdjustResolvedDeeplinkBlock)(NSString * _Nonnull resolvedLink); + @interface AdjustTestOptions : NSObject @property (nonatomic, copy, nullable) NSString *baseUrl; @@ -137,6 +139,15 @@ extern NSString * __nonnull const ADJDataResidencyUS; */ + (void)appWillOpenUrl:(nonnull NSURL *)url; +/** + * @brief Process the deep link that has opened an app and potentially get a resolved link. + * + * @param deeplink URL object which contains info about adjust deep link. + * @param completionHandler Completion handler where either resolved or echoed deep link will be sent. + */ ++ (void)processDeeplink:(nonnull NSURL *)deeplink + completionHandler:(void (^_Nonnull)(NSString * _Nonnull resolvedLink))completionHandler; + /** * @brief Set the device token used by push notifications. * @@ -407,6 +418,9 @@ extern NSString * __nonnull const ADJDataResidencyUS; - (void)appWillOpenUrl:(nonnull NSURL *)url; +- (void)processDeeplink:(nonnull NSURL *)deeplink + completionHandler:(void (^_Nonnull)(NSString * _Nonnull resolvedLink))completionHandler; + - (void)setOfflineMode:(BOOL)enabled; - (void)setDeviceToken:(nonnull NSData *)deviceToken; diff --git a/Assets/Adjust/iOS/AdjustSdk.a b/Assets/Adjust/iOS/AdjustSdk.a index fca3d712..046badd8 100644 Binary files a/Assets/Adjust/iOS/AdjustSdk.a and b/Assets/Adjust/iOS/AdjustSdk.a differ diff --git a/Assets/Adjust/iOS/AdjustUnity.mm b/Assets/Adjust/iOS/AdjustUnity.mm index 033c748d..2c472c9b 100644 --- a/Assets/Adjust/iOS/AdjustUnity.mm +++ b/Assets/Adjust/iOS/AdjustUnity.mm @@ -101,6 +101,7 @@ void _AdjustLaunchApp(const char* appToken, int linkMeEnabled, int needsCost, int coppaCompliant, + int readDeviceInfoOnce, int64_t secretId, int64_t info1, int64_t info2, @@ -222,6 +223,11 @@ void _AdjustLaunchApp(const char* appToken, [adjustConfig setCoppaCompliantEnabled:(BOOL)coppaCompliant]; } + // Read device info just once. + if (readDeviceInfoOnce != -1) { + [adjustConfig setReadDeviceInfoOnceEnabled:(BOOL)readDeviceInfoOnce]; + } + // User agent. if (stringUserAgent != nil) { [adjustConfig setUserAgent:stringUserAgent]; @@ -270,6 +276,7 @@ void _AdjustTrackEvent(const char* eventToken, double revenue, const char* currency, const char* receipt, + const char* receiptBase64, const char* productId, const char* transactionId, const char* callbackId, @@ -324,6 +331,14 @@ void _AdjustTrackEvent(const char* eventToken, [event setReceipt:[stringReceipt dataUsingEncoding:NSUTF8StringEncoding]]; } + // Base64 encoded receipt. + if (receiptBase64 != NULL) { + // If both (receipt and receiptBase64) set, receiptBase64 will be used. + NSString *stringReceiptBase64 = [NSString stringWithUTF8String:receiptBase64]; + NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:stringReceiptBase64 options:0]; + [event setReceipt:decodedData]; + } + // Callback ID. if (callbackId != NULL) { NSString *stringCallbackId = [NSString stringWithUTF8String:callbackId]; @@ -881,6 +896,33 @@ void _AdjustVerifyAppStorePurchase(const char* transactionId, }]; } + void _AdjustProcessDeeplink(const char* url, const char* sceneName) { + NSString *strSceneName = isStringValid(sceneName) == true ? [NSString stringWithUTF8String:sceneName] : nil; + if (url != NULL) { + NSString *stringUrl = [NSString stringWithUTF8String:url]; + NSURL *nsUrl; + if ([NSString instancesRespondToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) { + nsUrl = [NSURL URLWithString:[stringUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]]; + } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + nsUrl = [NSURL URLWithString:[stringUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + } +#pragma clang diagnostic pop + + [Adjust processDeeplink:nsUrl completionHandler:^(NSString * _Nonnull resolvedLink) { + if (strSceneName == nil) { + return; + } + if (resolvedLink == nil) { + return; + } + const char* resolvedLinkCString = [resolvedLink UTF8String]; + UnitySendMessage([strSceneName UTF8String], "GetNativeResolvedLink", resolvedLinkCString); + }]; + } + } + void _AdjustSetTestOptions(const char* baseUrl, const char* gdprUrl, const char* subscriptionUrl, diff --git a/Assets/Adjust/iOS/AdjustiOS.cs b/Assets/Adjust/iOS/AdjustiOS.cs index 17fe6448..6cc9307b 100644 --- a/Assets/Adjust/iOS/AdjustiOS.cs +++ b/Assets/Adjust/iOS/AdjustiOS.cs @@ -8,7 +8,7 @@ namespace com.adjust.sdk #if UNITY_IOS public class AdjustiOS { - private const string sdkPrefix = "unity4.36.0"; + private const string sdkPrefix = "unity4.37.0"; [DllImport("__Internal")] private static extern void _AdjustLaunchApp( @@ -31,6 +31,7 @@ private static extern void _AdjustLaunchApp( int linkMeEnabled, int needsCost, int coppaCompliant, + int readDeviceInfoOnce, long secretId, long info1, long info2, @@ -54,6 +55,7 @@ private static extern void _AdjustTrackEvent( double revenue, string currency, string receipt, + string receiptBase64, string productId, string transactionId, string callbackId, @@ -201,6 +203,9 @@ private static extern void _AdjustVerifyAppStorePurchase( string receipt, string sceneName); + [DllImport("__Internal")] + private static extern void _AdjustProcessDeeplink(string url, string sceneName); + public AdjustiOS() {} public static void Start(AdjustConfig adjustConfig) @@ -231,6 +236,7 @@ public static void Start(AdjustConfig adjustConfig) int linkMeEnabled = AdjustUtils.ConvertBool(adjustConfig.linkMeEnabled); int needsCost = AdjustUtils.ConvertBool(adjustConfig.needsCost); int coppaCompliant = AdjustUtils.ConvertBool(adjustConfig.coppaCompliantEnabled); + int readDeviceInfoOnce = AdjustUtils.ConvertBool(adjustConfig.readDeviceInfoOnceEnabled); int isAttributionCallbackImplemented = AdjustUtils.ConvertBool(adjustConfig.getAttributionChangedDelegate() != null); int isEventSuccessCallbackImplemented = AdjustUtils.ConvertBool(adjustConfig.getEventSuccessDelegate() != null); int isEventFailureCallbackImplemented = AdjustUtils.ConvertBool(adjustConfig.getEventFailureDelegate() != null); @@ -260,6 +266,7 @@ public static void Start(AdjustConfig adjustConfig) linkMeEnabled, needsCost, coppaCompliant, + readDeviceInfoOnce, secretId, info1, info2, @@ -285,13 +292,25 @@ public static void TrackEvent(AdjustEvent adjustEvent) string eventToken = adjustEvent.eventToken; string currency = adjustEvent.currency; string receipt = adjustEvent.receipt; + string receiptBase64 = adjustEvent.receiptBase64; string productId = adjustEvent.productId; string transactionId = adjustEvent.transactionId; string callbackId = adjustEvent.callbackId; string stringJsonCallbackParameters = AdjustUtils.ConvertListToJson(adjustEvent.callbackList); string stringJsonPartnerParameters = AdjustUtils.ConvertListToJson(adjustEvent.partnerList); - _AdjustTrackEvent(eventToken, revenue, currency, receipt, productId, transactionId, callbackId, isReceiptSet, stringJsonCallbackParameters, stringJsonPartnerParameters); + _AdjustTrackEvent( + eventToken, + revenue, + currency, + receipt, + receiptBase64, + productId, + transactionId, + callbackId, + isReceiptSet, + stringJsonCallbackParameters, + stringJsonPartnerParameters); } public static void SetEnabled(bool enabled) @@ -526,6 +545,11 @@ public static void VerifyAppStorePurchase(AdjustAppStorePurchase purchase, strin cSceneName); } + public static void ProcessDeeplink(string url, string sceneName) + { + _AdjustProcessDeeplink(url, sceneName); + } + // Used for testing only. public static void SetTestOptions(Dictionary testOptions) { diff --git a/Assets/AdjustOaid/Android/adjust-android-oaid.jar b/Assets/AdjustOaid/Android/adjust-android-oaid.jar index 4934f514..35b2b2dd 100644 Binary files a/Assets/AdjustOaid/Android/adjust-android-oaid.jar and b/Assets/AdjustOaid/Android/adjust-android-oaid.jar differ diff --git a/CHANGELOG.md b/CHANGELOG.md index a35471e7..47d5645a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ -### Version 4.35.2 (24th November 2023) +### Version 4.37.0 (16th January 2024) #### Added +- Added ability to process shortened deep links and provide the unshortened link back as a response. You can achieve this by invoking `processDeeplink` method of the `Adjust` instance. +- Added ability to inject iOS in-app purchase receipt directly as base64 encoded string when you are performing purchase event verification. You can achieve this by passing the base64 encoded string receipt via `setReceiptBase64` method of the `AdjustEvent` instance. + +#### Native SDKs +- [iOS@v4.37.0][ios_sdk_v4.37.0] +- [Android@v4.38.0][android_sdk_v4.38.0] +- [Windows@v4.17.0][windows_sdk_v4.17.0] +--- + +### Version 4.36.0 (24th November 2023) +#### Added +- Added ability to get IDFV value of the iOS device. You can achieve this by invoking `getIdfv()` method of the `Adjust` instance. - Added support for Meta install referrer. - Added support for Google Play Games on PC. - Added support for `TopOn` and `AD(X)` ad revenue tracking. @@ -1185,6 +1197,7 @@ Kudos to [Ivan](https://github.com/MatkovIvan) and [Evgeny](https://github.com/e [ios_sdk_v4.35.1]: https://github.com/adjust/ios_sdk/tree/v4.35.1 [ios_sdk_v4.35.2]: https://github.com/adjust/ios_sdk/tree/v4.35.2 [ios_sdk_v4.36.0]: https://github.com/adjust/ios_sdk/tree/v4.36.0 +[ios_sdk_v4.37.0]: https://github.com/adjust/ios_sdk/tree/v4.37.0 [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 @@ -1233,6 +1246,7 @@ Kudos to [Ivan](https://github.com/MatkovIvan) and [Evgeny](https://github.com/e [android_sdk_v4.35.0]: https://github.com/adjust/android_sdk/tree/v4.35.0 [android_sdk_v4.35.1]: https://github.com/adjust/android_sdk/tree/v4.35.1 [android_sdk_v4.37.0]: https://github.com/adjust/android_sdk/tree/v4.37.0 +[android_sdk_v4.38.0]: https://github.com/adjust/android_sdk/tree/v4.38.0 [windows_sdk_v4.12.0]: https://github.com/adjust/windows_sdk/tree/v4.12.0 [windows_sdk_v4.13.0]: https://github.com/adjust/windows_sdk/tree/v4.13.0 diff --git a/VERSION b/VERSION index 05ca23e8..69c42762 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.36.0 +4.37.0 diff --git a/doc/english/migration/migrate.md b/doc/english/migration/migrate.md index bece0b3e..79720683 100644 --- a/doc/english/migration/migrate.md +++ b/doc/english/migration/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for Unity3d to 4.36.0 from 3.4.4 +## Migrate your Adjust SDK for Unity3d to 4.37.0 from 3.4.4 ### Migration procedure diff --git a/ext/android/sdk b/ext/android/sdk index 6c5b44f4..6b58557f 160000 --- a/ext/android/sdk +++ b/ext/android/sdk @@ -1 +1 @@ -Subproject commit 6c5b44f42a7116ec02562c2319abe0a95a81c5c4 +Subproject commit 6b58557f18d886a1392d0cc245a90d4bca880c6e diff --git a/ext/ios/sdk b/ext/ios/sdk index 54096650..f7a0ad4a 160000 --- a/ext/ios/sdk +++ b/ext/ios/sdk @@ -1 +1 @@ -Subproject commit 54096650288c5c4411a24c5594e28f033a77aff7 +Subproject commit f7a0ad4a9f99fcbfc4c73dcad557ea3c86c5aaf6