From 5ea28136a9cd06dffa095f12ab591a275e4603bf Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Thu, 17 Nov 2022 13:12:39 +0600 Subject: [PATCH 01/22] Android native part updates supported. --- Editor/QonversionDependencies.xml | 4 +- .../unitywrapper/AutomationsWrapper.java | 50 +++++++++++++- .../unitywrapper/QonversionWrapper.java | 69 +++++++------------ Runtime/Android/QonversionWrapperAndroid.cs | 12 ++-- Runtime/Scripts/IQonversionWrapper.cs | 6 +- Runtime/Scripts/Qonversion.cs | 34 ++++----- Runtime/Scripts/QonversionWrapperNoop.cs | 6 +- Runtime/iOS/QonversionWrapperIOS.cs | 8 +-- package.json | 3 +- 9 files changed, 109 insertions(+), 83 deletions(-) diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml index 1f6fd83..694dad8 100644 --- a/Editor/QonversionDependencies.xml +++ b/Editor/QonversionDependencies.xml @@ -1,11 +1,11 @@ - + - + diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java index 3214d1c..8a4d8f2 100644 --- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java @@ -6,6 +6,8 @@ import androidx.annotation.Nullable; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; @@ -15,6 +17,7 @@ import io.qonversion.sandwich.AutomationsEventListener; import io.qonversion.sandwich.AutomationsSandwich; +@SuppressWarnings("UnnecessaryLocalVariable") public class AutomationsWrapper implements AutomationsEventListener { private static final String EVENT_SCREEN_SHOWN = "OnAutomationsScreenShown"; private static final String EVENT_ACTION_STARTED = "OnAutomationsActionStarted"; @@ -31,13 +34,56 @@ public AutomationsWrapper(MessageSender messageSender) { automationsSandwich = new AutomationsSandwich(); } + public void initialize() { + automationsSandwich.initialize(); + } + public void subscribe() { - automationsSandwich.subscribe(this); + automationsSandwich.setDelegate(this); + } + + public void setNotificationsToken(String token) { + automationsSandwich.setNotificationToken(token); + } + + public boolean handleNotification(String notification) { + try { + ObjectMapper mapper = new ObjectMapper(); + + TypeReference> typeRef + = new TypeReference>() { + }; + Map notificationInfo = mapper.readValue(notification, typeRef); + + boolean result = automationsSandwich.handleNotification(notificationInfo); + + return result; + } catch (Exception e) { + return false; + } + } + + @Nullable + public Map getNotificationCustomPayload(String notification) { + try { + ObjectMapper mapper = new ObjectMapper(); + + TypeReference> typeRef + = new TypeReference>() { + }; + Map notificationInfo = mapper.readValue(notification, typeRef); + + Map payload = automationsSandwich.getNotificationCustomPayload(notificationInfo); + + return payload; + } catch (Exception e) { + return null; + } } @Override public void onAutomationEvent(@NonNull Event event, @Nullable Map data) { - String methodName = ""; + String methodName; switch (event) { case ScreenShown: methodName = EVENT_SCREEN_SHOWN; diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java index c545fa2..2a75dc7 100644 --- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java @@ -27,7 +27,7 @@ public class QonversionWrapper { public static String TAG = "QonversionWrapper"; - public static String ON_UPDATED_PURCHASES_LISTENER = "OnReceiveUpdatedPurchases"; + public static String ENTITLEMENTS_UPDATE_LISTENER = "OnReceivedUpdatedEntitlements"; private static MessageSender messageSender; private static AutomationsWrapper automationsWrapper; @@ -40,7 +40,7 @@ public static synchronized void initialize(String unityListener) { qonversionSandwich = new QonversionSandwich( application, () -> UnityPlayer.currentActivity, - permissions -> sendMessageToUnity(permissions, ON_UPDATED_PURCHASES_LISTENER) + entitlements -> sendMessageToUnity(entitlements, ENTITLEMENTS_UPDATE_LISTENER) ); automationsWrapper = new AutomationsWrapper(messageSender); } @@ -49,18 +49,25 @@ public static synchronized void storeSdkInfo(String version, String source) { qonversionSandwich.storeSdkInfo(source, version); } - public static synchronized void launch(String projectKey, boolean observerMode, String unityCallbackName) { - qonversionSandwich.launch(projectKey, observerMode, getResultListener(unityCallbackName)); + public static synchronized void initializeSdk( + String projectKey, + String launchModeKey, + @Nullable String environmentKey, + @Nullable String entitlementsCacheLifetimeKey + ) { + qonversionSandwich.initialize( + UnityPlayer.currentActivity, + projectKey, + launchModeKey, + environmentKey, + entitlementsCacheLifetimeKey + ); } public static synchronized void syncPurchases() { qonversionSandwich.syncPurchases(); } - public static synchronized void setDebugMode() { - qonversionSandwich.setDebugMode(); - } - public static synchronized void setProperty(String key, String value) { qonversionSandwich.setDefinedProperty(key, value); } @@ -69,7 +76,7 @@ public static synchronized void setUserProperty(String key, String value) { qonversionSandwich.setCustomProperty(key, value); } - public static synchronized void attribution(String conversionData, String attributionSource) { + public static synchronized void attribution(String conversionData, String attributionProvider) { try { ObjectMapper mapper = new ObjectMapper(); @@ -77,7 +84,7 @@ public static synchronized void attribution(String conversionData, String attrib = new TypeReference>() {}; Map conversionInfo = mapper.readValue(conversionData, typeRef); - qonversionSandwich.addAttributionData(attributionSource, conversionInfo); + qonversionSandwich.addAttributionData(attributionProvider, conversionInfo); } catch (JsonProcessingException e) { handleSerializationException(e); } @@ -91,8 +98,8 @@ public static synchronized void logout() { qonversionSandwich.logout(); } - public static synchronized void checkPermissions(String unityCallbackName) { - qonversionSandwich.checkPermissions(getResultListener(unityCallbackName)); + public static synchronized void checkEntitlements(String unityCallbackName) { + qonversionSandwich.checkEntitlements(getResultListener(unityCallbackName)); } public static synchronized void purchase(String productId, String unityCallbackName) { @@ -123,7 +130,7 @@ public static synchronized void offerings(String unityCallbackName) { qonversionSandwich.offerings(getResultListener(unityCallbackName)); } - public static synchronized void checkTrialIntroEligibilityForProductIds(String productIds, String unityCallbackName) { + public static synchronized void checkTrialIntroEligibility(String productIds, String unityCallbackName) { try { ObjectMapper mapper = new ObjectMapper(); TypeReference> typeRef = new TypeReference>() {}; @@ -135,47 +142,17 @@ public static synchronized void checkTrialIntroEligibilityForProductIds(String p } } - public static synchronized void setPermissionsCacheLifetime(String lifetimeKey) { - qonversionSandwich.setPermissionsCacheLifetime(lifetimeKey); - } - public static synchronized void setNotificationsToken(String token) { - qonversionSandwich.setNotificationToken(token); + automationsWrapper.setNotificationsToken(token); } public static synchronized boolean handleNotification(String notification) { - try { - ObjectMapper mapper = new ObjectMapper(); - - TypeReference> typeRef - = new TypeReference>() { - }; - Map notificationInfo = mapper.readValue(notification, typeRef); - - boolean result = qonversionSandwich.handleNotification(notificationInfo); - - return result; - } catch (Exception e) { - return false; - } + return automationsWrapper.handleNotification(notification); } @Nullable public static synchronized Map getNotificationCustomPayload(String notification) { - try { - ObjectMapper mapper = new ObjectMapper(); - - TypeReference> typeRef - = new TypeReference>() { - }; - Map notificationInfo = mapper.readValue(notification, typeRef); - - Map payload = qonversionSandwich.getNotificationCustomPayload(notificationInfo); - - return payload; - } catch (Exception e) { - return null; - } + return automationsWrapper.getNotificationCustomPayload(notification); } public static synchronized void subscribeOnAutomationEvents() { diff --git a/Runtime/Android/QonversionWrapperAndroid.cs b/Runtime/Android/QonversionWrapperAndroid.cs index 3f29fe5..2829f0f 100644 --- a/Runtime/Android/QonversionWrapperAndroid.cs +++ b/Runtime/Android/QonversionWrapperAndroid.cs @@ -17,9 +17,9 @@ public void StoreSdkInfo(string version, string source) CallQonversion("storeSdkInfo", version, source); } - public void Launch(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, bool observerMode, string callbackName) { - CallQonversion("launch", projectKey, observerMode, callbackName); + CallQonversion("initializeSdk", projectKey, observerMode, callbackName); } public void SetDebugMode() @@ -101,9 +101,9 @@ public void Logout() CallQonversion("logout"); } - public void CheckPermissions(string callbackName) + public void CheckEntitlements(string callbackName) { - CallQonversion("checkPermissions", callbackName); + CallQonversion("checkEntitlements", callbackName); } public void Purchase(string productId, string callbackName) @@ -141,9 +141,9 @@ public void Offerings(string callbackName) CallQonversion("offerings", callbackName); } - public void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName) + public void CheckTrialIntroEligibility(string productIdsJson, string callbackName) { - CallQonversion("checkTrialIntroEligibilityForProductIds", productIdsJson, callbackName); + CallQonversion("checkTrialIntroEligibility", productIdsJson, callbackName); } public void SetNotificationsToken(string token) diff --git a/Runtime/Scripts/IQonversionWrapper.cs b/Runtime/Scripts/IQonversionWrapper.cs index 6fce157..4c31e5f 100644 --- a/Runtime/Scripts/IQonversionWrapper.cs +++ b/Runtime/Scripts/IQonversionWrapper.cs @@ -8,12 +8,12 @@ internal interface IQonversionWrapper void StoreSdkInfo(string version, string source); void SetDebugMode(); void SetAdvertisingID(); - void Launch(string projectKey, bool observerMode, string callbackName); + void InitializeSdk(string projectKey, bool observerMode, string callbackName); void SetUserProperty(string key, string value); void SetProperty(UserProperty key, string value); void SyncPurchases(); void AddAttributionData(string conversionData, AttributionSource source); - void CheckPermissions(string callbackName); + void CheckEntitlements(string callbackName); void Purchase(string productId, string callbackName); void PurchaseProduct(string productId, string offeringId, string callbackName); void Restore(string callbackName); @@ -21,7 +21,7 @@ internal interface IQonversionWrapper void UpdatePurchaseWithProduct(string productId, string offeringId, string oldProductId, ProrationMode prorationMode, string callbackName); void Products(string callbackName); void Offerings(string callbackName); - void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName); + void CheckTrialIntroEligibility(string productIdsJson, string callbackName); void SetAppleSearchAdsAttributionEnabled(bool enable); void Identify(string userID); void Logout(); diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index 712af99..9814d0f 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -36,9 +36,10 @@ public class Qonversion : MonoBehaviour public delegate void StartPromoPurchase(OnPermissionsReceived callback); /// - /// Delegate fires each time a deferred transaction happens + /// Delegate fires each time a user entitlements change asynchronously, + /// for example, when a deferred transaction happens. /// - public delegate void OnUpdatedPurchasesReceived(Dictionary permissions); + public delegate void OnUpdatedEntitlementsReceived(Dictionary permissions); private const string GameObjectName = "QonvesrionRuntimeGameObject"; private const string OnLaunchMethodName = "OnLaunch"; @@ -57,7 +58,7 @@ public class Qonversion : MonoBehaviour private const string SdkSource = "unity"; private static IQonversionWrapper _Instance; - private static OnUpdatedPurchasesReceived _onUpdatedPurchasesReceived; + private static OnUpdatedEntitlementsReceived _onUpdatedEntitlementsReceived; private static OnPromoPurchasesReceived _onPromoPurchasesReceived; private static string _storedPromoProductId = null; @@ -118,17 +119,18 @@ public static event OnPromoPurchasesReceived PromoPurchasesReceived } /// - /// This event will be fired each time a deferred transaction happens. + /// This event will be fired for each asynchronous entitlements update, + /// for example, when a deferred transaction happens. /// - public static event OnUpdatedPurchasesReceived UpdatedPurchasesReceived + public static event OnUpdatedEntitlementsReceived UpdatedEntitlementsReceived { add { - _onUpdatedPurchasesReceived += value; + _onUpdatedEntitlementsReceived += value; } remove { - _onUpdatedPurchasesReceived -= value; + _onUpdatedEntitlementsReceived -= value; } } @@ -152,7 +154,7 @@ public static void Launch(string apiKey, bool observerMode) { IQonversionWrapper instance = getFinalInstance(); instance.StoreSdkInfo(SdkVersion, SdkSource); - instance.Launch(apiKey, observerMode, OnLaunchMethodName); + instance.InitializeSdk(apiKey, observerMode, OnLaunchMethodName); } /// @@ -315,7 +317,7 @@ public static void CheckPermissions(OnPermissionsReceived callback) { CheckPermissionsCallbacks.Add(callback); IQonversionWrapper instance = getFinalInstance(); - instance.CheckPermissions(OnCheckPermissionsMethodName); + instance.CheckEntitlements(OnCheckPermissionsMethodName); } /// @@ -493,20 +495,20 @@ public static void Offerings(OnOfferingsReceived callback) /// /// Products identifiers that must be checked. /// Callback that will be called when response is received - public static void CheckTrialIntroEligibilityForProductIds(IList productIds, OnEligibilitiesReceived callback) + public static void CheckTrialIntroEligibility(IList productIds, OnEligibilitiesReceived callback) { var productIdsJson = Json.Serialize(productIds); EligibilitiesCallback = callback; IQonversionWrapper instance = getFinalInstance(); - instance.CheckTrialIntroEligibilityForProductIds(productIdsJson, OnEligibilitiesMethodName); + instance.CheckTrialIntroEligibility(productIdsJson, OnEligibilitiesMethodName); } /// /// Permissions cache is used when there are problems with the Qonversion API /// or internet connection. If so, Qonversion will return the last successfully loaded /// permissions. The current method allows you to configure how long that cache may be used. - /// The default value is . /// /// Desired permissions cache lifetime duration. public static void SetPermissionsCacheLifetime(PermissionsCacheLifetime lifetime) { @@ -682,17 +684,17 @@ private void OnEligibilities(string jsonString) } // Called from the native SDK - Called when deferred or pending purchase occured - private void OnReceiveUpdatedPurchases(string jsonString) + private void OnReceivedUpdatedEntitlements(string jsonString) { - Debug.Log("OnReceiveUpdatedPurchases " + jsonString); + Debug.Log("OnReceivedUpdatedEntitlements " + jsonString); - if (_onUpdatedPurchasesReceived == null) + if (_onUpdatedEntitlementsReceived == null) { return; } Dictionary permissions = Mapper.PermissionsFromJson(jsonString); - _onUpdatedPurchasesReceived(permissions); + _onUpdatedEntitlementsReceived(permissions); } private void OnReceivePromoPurchase(string storeProductId) diff --git a/Runtime/Scripts/QonversionWrapperNoop.cs b/Runtime/Scripts/QonversionWrapperNoop.cs index 58cb925..f0b2cb2 100644 --- a/Runtime/Scripts/QonversionWrapperNoop.cs +++ b/Runtime/Scripts/QonversionWrapperNoop.cs @@ -5,7 +5,7 @@ internal class QonversionWrapperNoop : IQonversionWrapper public void Initialize(string gameObjectName) { } - public void Launch(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, bool observerMode, string callbackName) { } @@ -33,7 +33,7 @@ public void SetAdvertisingID() { } - public void CheckPermissions(string callbackName) + public void CheckEntitlements(string callbackName) { } @@ -69,7 +69,7 @@ public void StoreSdkInfo(string version, string source) { } - public void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName) + public void CheckTrialIntroEligibility(string productIdsJson, string callbackName) { } diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index c4ec360..bec6e48 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -101,7 +101,7 @@ public void StoreSdkInfo(string version, string source) #endif } - public void Launch(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, bool observerMode, string callbackName) { #if UNITY_IOS _launchWithKey(projectKey, callbackName); @@ -177,7 +177,7 @@ public void PresentCodeRedemptionSheet() #endif } - public void CheckPermissions(string callbackName) + public void CheckEntitlements(string callbackName) { #if UNITY_IOS _checkPermissions(callbackName); @@ -227,10 +227,10 @@ public void Offerings(string callbackName) #endif } - public void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName) + public void CheckTrialIntroEligibility(string productIdsJson, string callbackName) { #if UNITY_IOS - _checkTrialIntroEligibilityForProductIds(productIdsJson, callbackName); + _checkTrialIntroEligibility(productIdsJson, callbackName); #endif } diff --git a/package.json b/package.json index 2fb7af6..8040cd0 100644 --- a/package.json +++ b/package.json @@ -29,5 +29,6 @@ "/Runtime.meta", "/Editor", "/Editor.meta" - ] + ], + "dependencies": {} } From 61b1a4f1f63b5c5f64470bb0d67ca313863ce555 Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Thu, 17 Nov 2022 13:13:50 +0600 Subject: [PATCH 02/22] User info method added. --- .../com/qonversion/unitywrapper/QonversionWrapper.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java index 2a75dc7..f0593fe 100644 --- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java @@ -98,6 +98,10 @@ public static synchronized void logout() { qonversionSandwich.logout(); } + public static synchronized void userInfo(String unityCallbackName) { + qonversionSandwich.userInfo(getResultListener(unityCallbackName)); + } + public static synchronized void checkEntitlements(String unityCallbackName) { qonversionSandwich.checkEntitlements(getResultListener(unityCallbackName)); } From f43f233c33a6373ae23357ffbea6e301d76f8c7a Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Thu, 17 Nov 2022 13:41:37 +0600 Subject: [PATCH 03/22] DTO fixes --- Runtime/Android/QonversionWrapperAndroid.cs | 22 ++++----- Runtime/Scripts/IQonversionWrapper.cs | 2 +- Runtime/Scripts/Mapper.cs | 22 ++------- ...butionSource.cs => AttributionProvider.cs} | 2 +- ...ce.cs.meta => AttributionProvider.cs.meta} | 0 .../Models/{Permission.cs => Entitlement.cs} | 48 +++++++++---------- ...Permission.cs.meta => Entitlement.cs.meta} | 0 .../Models/EntitlementsCacheLifetime.cs | 14 ++++++ ...meta => EntitlementsCacheLifetime.cs.meta} | 0 .../Models/PermissionsCacheLifetime.cs | 14 ------ Runtime/Scripts/Models/ProrationMode.cs | 2 +- Runtime/Scripts/Models/UserProperty.cs | 7 +-- Runtime/Scripts/Qonversion.cs | 29 +++++------ Runtime/Scripts/QonversionWrapperNoop.cs | 2 +- Runtime/iOS/QonversionWrapperIOS.cs | 2 +- 15 files changed, 77 insertions(+), 89 deletions(-) rename Runtime/Scripts/Models/{AttributionSource.cs => AttributionProvider.cs} (73%) rename Runtime/Scripts/Models/{AttributionSource.cs.meta => AttributionProvider.cs.meta} (100%) rename Runtime/Scripts/Models/{Permission.cs => Entitlement.cs} (63%) rename Runtime/Scripts/Models/{Permission.cs.meta => Entitlement.cs.meta} (100%) create mode 100644 Runtime/Scripts/Models/EntitlementsCacheLifetime.cs rename Runtime/Scripts/Models/{PermissionsCacheLifetime.cs.meta => EntitlementsCacheLifetime.cs.meta} (100%) delete mode 100644 Runtime/Scripts/Models/PermissionsCacheLifetime.cs diff --git a/Runtime/Android/QonversionWrapperAndroid.cs b/Runtime/Android/QonversionWrapperAndroid.cs index 2829f0f..a2f592d 100644 --- a/Runtime/Android/QonversionWrapperAndroid.cs +++ b/Runtime/Android/QonversionWrapperAndroid.cs @@ -61,29 +61,29 @@ public void SetAppleSearchAdsAttributionEnabled(bool enable) { } - public void AddAttributionData(string conversionData, AttributionSource source) + public void AddAttributionData(string conversionData, AttributionProvider provider) { - string attibutionSource; + string attibutionProvider; - switch (source) + switch (provider) { - case AttributionSource.AppsFlyer: - attibutionSource = "AppsFlyer"; + case AttributionProvider.AppsFlyer: + attibutionProvider = "AppsFlyer"; break; - case AttributionSource.Branch: - attibutionSource = "Branch"; + case AttributionProvider.Branch: + attibutionProvider = "Branch"; break; - case AttributionSource.Adjust: - attibutionSource = "Adjust"; + case AttributionProvider.Adjust: + attibutionProvider = "Adjust"; break; default: - Debug.LogWarning(string.Format("[Qonversion] Not Supported AttributionSource.{0} on Android platform.", source)); + Debug.LogWarning(string.Format("[Qonversion] Not Supported AttributionProvider.{0} on Android platform.", provider)); return; } try { - CallQonversion("attribution", conversionData, attibutionSource); + CallQonversion("attribution", conversionData, attibutionProvider); } catch (Exception e) { diff --git a/Runtime/Scripts/IQonversionWrapper.cs b/Runtime/Scripts/IQonversionWrapper.cs index 4c31e5f..0895a11 100644 --- a/Runtime/Scripts/IQonversionWrapper.cs +++ b/Runtime/Scripts/IQonversionWrapper.cs @@ -12,7 +12,7 @@ internal interface IQonversionWrapper void SetUserProperty(string key, string value); void SetProperty(UserProperty key, string value); void SyncPurchases(); - void AddAttributionData(string conversionData, AttributionSource source); + void AddAttributionData(string conversionData, AttributionProvider provider); void CheckEntitlements(string callbackName); void Purchase(string productId, string callbackName); void PurchaseProduct(string productId, string offeringId, string callbackName); diff --git a/Runtime/Scripts/Mapper.cs b/Runtime/Scripts/Mapper.cs index 035baf5..fd49216 100644 --- a/Runtime/Scripts/Mapper.cs +++ b/Runtime/Scripts/Mapper.cs @@ -7,20 +7,6 @@ namespace QonversionUnity { internal class Mapper { - internal static string GetLifetimeKey(PermissionsCacheLifetime lifetime) { - var keys = new Dictionary() { - {PermissionsCacheLifetime.WEEK, "Week"}, - {PermissionsCacheLifetime.TWO_WEEKS, "TwoWeeks"}, - {PermissionsCacheLifetime.MONTH, "Month"}, - {PermissionsCacheLifetime.TWO_MONTHS, "TwoMonths"}, - {PermissionsCacheLifetime.THREE_MONTHS, "ThreeMonths"}, - {PermissionsCacheLifetime.SIX_MONTHS, "SixMonths"}, - {PermissionsCacheLifetime.YEAR, "Year"}, - {PermissionsCacheLifetime.UNLIMITED, "Unlimited"} - }; - return keys[lifetime]; - } - internal static bool GetIsCancelledFromJson(string jsonStr) { if (!(Json.Deserialize(jsonStr) is Dictionary result)) @@ -32,9 +18,9 @@ internal static bool GetIsCancelledFromJson(string jsonStr) return result.TryGetValue("isCancelled", out var isCancelled) && Convert.ToBoolean(isCancelled); } - internal static Dictionary PermissionsFromJson(string jsonStr) + internal static Dictionary PermissionsFromJson(string jsonStr) { - var result = new Dictionary(); + var result = new Dictionary(); if (!(Json.Deserialize(jsonStr) is Dictionary permissions)) { @@ -46,8 +32,8 @@ internal static Dictionary PermissionsFromJson(string jsonSt { if (permissionPair.Value is Dictionary permissionDict) { - Permission permission = new Permission(permissionDict); - result.Add(permissionPair.Key, permission); + Entitlement entitlement = new Entitlement(permissionDict); + result.Add(permissionPair.Key, entitlement); } } diff --git a/Runtime/Scripts/Models/AttributionSource.cs b/Runtime/Scripts/Models/AttributionProvider.cs similarity index 73% rename from Runtime/Scripts/Models/AttributionSource.cs rename to Runtime/Scripts/Models/AttributionProvider.cs index 75b4474..e80b99a 100644 --- a/Runtime/Scripts/Models/AttributionSource.cs +++ b/Runtime/Scripts/Models/AttributionProvider.cs @@ -1,6 +1,6 @@ namespace QonversionUnity { - public enum AttributionSource + public enum AttributionProvider { AppsFlyer = 0, Branch, diff --git a/Runtime/Scripts/Models/AttributionSource.cs.meta b/Runtime/Scripts/Models/AttributionProvider.cs.meta similarity index 100% rename from Runtime/Scripts/Models/AttributionSource.cs.meta rename to Runtime/Scripts/Models/AttributionProvider.cs.meta diff --git a/Runtime/Scripts/Models/Permission.cs b/Runtime/Scripts/Models/Entitlement.cs similarity index 63% rename from Runtime/Scripts/Models/Permission.cs rename to Runtime/Scripts/Models/Entitlement.cs index ecde528..2ddc881 100644 --- a/Runtime/Scripts/Models/Permission.cs +++ b/Runtime/Scripts/Models/Entitlement.cs @@ -4,21 +4,21 @@ namespace QonversionUnity { - public class Permission + public class Entitlement { - /// Qonversion Permission ID, like premium. - [Tooltip("Create Permission: https://qonversion.io/docs/create-permission")] - public readonly string PermissionID; + /// Qonversion Entitlement ID, like premium. + [Tooltip("Create Entitlement: https://qonversion.io/docs/create-permission")] + public readonly string Id; /// Product ID created in Qonversion Dashboard. [Tooltip("Create Products: https://qonversion.io/docs/create-products")] - public readonly string ProductID; + public readonly string ProductId; - /// A renew state for an associate product that unlocked permission - public readonly QProductRenewState RenewState; + /// A renew state for an associate product that unlocked entitlement + public readonly QEntitlementRenewState RenewState; - /// A source determining where this permission is originally from - App Store, Play Store, Stripe, etc. - public readonly QPermissionSource Source; + /// A source determining where this entitlement is originally from - App Store, Play Store, Stripe, etc. + public readonly QEntitlementSource Source; /// Purchase date public readonly DateTime StartedDate; @@ -26,17 +26,17 @@ public class Permission /// Expiration date for subscription public readonly DateTime? ExpirationDate; - /// Use for checking permission for current user. + /// Use for checking entitlement for current user. /// Pay attention, isActive == true does not mean that subscription is renewable. - /// Subscription could be canceled, but the user could still have a permission + /// Subscription could be canceled, but the user could still have a entitlement public readonly bool IsActive; - public Permission(Dictionary dict) + public Entitlement(Dictionary dict) { - if (dict.TryGetValue("id", out object value)) PermissionID = value as string; - if (dict.TryGetValue("associatedProduct", out value)) ProductID = value as string; + if (dict.TryGetValue("id", out object value)) Id = value as string; + if (dict.TryGetValue("productId", out value)) ProductId = value as string; if (dict.TryGetValue("renewState", out value)) RenewState = FormatRenewState(value); - Source = dict.TryGetValue("source", out value) ? FormatPermissionSource(value) : QPermissionSource.Unknown; + Source = dict.TryGetValue("source", out value) ? FormatEntitlementSource(value) : QEntitlementSource.Unknown; if (dict.TryGetValue("active", out value)) IsActive = (bool)value; if (dict.TryGetValue("startedTimestamp", out value)) StartedDate = FormatDate(value); if (dict.TryGetValue("expirationTimestamp", out value) && value != null) ExpirationDate = FormatDate(value); @@ -44,8 +44,8 @@ public Permission(Dictionary dict) public override string ToString() { - return $"{nameof(PermissionID)}: {PermissionID}, " + - $"{nameof(ProductID)}: {ProductID}, " + + return $"{nameof(Id)}: {Id}, " + + $"{nameof(ProductId)}: {ProductId}, " + $"{nameof(RenewState)}: {RenewState}, " + $"{nameof(Source)}: {Source}, " + $"{nameof(StartedDate)}: {StartedDate}, " + @@ -61,17 +61,17 @@ private DateTime FormatDate(object time) { return Utils.FormatDate((long) time); } - private QProductRenewState FormatRenewState(object renewState) => - (QProductRenewState)Convert.ToInt32(renewState); + private QEntitlementRenewState FormatRenewState(object renewState) => + (QEntitlementRenewState)Convert.ToInt32(renewState); - private QPermissionSource FormatPermissionSource(object source) { - return Enum.TryParse(source.ToString(), out QPermissionSource parsedSource) + private QEntitlementSource FormatEntitlementSource(object source) { + return Enum.TryParse(source.ToString(), out QEntitlementSource parsedSource) ? parsedSource - : QPermissionSource.Unknown; + : QEntitlementSource.Unknown; } } - public enum QProductRenewState + public enum QEntitlementRenewState { /// For in-app purchases. NonRenewable = -1, @@ -87,7 +87,7 @@ public enum QProductRenewState BillingIssue = 3 } - public enum QPermissionSource + public enum QEntitlementSource { Unknown, AppStore, diff --git a/Runtime/Scripts/Models/Permission.cs.meta b/Runtime/Scripts/Models/Entitlement.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Permission.cs.meta rename to Runtime/Scripts/Models/Entitlement.cs.meta diff --git a/Runtime/Scripts/Models/EntitlementsCacheLifetime.cs b/Runtime/Scripts/Models/EntitlementsCacheLifetime.cs new file mode 100644 index 0000000..b9c4593 --- /dev/null +++ b/Runtime/Scripts/Models/EntitlementsCacheLifetime.cs @@ -0,0 +1,14 @@ +namespace QonversionUnity +{ + public enum EntitlementsCacheLifetime + { + Week, + TwoWeeks, + Month, + TwoMonths, + ThreeMonths, + SixMonths, + Year, + Unlimited + } +} \ No newline at end of file diff --git a/Runtime/Scripts/Models/PermissionsCacheLifetime.cs.meta b/Runtime/Scripts/Models/EntitlementsCacheLifetime.cs.meta similarity index 100% rename from Runtime/Scripts/Models/PermissionsCacheLifetime.cs.meta rename to Runtime/Scripts/Models/EntitlementsCacheLifetime.cs.meta diff --git a/Runtime/Scripts/Models/PermissionsCacheLifetime.cs b/Runtime/Scripts/Models/PermissionsCacheLifetime.cs deleted file mode 100644 index 2560404..0000000 --- a/Runtime/Scripts/Models/PermissionsCacheLifetime.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace QonversionUnity -{ - public enum PermissionsCacheLifetime - { - WEEK, - TWO_WEEKS, - MONTH, - TWO_MONTHS, - THREE_MONTHS, - SIX_MONTHS, - YEAR, - UNLIMITED - } -} \ No newline at end of file diff --git a/Runtime/Scripts/Models/ProrationMode.cs b/Runtime/Scripts/Models/ProrationMode.cs index 707c3dd..5176a56 100644 --- a/Runtime/Scripts/Models/ProrationMode.cs +++ b/Runtime/Scripts/Models/ProrationMode.cs @@ -9,7 +9,7 @@ public enum ProrationMode ImmediateAndChargeProratedPrice, /// Replacement takes effect immediately, and the new price will be charged on next recurrence time. ImmediateWithoutProration, - /// Replacement takes effect when the old plan expires, and the new price will be charged at the same time. + /// Replacement takes effect when the old plan expires, and the new price will be charged at the same time. Deferred } } \ No newline at end of file diff --git a/Runtime/Scripts/Models/UserProperty.cs b/Runtime/Scripts/Models/UserProperty.cs index 6a569c8..46047a0 100644 --- a/Runtime/Scripts/Models/UserProperty.cs +++ b/Runtime/Scripts/Models/UserProperty.cs @@ -4,12 +4,13 @@ public enum UserProperty { Email, Name, + KochavaDeviceId, AppsFlyerUserId, AdjustAdId, - KochavaDeviceId, CustomUserId, - FacebookAttribution, + FacebookAttribution, // Android only FirebaseAppInstanceId, - AppSetId + AppSetId, // Android only + AdvertisingId, // iOS only } } \ No newline at end of file diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index 9814d0f..3efd440 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -8,8 +8,8 @@ namespace QonversionUnity { public class Qonversion : MonoBehaviour { - public delegate void OnPurchaseResultReceived(Dictionary permissions, QonversionError error, bool isCancelled); - public delegate void OnPermissionsReceived(Dictionary permissions, QonversionError error); + public delegate void OnPurchaseResultReceived(Dictionary permissions, QonversionError error, bool isCancelled); + public delegate void OnPermissionsReceived(Dictionary permissions, QonversionError error); public delegate void OnProductsReceived(Dictionary products, QonversionError error); public delegate void OnOfferingsReceived(Offerings offerings, QonversionError error); public delegate void OnEligibilitiesReceived(Dictionary eligibilities, QonversionError error); @@ -39,7 +39,7 @@ public class Qonversion : MonoBehaviour /// Delegate fires each time a user entitlements change asynchronously, /// for example, when a deferred transaction happens. /// - public delegate void OnUpdatedEntitlementsReceived(Dictionary permissions); + public delegate void OnUpdatedEntitlementsReceived(Dictionary permissions); private const string GameObjectName = "QonvesrionRuntimeGameObject"; private const string OnLaunchMethodName = "OnLaunch"; @@ -253,22 +253,22 @@ public static void PresentCodeRedemptionSheet() /// Sends your attribution data to the attribution source. /// /// An object containing your attribution data. - /// The attribution source to which the data will be sent. - public static void AddAttributionData(Dictionary conversionData, AttributionSource attributionSource) + /// The attribution source to which the data will be sent. + public static void AddAttributionData(Dictionary conversionData, AttributionProvider attributionProvider) { - AddAttributionData(conversionData.toJson(), attributionSource); + AddAttributionData(conversionData.toJson(), attributionProvider); } /// /// Sends your attribution data to the attribution source. /// /// A json string containing your attribution data. - /// The attribution source to which the data will be sent. - public static void AddAttributionData(string conversionData, AttributionSource attributionSource) + /// The attribution source to which the data will be sent. + public static void AddAttributionData(string conversionData, AttributionProvider attributionProvider) { IQonversionWrapper instance = getFinalInstance(); - instance.AddAttributionData(conversionData, attributionSource); + instance.AddAttributionData(conversionData, attributionProvider); } /// @@ -508,11 +508,12 @@ public static void CheckTrialIntroEligibility(IList productIds, OnEligib /// Permissions cache is used when there are problems with the Qonversion API /// or internet connection. If so, Qonversion will return the last successfully loaded /// permissions. The current method allows you to configure how long that cache may be used. - /// The default value is . + /// The default value is . /// /// Desired permissions cache lifetime duration. - public static void SetPermissionsCacheLifetime(PermissionsCacheLifetime lifetime) { - var lifetimeKey = Mapper.GetLifetimeKey(lifetime); + public static void SetPermissionsCacheLifetime(EntitlementsCacheLifetime lifetime) { + + var lifetimeKey = Enum.GetName(typeof(EntitlementsCacheLifetime), lifetime); IQonversionWrapper instance = getFinalInstance(); instance.SetPermissionsCacheLifetime(lifetimeKey); } @@ -693,7 +694,7 @@ private void OnReceivedUpdatedEntitlements(string jsonString) return; } - Dictionary permissions = Mapper.PermissionsFromJson(jsonString); + Dictionary permissions = Mapper.PermissionsFromJson(jsonString); _onUpdatedEntitlementsReceived(permissions); } @@ -808,7 +809,7 @@ private void OnAutomationsFinished(string jsonString) private static OnPurchaseResultReceived ConvertPermissionsCallbackToPurchaseResultCallback(OnPermissionsReceived callback) { - return delegate(Dictionary permissions, QonversionError error, bool isCancelled) { + return delegate(Dictionary permissions, QonversionError error, bool isCancelled) { callback(permissions, error); }; } diff --git a/Runtime/Scripts/QonversionWrapperNoop.cs b/Runtime/Scripts/QonversionWrapperNoop.cs index f0b2cb2..004a56e 100644 --- a/Runtime/Scripts/QonversionWrapperNoop.cs +++ b/Runtime/Scripts/QonversionWrapperNoop.cs @@ -21,7 +21,7 @@ public void SetProperty(UserProperty key, string value) { } - public void AddAttributionData(string conversionData, AttributionSource source) + public void AddAttributionData(string conversionData, AttributionProvider provider) { } diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index bec6e48..2f3126a 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -141,7 +141,7 @@ public void SetProperty(UserProperty key, string value) #endif } - public void AddAttributionData(string conversionData, AttributionSource source) + public void AddAttributionData(string conversionData, AttributionProvider provider) { #if UNITY_IOS string sourceName = Enum.GetName(typeof(AttributionSource), source); From b4d78afb632fa4772d0a1b43db65288801a5883c Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Thu, 17 Nov 2022 14:06:11 +0600 Subject: [PATCH 04/22] Models directory renamed to Dto --- Runtime/Scripts/{Models.meta => Dto.meta} | 0 Runtime/Scripts/{Models => Dto}/ActionResult.cs | 0 Runtime/Scripts/{Models => Dto}/ActionResult.cs.meta | 0 Runtime/Scripts/{Models => Dto}/ActionResultType.cs | 0 Runtime/Scripts/{Models => Dto}/ActionResultType.cs.meta | 0 Runtime/Scripts/{Models => Dto}/AttributionProvider.cs | 0 Runtime/Scripts/{Models => Dto}/AttributionProvider.cs.meta | 0 Runtime/Scripts/{Models => Dto}/AutomationsEvent.cs | 0 Runtime/Scripts/{Models => Dto}/AutomationsEvent.cs.meta | 0 Runtime/Scripts/{Models => Dto}/AutomationsEventType.cs | 0 Runtime/Scripts/{Models => Dto}/AutomationsEventType.cs.meta | 0 Runtime/Scripts/{Models => Dto}/Eligibility.cs | 0 Runtime/Scripts/{Models => Dto}/Eligibility.cs.meta | 0 Runtime/Scripts/{Models => Dto}/EligibilityStatus.cs | 0 Runtime/Scripts/{Models => Dto}/EligibilityStatus.cs.meta | 0 Runtime/Scripts/{Models => Dto}/Entitlement.cs | 0 Runtime/Scripts/{Models => Dto}/Entitlement.cs.meta | 0 Runtime/Scripts/{Models => Dto}/EntitlementsCacheLifetime.cs | 0 .../Scripts/{Models => Dto}/EntitlementsCacheLifetime.cs.meta | 0 Runtime/Scripts/{Models => Dto}/Offering.cs | 2 +- Runtime/Scripts/{Models => Dto}/Offering.cs.meta | 0 Runtime/Scripts/{Models => Dto}/Offerings.cs | 0 Runtime/Scripts/{Models => Dto}/Offerings.cs.meta | 0 Runtime/Scripts/{Models => Dto}/Product.cs | 0 Runtime/Scripts/{Models => Dto}/Product.cs.meta | 0 Runtime/Scripts/{Models => Dto}/ProrationMode.cs | 0 Runtime/Scripts/{Models => Dto}/ProrationMode.cs.meta | 0 Runtime/Scripts/{Models => Dto}/QonversionError.cs | 0 Runtime/Scripts/{Models => Dto}/QonversionError.cs.meta | 0 Runtime/Scripts/{Models => Dto}/SkProduct.meta | 0 Runtime/Scripts/{Models => Dto}/SkProduct/SKProduct.cs | 0 Runtime/Scripts/{Models => Dto}/SkProduct/SKProduct.cs.meta | 0 Runtime/Scripts/{Models => Dto}/SkProduct/SKProductDiscount.cs | 0 .../Scripts/{Models => Dto}/SkProduct/SKProductDiscount.cs.meta | 0 .../{Models => Dto}/SkProduct/SKProductSubscriptionPeriod.cs | 0 .../SkProduct/SKProductSubscriptionPeriod.cs.meta | 0 Runtime/Scripts/{Models => Dto}/SkuDetails.cs | 2 +- Runtime/Scripts/{Models => Dto}/SkuDetails.cs.meta | 0 Runtime/Scripts/{Models => Dto}/UserProperty.cs | 0 Runtime/Scripts/{Models => Dto}/UserProperty.cs.meta | 0 40 files changed, 2 insertions(+), 2 deletions(-) rename Runtime/Scripts/{Models.meta => Dto.meta} (100%) rename Runtime/Scripts/{Models => Dto}/ActionResult.cs (100%) rename Runtime/Scripts/{Models => Dto}/ActionResult.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/ActionResultType.cs (100%) rename Runtime/Scripts/{Models => Dto}/ActionResultType.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/AttributionProvider.cs (100%) rename Runtime/Scripts/{Models => Dto}/AttributionProvider.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/AutomationsEvent.cs (100%) rename Runtime/Scripts/{Models => Dto}/AutomationsEvent.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/AutomationsEventType.cs (100%) rename Runtime/Scripts/{Models => Dto}/AutomationsEventType.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/Eligibility.cs (100%) rename Runtime/Scripts/{Models => Dto}/Eligibility.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/EligibilityStatus.cs (100%) rename Runtime/Scripts/{Models => Dto}/EligibilityStatus.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/Entitlement.cs (100%) rename Runtime/Scripts/{Models => Dto}/Entitlement.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/EntitlementsCacheLifetime.cs (100%) rename Runtime/Scripts/{Models => Dto}/EntitlementsCacheLifetime.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/Offering.cs (99%) rename Runtime/Scripts/{Models => Dto}/Offering.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/Offerings.cs (100%) rename Runtime/Scripts/{Models => Dto}/Offerings.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/Product.cs (100%) rename Runtime/Scripts/{Models => Dto}/Product.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/ProrationMode.cs (100%) rename Runtime/Scripts/{Models => Dto}/ProrationMode.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/QonversionError.cs (100%) rename Runtime/Scripts/{Models => Dto}/QonversionError.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProduct.cs (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProduct.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProductDiscount.cs (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProductDiscount.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProductSubscriptionPeriod.cs (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProductSubscriptionPeriod.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkuDetails.cs (99%) rename Runtime/Scripts/{Models => Dto}/SkuDetails.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/UserProperty.cs (100%) rename Runtime/Scripts/{Models => Dto}/UserProperty.cs.meta (100%) diff --git a/Runtime/Scripts/Models.meta b/Runtime/Scripts/Dto.meta similarity index 100% rename from Runtime/Scripts/Models.meta rename to Runtime/Scripts/Dto.meta diff --git a/Runtime/Scripts/Models/ActionResult.cs b/Runtime/Scripts/Dto/ActionResult.cs similarity index 100% rename from Runtime/Scripts/Models/ActionResult.cs rename to Runtime/Scripts/Dto/ActionResult.cs diff --git a/Runtime/Scripts/Models/ActionResult.cs.meta b/Runtime/Scripts/Dto/ActionResult.cs.meta similarity index 100% rename from Runtime/Scripts/Models/ActionResult.cs.meta rename to Runtime/Scripts/Dto/ActionResult.cs.meta diff --git a/Runtime/Scripts/Models/ActionResultType.cs b/Runtime/Scripts/Dto/ActionResultType.cs similarity index 100% rename from Runtime/Scripts/Models/ActionResultType.cs rename to Runtime/Scripts/Dto/ActionResultType.cs diff --git a/Runtime/Scripts/Models/ActionResultType.cs.meta b/Runtime/Scripts/Dto/ActionResultType.cs.meta similarity index 100% rename from Runtime/Scripts/Models/ActionResultType.cs.meta rename to Runtime/Scripts/Dto/ActionResultType.cs.meta diff --git a/Runtime/Scripts/Models/AttributionProvider.cs b/Runtime/Scripts/Dto/AttributionProvider.cs similarity index 100% rename from Runtime/Scripts/Models/AttributionProvider.cs rename to Runtime/Scripts/Dto/AttributionProvider.cs diff --git a/Runtime/Scripts/Models/AttributionProvider.cs.meta b/Runtime/Scripts/Dto/AttributionProvider.cs.meta similarity index 100% rename from Runtime/Scripts/Models/AttributionProvider.cs.meta rename to Runtime/Scripts/Dto/AttributionProvider.cs.meta diff --git a/Runtime/Scripts/Models/AutomationsEvent.cs b/Runtime/Scripts/Dto/AutomationsEvent.cs similarity index 100% rename from Runtime/Scripts/Models/AutomationsEvent.cs rename to Runtime/Scripts/Dto/AutomationsEvent.cs diff --git a/Runtime/Scripts/Models/AutomationsEvent.cs.meta b/Runtime/Scripts/Dto/AutomationsEvent.cs.meta similarity index 100% rename from Runtime/Scripts/Models/AutomationsEvent.cs.meta rename to Runtime/Scripts/Dto/AutomationsEvent.cs.meta diff --git a/Runtime/Scripts/Models/AutomationsEventType.cs b/Runtime/Scripts/Dto/AutomationsEventType.cs similarity index 100% rename from Runtime/Scripts/Models/AutomationsEventType.cs rename to Runtime/Scripts/Dto/AutomationsEventType.cs diff --git a/Runtime/Scripts/Models/AutomationsEventType.cs.meta b/Runtime/Scripts/Dto/AutomationsEventType.cs.meta similarity index 100% rename from Runtime/Scripts/Models/AutomationsEventType.cs.meta rename to Runtime/Scripts/Dto/AutomationsEventType.cs.meta diff --git a/Runtime/Scripts/Models/Eligibility.cs b/Runtime/Scripts/Dto/Eligibility.cs similarity index 100% rename from Runtime/Scripts/Models/Eligibility.cs rename to Runtime/Scripts/Dto/Eligibility.cs diff --git a/Runtime/Scripts/Models/Eligibility.cs.meta b/Runtime/Scripts/Dto/Eligibility.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Eligibility.cs.meta rename to Runtime/Scripts/Dto/Eligibility.cs.meta diff --git a/Runtime/Scripts/Models/EligibilityStatus.cs b/Runtime/Scripts/Dto/EligibilityStatus.cs similarity index 100% rename from Runtime/Scripts/Models/EligibilityStatus.cs rename to Runtime/Scripts/Dto/EligibilityStatus.cs diff --git a/Runtime/Scripts/Models/EligibilityStatus.cs.meta b/Runtime/Scripts/Dto/EligibilityStatus.cs.meta similarity index 100% rename from Runtime/Scripts/Models/EligibilityStatus.cs.meta rename to Runtime/Scripts/Dto/EligibilityStatus.cs.meta diff --git a/Runtime/Scripts/Models/Entitlement.cs b/Runtime/Scripts/Dto/Entitlement.cs similarity index 100% rename from Runtime/Scripts/Models/Entitlement.cs rename to Runtime/Scripts/Dto/Entitlement.cs diff --git a/Runtime/Scripts/Models/Entitlement.cs.meta b/Runtime/Scripts/Dto/Entitlement.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Entitlement.cs.meta rename to Runtime/Scripts/Dto/Entitlement.cs.meta diff --git a/Runtime/Scripts/Models/EntitlementsCacheLifetime.cs b/Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs similarity index 100% rename from Runtime/Scripts/Models/EntitlementsCacheLifetime.cs rename to Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs diff --git a/Runtime/Scripts/Models/EntitlementsCacheLifetime.cs.meta b/Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs.meta similarity index 100% rename from Runtime/Scripts/Models/EntitlementsCacheLifetime.cs.meta rename to Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs.meta diff --git a/Runtime/Scripts/Models/Offering.cs b/Runtime/Scripts/Dto/Offering.cs similarity index 99% rename from Runtime/Scripts/Models/Offering.cs rename to Runtime/Scripts/Dto/Offering.cs index e47490b..8b34b23 100644 --- a/Runtime/Scripts/Models/Offering.cs +++ b/Runtime/Scripts/Dto/Offering.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using JetBrains.Annotations; diff --git a/Runtime/Scripts/Models/Offering.cs.meta b/Runtime/Scripts/Dto/Offering.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Offering.cs.meta rename to Runtime/Scripts/Dto/Offering.cs.meta diff --git a/Runtime/Scripts/Models/Offerings.cs b/Runtime/Scripts/Dto/Offerings.cs similarity index 100% rename from Runtime/Scripts/Models/Offerings.cs rename to Runtime/Scripts/Dto/Offerings.cs diff --git a/Runtime/Scripts/Models/Offerings.cs.meta b/Runtime/Scripts/Dto/Offerings.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Offerings.cs.meta rename to Runtime/Scripts/Dto/Offerings.cs.meta diff --git a/Runtime/Scripts/Models/Product.cs b/Runtime/Scripts/Dto/Product.cs similarity index 100% rename from Runtime/Scripts/Models/Product.cs rename to Runtime/Scripts/Dto/Product.cs diff --git a/Runtime/Scripts/Models/Product.cs.meta b/Runtime/Scripts/Dto/Product.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Product.cs.meta rename to Runtime/Scripts/Dto/Product.cs.meta diff --git a/Runtime/Scripts/Models/ProrationMode.cs b/Runtime/Scripts/Dto/ProrationMode.cs similarity index 100% rename from Runtime/Scripts/Models/ProrationMode.cs rename to Runtime/Scripts/Dto/ProrationMode.cs diff --git a/Runtime/Scripts/Models/ProrationMode.cs.meta b/Runtime/Scripts/Dto/ProrationMode.cs.meta similarity index 100% rename from Runtime/Scripts/Models/ProrationMode.cs.meta rename to Runtime/Scripts/Dto/ProrationMode.cs.meta diff --git a/Runtime/Scripts/Models/QonversionError.cs b/Runtime/Scripts/Dto/QonversionError.cs similarity index 100% rename from Runtime/Scripts/Models/QonversionError.cs rename to Runtime/Scripts/Dto/QonversionError.cs diff --git a/Runtime/Scripts/Models/QonversionError.cs.meta b/Runtime/Scripts/Dto/QonversionError.cs.meta similarity index 100% rename from Runtime/Scripts/Models/QonversionError.cs.meta rename to Runtime/Scripts/Dto/QonversionError.cs.meta diff --git a/Runtime/Scripts/Models/SkProduct.meta b/Runtime/Scripts/Dto/SkProduct.meta similarity index 100% rename from Runtime/Scripts/Models/SkProduct.meta rename to Runtime/Scripts/Dto/SkProduct.meta diff --git a/Runtime/Scripts/Models/SkProduct/SKProduct.cs b/Runtime/Scripts/Dto/SkProduct/SKProduct.cs similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProduct.cs rename to Runtime/Scripts/Dto/SkProduct/SKProduct.cs diff --git a/Runtime/Scripts/Models/SkProduct/SKProduct.cs.meta b/Runtime/Scripts/Dto/SkProduct/SKProduct.cs.meta similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProduct.cs.meta rename to Runtime/Scripts/Dto/SkProduct/SKProduct.cs.meta diff --git a/Runtime/Scripts/Models/SkProduct/SKProductDiscount.cs b/Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProductDiscount.cs rename to Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs diff --git a/Runtime/Scripts/Models/SkProduct/SKProductDiscount.cs.meta b/Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs.meta similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProductDiscount.cs.meta rename to Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs.meta diff --git a/Runtime/Scripts/Models/SkProduct/SKProductSubscriptionPeriod.cs b/Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProductSubscriptionPeriod.cs rename to Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs diff --git a/Runtime/Scripts/Models/SkProduct/SKProductSubscriptionPeriod.cs.meta b/Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs.meta similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProductSubscriptionPeriod.cs.meta rename to Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs.meta diff --git a/Runtime/Scripts/Models/SkuDetails.cs b/Runtime/Scripts/Dto/SkuDetails.cs similarity index 99% rename from Runtime/Scripts/Models/SkuDetails.cs rename to Runtime/Scripts/Dto/SkuDetails.cs index b943373..ed4a94b 100644 --- a/Runtime/Scripts/Models/SkuDetails.cs +++ b/Runtime/Scripts/Dto/SkuDetails.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace QonversionUnity diff --git a/Runtime/Scripts/Models/SkuDetails.cs.meta b/Runtime/Scripts/Dto/SkuDetails.cs.meta similarity index 100% rename from Runtime/Scripts/Models/SkuDetails.cs.meta rename to Runtime/Scripts/Dto/SkuDetails.cs.meta diff --git a/Runtime/Scripts/Models/UserProperty.cs b/Runtime/Scripts/Dto/UserProperty.cs similarity index 100% rename from Runtime/Scripts/Models/UserProperty.cs rename to Runtime/Scripts/Dto/UserProperty.cs diff --git a/Runtime/Scripts/Models/UserProperty.cs.meta b/Runtime/Scripts/Dto/UserProperty.cs.meta similarity index 100% rename from Runtime/Scripts/Models/UserProperty.cs.meta rename to Runtime/Scripts/Dto/UserProperty.cs.meta From 3a30f3c9adb58032893ab42e4c11c4943b083962 Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Fri, 18 Nov 2022 19:32:27 +0600 Subject: [PATCH 05/22] CSharp part of major release support. --- Runtime/Android/AutomationsWrapperAndroid.cs | 55 ++ .../Android/AutomationsWrapperAndroid.cs.meta | 3 + Runtime/Android/QonversionWrapperAndroid.cs | 61 +- Runtime/Scripts/Automations.cs | 79 +- .../Scripts/{ => Dto}/AutomationsDelegate.cs | 2 +- .../{ => Dto}/AutomationsDelegate.cs.meta | 0 Runtime/Scripts/Dto/Environment.cs | 8 + Runtime/Scripts/Dto/Environment.cs.meta | 3 + Runtime/Scripts/Dto/LaunchMode.cs | 8 + Runtime/Scripts/Dto/LaunchMode.cs.meta | 3 + Runtime/Scripts/Dto/User.cs | 36 + Runtime/Scripts/Dto/User.cs.meta | 3 + Runtime/Scripts/IQonversionResultHandler.cs | 9 - .../Scripts/IQonversionResultHandler.cs.meta | 11 - Runtime/Scripts/InitDelegate.cs | 7 - Runtime/Scripts/InitEvent.cs | 8 - Runtime/Scripts/InitEvent.cs.meta | 11 - Runtime/Scripts/Internal.meta | 3 + .../Scripts/Internal/AutomationsInternal.cs | 137 +++ .../Internal/AutomationsInternal.cs.meta | 3 + Runtime/Scripts/{ => Internal}/Constants.cs | 2 +- .../Scripts/{ => Internal}/Constants.cs.meta | 0 Runtime/Scripts/{ => Internal}/Mapper.cs | 25 +- Runtime/Scripts/{ => Internal}/Mapper.cs.meta | 0 .../Scripts/Internal/QonversionInternal.cs | 471 ++++++++++ .../QonversionInternal.cs.meta} | 2 +- Runtime/Scripts/{ => Internal}/Utils.cs | 0 Runtime/Scripts/{ => Internal}/Utils.cs.meta | 0 Runtime/Scripts/Internal/wrappers.meta | 3 + .../Internal/wrappers/automations.meta | 3 + .../automations/IAutomationsWrapper.cs | 14 + .../automations/IAutomationsWrapper.cs.meta | 3 + .../automations/QonversionWrapperNoop.cs | 31 + .../automations/QonversionWrapperNoop.cs.meta | 3 + .../Scripts/Internal/wrappers/qonversion.meta | 3 + .../qonversion}/IQonversionWrapper.cs | 11 +- .../qonversion}/IQonversionWrapper.cs.meta | 0 .../qonversion}/QonversionWrapperNoop.cs | 30 +- .../qonversion}/QonversionWrapperNoop.cs.meta | 0 Runtime/Scripts/Qonversion.cs | 874 ++++-------------- Runtime/Scripts/Qonversion.cs.meta | 12 +- Runtime/Scripts/QonversionAndroidHandler.cs | 26 - .../Scripts/QonversionAndroidHandler.cs.meta | 11 - Runtime/Scripts/QonversionConfig.cs | 18 + Runtime/Scripts/QonversionConfig.cs.meta | 3 + Runtime/Scripts/QonversionConfigBuilder.cs | 55 ++ .../Scripts/QonversionConfigBuilder.cs.meta | 3 + Runtime/Scripts/QonversionLauncher.cs | 29 - Runtime/Scripts/QonversionLauncher.cs.meta | 11 - Runtime/iOS/AutomationsWrapperIOS.cs | 76 ++ Runtime/iOS/AutomationsWrapperIOS.cs.meta | 3 + Runtime/iOS/QonversionWrapperIOS.cs | 73 +- 52 files changed, 1249 insertions(+), 996 deletions(-) create mode 100644 Runtime/Android/AutomationsWrapperAndroid.cs create mode 100644 Runtime/Android/AutomationsWrapperAndroid.cs.meta rename Runtime/Scripts/{ => Dto}/AutomationsDelegate.cs (91%) rename Runtime/Scripts/{ => Dto}/AutomationsDelegate.cs.meta (100%) create mode 100644 Runtime/Scripts/Dto/Environment.cs create mode 100644 Runtime/Scripts/Dto/Environment.cs.meta create mode 100644 Runtime/Scripts/Dto/LaunchMode.cs create mode 100644 Runtime/Scripts/Dto/LaunchMode.cs.meta create mode 100644 Runtime/Scripts/Dto/User.cs create mode 100644 Runtime/Scripts/Dto/User.cs.meta delete mode 100644 Runtime/Scripts/IQonversionResultHandler.cs delete mode 100644 Runtime/Scripts/IQonversionResultHandler.cs.meta delete mode 100644 Runtime/Scripts/InitDelegate.cs delete mode 100644 Runtime/Scripts/InitEvent.cs delete mode 100644 Runtime/Scripts/InitEvent.cs.meta create mode 100644 Runtime/Scripts/Internal.meta create mode 100644 Runtime/Scripts/Internal/AutomationsInternal.cs create mode 100644 Runtime/Scripts/Internal/AutomationsInternal.cs.meta rename Runtime/Scripts/{ => Internal}/Constants.cs (73%) rename Runtime/Scripts/{ => Internal}/Constants.cs.meta (100%) rename Runtime/Scripts/{ => Internal}/Mapper.cs (83%) rename Runtime/Scripts/{ => Internal}/Mapper.cs.meta (100%) create mode 100644 Runtime/Scripts/Internal/QonversionInternal.cs rename Runtime/Scripts/{InitDelegate.cs.meta => Internal/QonversionInternal.cs.meta} (83%) rename Runtime/Scripts/{ => Internal}/Utils.cs (100%) rename Runtime/Scripts/{ => Internal}/Utils.cs.meta (100%) create mode 100644 Runtime/Scripts/Internal/wrappers.meta create mode 100644 Runtime/Scripts/Internal/wrappers/automations.meta create mode 100644 Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs create mode 100644 Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta create mode 100644 Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs create mode 100644 Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs.meta create mode 100644 Runtime/Scripts/Internal/wrappers/qonversion.meta rename Runtime/Scripts/{ => Internal/wrappers/qonversion}/IQonversionWrapper.cs (73%) rename Runtime/Scripts/{ => Internal/wrappers/qonversion}/IQonversionWrapper.cs.meta (100%) rename Runtime/Scripts/{ => Internal/wrappers/qonversion}/QonversionWrapperNoop.cs (75%) rename Runtime/Scripts/{ => Internal/wrappers/qonversion}/QonversionWrapperNoop.cs.meta (100%) delete mode 100644 Runtime/Scripts/QonversionAndroidHandler.cs delete mode 100644 Runtime/Scripts/QonversionAndroidHandler.cs.meta create mode 100644 Runtime/Scripts/QonversionConfig.cs create mode 100644 Runtime/Scripts/QonversionConfig.cs.meta create mode 100644 Runtime/Scripts/QonversionConfigBuilder.cs create mode 100644 Runtime/Scripts/QonversionConfigBuilder.cs.meta delete mode 100644 Runtime/Scripts/QonversionLauncher.cs delete mode 100644 Runtime/Scripts/QonversionLauncher.cs.meta create mode 100644 Runtime/iOS/AutomationsWrapperIOS.cs create mode 100644 Runtime/iOS/AutomationsWrapperIOS.cs.meta diff --git a/Runtime/Android/AutomationsWrapperAndroid.cs b/Runtime/Android/AutomationsWrapperAndroid.cs new file mode 100644 index 0000000..0c97b24 --- /dev/null +++ b/Runtime/Android/AutomationsWrapperAndroid.cs @@ -0,0 +1,55 @@ +using UnityEngine; + +namespace QonversionUnity +{ + internal class AutomationsWrapperAndroid : IAutomationsWrapper + { + public void Initialize(string gameObjectName) + { + CallQonversion("initialize", gameObjectName); + } + + public void InitializeSdk() + { + CallQonversion("initializeSdk"); + } + + public void SetNotificationsToken(string token) + { + CallQonversion("setNotificationsToken", token); + } + + public bool HandleNotification(string notification) + { + return CallQonversion("handleNotification", notification); + } + + public string GetNotificationCustomPayload(string notification) + { + return CallQonversion("getNotificationCustomPayload", notification); + } + + public void SubscribeOnAutomationEvents() + { + CallQonversion("subscribeOnAutomationEvents"); + } + + private const string AutomationsWrapper = "com.qonversion.unitywrapper.AutomationsWrapper"; + + private static T CallQonversion(string methodName, params object[] args) + { + using (var automations = new AndroidJavaClass(AutomationsWrapper)) + { + return automations.CallStatic(methodName, args); + } + } + + private static void CallQonversion(string methodName, params object[] args) + { + using (var automations = new AndroidJavaClass(AutomationsWrapper)) + { + automations.CallStatic(methodName, args); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Android/AutomationsWrapperAndroid.cs.meta b/Runtime/Android/AutomationsWrapperAndroid.cs.meta new file mode 100644 index 0000000..70fa1d1 --- /dev/null +++ b/Runtime/Android/AutomationsWrapperAndroid.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bf1469979a8544c5b531368ea34cec2f +timeCreated: 1668776137 \ No newline at end of file diff --git a/Runtime/Android/QonversionWrapperAndroid.cs b/Runtime/Android/QonversionWrapperAndroid.cs index a2f592d..4ab59b9 100644 --- a/Runtime/Android/QonversionWrapperAndroid.cs +++ b/Runtime/Android/QonversionWrapperAndroid.cs @@ -1,6 +1,5 @@ using System; -using System.Collections.Generic; -using QonversionUnity.MiniJSON; +using JetBrains.Annotations; using UnityEngine; namespace QonversionUnity @@ -17,9 +16,9 @@ public void StoreSdkInfo(string version, string source) CallQonversion("storeSdkInfo", version, source); } - public void InitializeSdk(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime) { - CallQonversion("initializeSdk", projectKey, observerMode, callbackName); + CallQonversion("initializeSdk", projectKey, launchMode, environment, entitlementsCacheLifetime); } public void SetDebugMode() @@ -61,29 +60,11 @@ public void SetAppleSearchAdsAttributionEnabled(bool enable) { } - public void AddAttributionData(string conversionData, AttributionProvider provider) + public void AddAttributionData(string conversionData, string providerName) { - string attibutionProvider; - - switch (provider) - { - case AttributionProvider.AppsFlyer: - attibutionProvider = "AppsFlyer"; - break; - case AttributionProvider.Branch: - attibutionProvider = "Branch"; - break; - case AttributionProvider.Adjust: - attibutionProvider = "Adjust"; - break; - default: - Debug.LogWarning(string.Format("[Qonversion] Not Supported AttributionProvider.{0} on Android platform.", provider)); - return; - } - try { - CallQonversion("attribution", conversionData, attibutionProvider); + CallQonversion("attribution", conversionData, providerName); } catch (Exception e) { @@ -101,6 +82,11 @@ public void Logout() CallQonversion("logout"); } + public void UserInfo(string callbackName) + { + CallQonversion("userInfo", callbackName); + } + public void CheckEntitlements(string callbackName) { CallQonversion("checkEntitlements", callbackName); @@ -146,24 +132,8 @@ public void CheckTrialIntroEligibility(string productIdsJson, string callbackNam CallQonversion("checkTrialIntroEligibility", productIdsJson, callbackName); } - public void SetNotificationsToken(string token) - { - CallQonversion("setNotificationsToken", token); - } - - public bool HandleNotification(string notification) - { - return CallQonversion("handleNotification", notification); - } - - public string GetNotificationCustomPayload(string notification) - { - return CallQonversion("getNotificationCustomPayload", notification); - } - - public void SubscribeOnAutomationEvents() + public void PromoPurchase(string storeProductId, string callbackName) { - CallQonversion("subscribeOnAutomationEvents"); } private const string QonversionWrapper = "com.qonversion.unitywrapper.QonversionWrapper"; @@ -183,14 +153,5 @@ private static void CallQonversion(string methodName, params object[] args) qonversion.CallStatic(methodName, args); } } - - public void PromoPurchase(string storeProductId, string callbackName) - { - } - - public void SetPermissionsCacheLifetime(string lifetime) - { - CallQonversion("setPermissionsCacheLifetime", lifetime); - } } } \ No newline at end of file diff --git a/Runtime/Scripts/Automations.cs b/Runtime/Scripts/Automations.cs index c9c464a..faf02f5 100644 --- a/Runtime/Scripts/Automations.cs +++ b/Runtime/Scripts/Automations.cs @@ -1,17 +1,84 @@ -using UnityEngine; +using System; +using System.Collections.Generic; +using JetBrains.Annotations; +using UnityEngine; namespace QonversionUnity { - public partial class Automations : MonoBehaviour + public abstract class Automations : MonoBehaviour { + [CanBeNull] private static Automations _backingInstance; + + /// + /// Use this variable to get a current initialized instance of the Qonversion Automations. + /// Please, use the property only after calling . + /// Otherwise, trying to access the variable will cause an exception. + /// + /// Current initialized instance of the Qonversion Automations. + /// throws exception if the instance has not been initialized + public static Automations GetSharedInstance() + { + if (_backingInstance == null) + { + throw new Exception( + "Automations has not been initialized. You should call " + + "the initialize method before accessing the shared instance of Automations." + ); + } + + return _backingInstance; + } + + /// + /// An entry point to use Qonversion Automations. Call to initialize Automations. + /// Make sure you have initialized first. + /// + /// Initialized instance of the Qonversion Automations. + /// throws exception if has not been initialized + public static Automations Initialize() + { + try + { + Qonversion.GetSharedInstance(); + } + catch (Exception e) + { + throw new Exception("Qonversion has not been initialized. " + + "Automations initialization should be called after Qonversion is initialized."); + } + + _backingInstance = new AutomationsInternal(); + return _backingInstance; + } + /// /// The Automations delegate is responsible for handling in-app screens and actions when push notification is received. /// Make sure the method is called before Qonversion.handleNotification. /// /// The delegate to handle automations events - public static void SetDelegate(AutomationsDelegate automationsDelegate) - { - Qonversion.SetAutomationsDelegate(automationsDelegate); - } + public abstract void SetDelegate(AutomationsDelegate automationsDelegate); + + /// + /// Set push token to Qonversion to enable Qonversion push notifications + /// + /// Firebase device token on Android. APNs device token on iOS. + public abstract void SetNotificationsToken(string token); + + /// + /// Call to handle push notifications sent by Qonversion Automations. + /// + /// notification payload data + /// true when a push notification was received from Qonversion. Otherwise, returns false, so you need to handle a notification yourself + /// Firebase RemoteMessage data + /// APNs notification data + public abstract bool HandleNotification(Dictionary notification); + + /// + /// Get parsed custom payload, which you added to the notification in the dashboard + /// + /// notification payload data + /// a map with custom payload from the notification or null if it's not provided + [CanBeNull] + public abstract Dictionary GetNotificationCustomPayload(Dictionary notification); } } diff --git a/Runtime/Scripts/AutomationsDelegate.cs b/Runtime/Scripts/Dto/AutomationsDelegate.cs similarity index 91% rename from Runtime/Scripts/AutomationsDelegate.cs rename to Runtime/Scripts/Dto/AutomationsDelegate.cs index 0c569ae..e6cd12a 100644 --- a/Runtime/Scripts/AutomationsDelegate.cs +++ b/Runtime/Scripts/Dto/AutomationsDelegate.cs @@ -28,7 +28,7 @@ public abstract class AutomationsDelegate : MonoBehaviour /// /// Called when Automations flow finishes executing an action /// For instance, if the user made a purchase then action.type == QONActionResultTypePurchase - /// Then you can use the method to get available permissions + /// Then you can use the method to get available permissions /// /// executed action public abstract void OnAutomationsActionFinished(ActionResult actionResult); diff --git a/Runtime/Scripts/AutomationsDelegate.cs.meta b/Runtime/Scripts/Dto/AutomationsDelegate.cs.meta similarity index 100% rename from Runtime/Scripts/AutomationsDelegate.cs.meta rename to Runtime/Scripts/Dto/AutomationsDelegate.cs.meta diff --git a/Runtime/Scripts/Dto/Environment.cs b/Runtime/Scripts/Dto/Environment.cs new file mode 100644 index 0000000..f28363b --- /dev/null +++ b/Runtime/Scripts/Dto/Environment.cs @@ -0,0 +1,8 @@ +namespace QonversionUnity +{ + public enum Environment + { + Sandbox, + Production + } +} diff --git a/Runtime/Scripts/Dto/Environment.cs.meta b/Runtime/Scripts/Dto/Environment.cs.meta new file mode 100644 index 0000000..417ae4e --- /dev/null +++ b/Runtime/Scripts/Dto/Environment.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1b02fbe89ab349a59491d47e9ca2329d +timeCreated: 1668682691 \ No newline at end of file diff --git a/Runtime/Scripts/Dto/LaunchMode.cs b/Runtime/Scripts/Dto/LaunchMode.cs new file mode 100644 index 0000000..b847756 --- /dev/null +++ b/Runtime/Scripts/Dto/LaunchMode.cs @@ -0,0 +1,8 @@ +namespace QonversionUnity +{ + public enum LaunchMode + { + Analytics, + SubscriptionManagement + } +} \ No newline at end of file diff --git a/Runtime/Scripts/Dto/LaunchMode.cs.meta b/Runtime/Scripts/Dto/LaunchMode.cs.meta new file mode 100644 index 0000000..82beaa8 --- /dev/null +++ b/Runtime/Scripts/Dto/LaunchMode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 24dcbe0f097a40c59733cfbd46312398 +timeCreated: 1668682749 \ No newline at end of file diff --git a/Runtime/Scripts/Dto/User.cs b/Runtime/Scripts/Dto/User.cs new file mode 100644 index 0000000..ff8e9e3 --- /dev/null +++ b/Runtime/Scripts/Dto/User.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace QonversionUnity +{ + public class User + { + public readonly string QonversionId; + [CanBeNull] public readonly string IdentityId; + + public User(string qonversionId, [CanBeNull] string identityId) + { + QonversionId = qonversionId; + IdentityId = identityId; + } + + public User(Dictionary dict) + { + if (dict.TryGetValue("qonversionId", out var qonversionId) && qonversionId != null) + { + QonversionId = qonversionId as string; + } + + if (dict.TryGetValue("identityId", out var identityId) && identityId != null) + { + IdentityId = identityId as string; + } + } + + public override string ToString() + { + return $"{nameof(QonversionId)}: {QonversionId}, " + + $"{nameof(IdentityId)}: {IdentityId}"; + } + } +} diff --git a/Runtime/Scripts/Dto/User.cs.meta b/Runtime/Scripts/Dto/User.cs.meta new file mode 100644 index 0000000..7eda00b --- /dev/null +++ b/Runtime/Scripts/Dto/User.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e90e3bc36aae4e069c0c373e53427b0c +timeCreated: 1668747828 \ No newline at end of file diff --git a/Runtime/Scripts/IQonversionResultHandler.cs b/Runtime/Scripts/IQonversionResultHandler.cs deleted file mode 100644 index b057ae2..0000000 --- a/Runtime/Scripts/IQonversionResultHandler.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace QonversionUnity -{ - internal interface IQonversionResultHandler - { - void onSuccessInit(string uid); - - void onErrorInit(string errorMessage); - } -} \ No newline at end of file diff --git a/Runtime/Scripts/IQonversionResultHandler.cs.meta b/Runtime/Scripts/IQonversionResultHandler.cs.meta deleted file mode 100644 index 9e1310e..0000000 --- a/Runtime/Scripts/IQonversionResultHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0da42bd95a3b8ca4087c7fd255c437d5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Scripts/InitDelegate.cs b/Runtime/Scripts/InitDelegate.cs deleted file mode 100644 index c440e68..0000000 --- a/Runtime/Scripts/InitDelegate.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace QonversionUnity -{ - /// - /// Init delegate. - /// - public delegate void InitDelegate(); -} \ No newline at end of file diff --git a/Runtime/Scripts/InitEvent.cs b/Runtime/Scripts/InitEvent.cs deleted file mode 100644 index 36cb04e..0000000 --- a/Runtime/Scripts/InitEvent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using UnityEngine.Events; - -namespace QonversionUnity -{ - [System.Serializable] - public class InitEvent : UnityEvent - {} -} \ No newline at end of file diff --git a/Runtime/Scripts/InitEvent.cs.meta b/Runtime/Scripts/InitEvent.cs.meta deleted file mode 100644 index ec73118..0000000 --- a/Runtime/Scripts/InitEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e3083807ce0ef5d488edcd762c9afa93 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Scripts/Internal.meta b/Runtime/Scripts/Internal.meta new file mode 100644 index 0000000..43a7970 --- /dev/null +++ b/Runtime/Scripts/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 00384c60219c4bda98b08e4f7c65bc6f +timeCreated: 1668672384 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/AutomationsInternal.cs b/Runtime/Scripts/Internal/AutomationsInternal.cs new file mode 100644 index 0000000..7fd1867 --- /dev/null +++ b/Runtime/Scripts/Internal/AutomationsInternal.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using QonversionUnity.MiniJSON; +using UnityEngine; + +namespace QonversionUnity +{ + internal class AutomationsInternal : Automations + { + private const string GameObjectName = "QonvesrionAutomationsRuntimeGameObject"; + private IAutomationsWrapper _nativeWrapperInstance; + private AutomationsDelegate _automationsDelegate; + + public override void SetDelegate(AutomationsDelegate automationsDelegate) + { + _automationsDelegate = automationsDelegate; + + IAutomationsWrapper instance = GetNativeWrapper(); + instance.SubscribeOnAutomationEvents(); + } + + public override void SetNotificationsToken(string token) + { + IAutomationsWrapper instance = GetNativeWrapper(); + instance.SetNotificationsToken(token); + } + + public override bool HandleNotification(Dictionary notification) + { + IAutomationsWrapper instance = GetNativeWrapper(); + return instance.HandleNotification(notification.toJson()); + } + + public override Dictionary GetNotificationCustomPayload(Dictionary notification) + { + IAutomationsWrapper instance = GetNativeWrapper(); + var payloadJson = instance.GetNotificationCustomPayload(notification.toJson()); + + if (payloadJson == null) + { + return null; + } + + if (!(Json.Deserialize(payloadJson) is Dictionary response)) + { + Debug.LogError("Could not parse custom notification payload."); + return null; + } + + return response; + } + + private IAutomationsWrapper GetNativeWrapper() + { + if (_nativeWrapperInstance != null) + { + return _nativeWrapperInstance; + } + + switch (Application.platform) + { + case RuntimePlatform.Android: + _nativeWrapperInstance = new AutomationsWrapperAndroid(); + break; + case RuntimePlatform.IPhonePlayer: + _nativeWrapperInstance = new AutomationsWrapperIOS(); + break; + default: + _nativeWrapperInstance = new AutomationsWrapperNoop(); + break; + } + _nativeWrapperInstance.Initialize(GameObjectName); + + GameObject go = new GameObject(GameObjectName); + go.AddComponent(); + DontDestroyOnLoad(go); + + return _nativeWrapperInstance; + } + + // The below methods are called from native when Automations events occur + private void OnAutomationsScreenShown(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + string screenId = Mapper.ScreenIdFromJson(jsonString); + + _automationsDelegate.OnAutomationsScreenShown(screenId); + } + + private void OnAutomationsActionStarted(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); + _automationsDelegate.OnAutomationsActionStarted(actionResult); + } + + private void OnAutomationsActionFailed(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); + _automationsDelegate.OnAutomationsActionFailed(actionResult); + } + + + private void OnAutomationsActionFinished(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); + _automationsDelegate.OnAutomationsActionFinished(actionResult); + } + + private void OnAutomationsFinished(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + _automationsDelegate.OnAutomationsFinished(); + } + } +} diff --git a/Runtime/Scripts/Internal/AutomationsInternal.cs.meta b/Runtime/Scripts/Internal/AutomationsInternal.cs.meta new file mode 100644 index 0000000..e936d9f --- /dev/null +++ b/Runtime/Scripts/Internal/AutomationsInternal.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c4a786ad04fb4a94b86844c34f317f23 +timeCreated: 1668753627 \ No newline at end of file diff --git a/Runtime/Scripts/Constants.cs b/Runtime/Scripts/Internal/Constants.cs similarity index 73% rename from Runtime/Scripts/Constants.cs rename to Runtime/Scripts/Internal/Constants.cs index 67b0cfc..e3bea8f 100644 --- a/Runtime/Scripts/Constants.cs +++ b/Runtime/Scripts/Internal/Constants.cs @@ -1,6 +1,6 @@ namespace QonversionUnity { - static class Constants + internal static class Constants { public const int SkuDetailsPriceRatio = 1000000; } diff --git a/Runtime/Scripts/Constants.cs.meta b/Runtime/Scripts/Internal/Constants.cs.meta similarity index 100% rename from Runtime/Scripts/Constants.cs.meta rename to Runtime/Scripts/Internal/Constants.cs.meta diff --git a/Runtime/Scripts/Mapper.cs b/Runtime/Scripts/Internal/Mapper.cs similarity index 83% rename from Runtime/Scripts/Mapper.cs rename to Runtime/Scripts/Internal/Mapper.cs index fd49216..42e87a9 100644 --- a/Runtime/Scripts/Mapper.cs +++ b/Runtime/Scripts/Internal/Mapper.cs @@ -18,22 +18,22 @@ internal static bool GetIsCancelledFromJson(string jsonStr) return result.TryGetValue("isCancelled", out var isCancelled) && Convert.ToBoolean(isCancelled); } - internal static Dictionary PermissionsFromJson(string jsonStr) + internal static Dictionary EntitlementsFromJson(string jsonStr) { var result = new Dictionary(); - if (!(Json.Deserialize(jsonStr) is Dictionary permissions)) + if (!(Json.Deserialize(jsonStr) is Dictionary entitlements)) { - Debug.LogError("Could not parse QPermissions"); + Debug.LogError("Could not parse QEntitlements"); return result; } - foreach (KeyValuePair permissionPair in permissions) + foreach (KeyValuePair entitlementPair in entitlements) { - if (permissionPair.Value is Dictionary permissionDict) + if (entitlementPair.Value is Dictionary entitlementDict) { - Entitlement entitlement = new Entitlement(permissionDict); - result.Add(permissionPair.Key, entitlement); + Entitlement entitlement = new Entitlement(entitlementDict); + result.Add(entitlementPair.Key, entitlement); } } @@ -117,6 +117,17 @@ internal static Dictionary EligibilitiesFromJson(string jso return result; } + internal static User UserFromJson(string jsonStr) + { + if (!(Json.Deserialize(jsonStr) is Dictionary userInfo)) + { + Debug.LogError("Could not parse User"); + return new User("", null); + } + + return new User(userInfo); + } + internal static QonversionError ErrorFromJson(string jsonStr) { if (!(Json.Deserialize(jsonStr) is Dictionary dict)) return null; diff --git a/Runtime/Scripts/Mapper.cs.meta b/Runtime/Scripts/Internal/Mapper.cs.meta similarity index 100% rename from Runtime/Scripts/Mapper.cs.meta rename to Runtime/Scripts/Internal/Mapper.cs.meta diff --git a/Runtime/Scripts/Internal/QonversionInternal.cs b/Runtime/Scripts/Internal/QonversionInternal.cs new file mode 100644 index 0000000..14f5b14 --- /dev/null +++ b/Runtime/Scripts/Internal/QonversionInternal.cs @@ -0,0 +1,471 @@ +using JetBrains.Annotations; +using QonversionUnity.MiniJSON; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace QonversionUnity +{ + internal class QonversionInternal : MonoBehaviour, Qonversion + { + private const string GameObjectName = "QonvesrionRuntimeGameObject"; + private const string OnCheckEntitlementsMethodName = "OnCheckEntitlements"; + private const string OnPurchaseMethodName = "OnPurchase"; + private const string OnPromoPurchaseMethodName = "OnPromoPurchase"; + private const string OnPurchaseProductMethodName = "OnPurchaseProduct"; + private const string OnUpdatePurchaseMethodName = "OnUpdatePurchase"; + private const string OnUpdatePurchaseWithProductMethodName = "OnUpdatePurchaseWithProduct"; + private const string OnRestoreMethodName = "OnRestore"; + private const string OnProductsMethodName = "OnProducts"; + private const string OnOfferingsMethodName = "OnOfferings"; + private const string OnEligibilitiesMethodName = "OnEligibilities"; + private const string OnUserInfoMethodName = "OnUserInfo"; + + private const string SdkVersion = "3.7.1"; + private const string SdkSource = "unity"; + + private IQonversionWrapper _nativeWrapperInstance; + private Qonversion.OnUpdatedEntitlementsReceived _onUpdatedEntitlementsReceived; + + private Qonversion.OnPromoPurchasesReceived _onPromoPurchasesReceived; + private string _storedPromoProductId = null; + + private List CheckEntitlementsCallbacks { get; } = new List(); + private List RestoreCallbacks { get; } = new List(); + private Qonversion.OnPurchaseResultReceived PurchaseCallback { get; set; } + private Qonversion.OnPurchaseResultReceived PurchaseProductCallback { get; set; } + private Qonversion.OnPurchaseResultReceived UpdatePurchaseCallback { get; set; } + private Qonversion.OnPurchaseResultReceived UpdatePurchaseWithProductCallback { get; set; } + private List ProductsCallbacks { get; } = new List(); + private List OfferingsCallbacks { get; } = new List(); + private Qonversion.OnEligibilitiesReceived EligibilitiesCallback { get; set; } + private Qonversion.OnEntitlementsReceived PromoPurchaseCallback { get; set; } + private Qonversion.OnUserInfoReceived UserInfoCallback { get; set; } + + public event Qonversion.OnPromoPurchasesReceived PromoPurchasesReceived + { + add + { + _onPromoPurchasesReceived += value; + } + remove + { + _onPromoPurchasesReceived -= value; + } + } + + public event Qonversion.OnUpdatedEntitlementsReceived UpdatedEntitlementsReceived + { + add + { + _onUpdatedEntitlementsReceived += value; + } + remove + { + _onUpdatedEntitlementsReceived -= value; + } + } + + public QonversionInternal(QonversionConfig config) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.StoreSdkInfo(SdkVersion, SdkSource); + + string launchModeKey = Enum.GetName(typeof(LaunchMode), config.LaunchMode); + string environmentKey = config.Environment == null + ? Enum.GetName(typeof(Environment), config.Environment) + : null; + string cacheLifetimeKey = config.EntitlementsCacheLifetime == null + ? Enum.GetName(typeof(EntitlementsCacheLifetime), config.EntitlementsCacheLifetime) + : null; + + instance.InitializeSdk(config.ProjectKey, launchModeKey, environmentKey, cacheLifetimeKey); + } + + public void Purchase(string productId, Qonversion.OnPurchaseResultReceived callback) + { + PurchaseCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.Purchase(productId, OnPurchaseMethodName); + } + + public void PurchaseProduct([NotNull] Product product, Qonversion.OnPurchaseResultReceived callback) + { + if (product == null) + { + callback(null, new QonversionError("PurchaseInvalid", "Product is null"), false); + return; + } + + PurchaseProductCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.PurchaseProduct(product.QonversionId, product.OfferingId, OnPurchaseProductMethodName); + } + + public void UpdatePurchase(string productId, string oldProductId, Qonversion.OnPurchaseResultReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) + { + UpdatePurchaseCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.UpdatePurchase(productId, oldProductId, prorationMode, OnUpdatePurchaseMethodName); + } + + public void UpdatePurchaseWithProduct([NotNull] Product product, string oldProductId, Qonversion.OnPurchaseResultReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) + { + if (product == null) + { + callback(null, new QonversionError("PurchaseInvalid", "Product is null"), false); + return; + } + + UpdatePurchaseWithProductCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.UpdatePurchaseWithProduct(product.QonversionId, product.OfferingId, oldProductId, prorationMode, OnUpdatePurchaseWithProductMethodName); + } + + public void Products(Qonversion.OnProductsReceived callback) + { + ProductsCallbacks.Add(callback); + IQonversionWrapper instance = GetNativeWrapper(); + instance.Products(OnProductsMethodName); + } + + public void Offerings(Qonversion.OnOfferingsReceived callback) + { + OfferingsCallbacks.Add(callback); + IQonversionWrapper instance = GetNativeWrapper(); + instance.Offerings(OnOfferingsMethodName); + } + + public void CheckTrialIntroEligibility(IList productIds, Qonversion.OnEligibilitiesReceived callback) + { + var productIdsJson = Json.Serialize(productIds); + + EligibilitiesCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.CheckTrialIntroEligibility(productIdsJson, OnEligibilitiesMethodName); + } + + public void CheckEntitlements(Qonversion.OnEntitlementsReceived callback) + { + CheckEntitlementsCallbacks.Add(callback); + IQonversionWrapper instance = GetNativeWrapper(); + instance.CheckEntitlements(OnCheckEntitlementsMethodName); + } + + public void Restore(Qonversion.OnEntitlementsReceived callback) + { + RestoreCallbacks.Add(callback); + IQonversionWrapper instance = GetNativeWrapper(); + instance.Restore(OnRestoreMethodName); + } + + public void SyncPurchases() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SyncPurchases(); + } + + public void Identify(string userID) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.Identify(userID); + } + + public void Logout() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.Logout(); + } + + public void UserInfo(Qonversion.OnUserInfoReceived callback) + { + UserInfoCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.UserInfo(OnUserInfoMethodName); + } + + public void Attribution(Dictionary conversionData, AttributionProvider attributionProvider) + { + Attribution(conversionData.toJson(), attributionProvider); + } + + public void Attribution(string conversionData, AttributionProvider attributionProvider) + { + string providerName = Enum.GetName(typeof(AttributionProvider), attributionProvider); + + IQonversionWrapper instance = GetNativeWrapper(); + + instance.AddAttributionData(conversionData, providerName); + } + + public void SetProperty(UserProperty key, string value) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SetProperty(key, value); + } + + public void SetUserProperty(string key, string value) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SetUserProperty(key, value); + } + + public void SetAdvertisingID() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SetAdvertisingID(); + } + + public void SetAppleSearchAdsAttributionEnabled(bool enable) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SetAppleSearchAdsAttributionEnabled(enable); + } + + public void PresentCodeRedemptionSheet() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.PresentCodeRedemptionSheet(); + } + + // Called from the native SDK - Called when entitlements received from the checkEntitlements() method + private void OnCheckEntitlements(string jsonString) + { + Debug.Log("OnCheckEntitlements " + jsonString); + HandleEntitlements(CheckEntitlementsCallbacks, jsonString); + CheckEntitlementsCallbacks.Clear(); + } + + // Called from the native SDK - Called when purchase result received from the purchase() method + private void OnPurchase(string jsonString) + { + Debug.Log("OnPurchase callback " + jsonString); + HandlePurchaseResult(PurchaseCallback, jsonString); + PurchaseCallback = null; + } + + // Called from the native SDK - Called when purchase result received from the purchaseProduct() method + private void OnPurchaseProduct(string jsonString) + { + Debug.Log("OnPurchaseProduct callback " + jsonString); + HandlePurchaseResult(PurchaseProductCallback, jsonString); + PurchaseProductCallback = null; + } + + // Called from the native SDK - Called when entitlements received from the restore() method + private void OnRestore(string jsonString) + { + Debug.Log("OnRestore " + jsonString); + HandleEntitlements(RestoreCallbacks, jsonString); + RestoreCallbacks.Clear(); + } + + // Called from the native SDK - Called when purchase result received from the updatePurchase() method + private void OnUpdatePurchase(string jsonString) + { + Debug.Log("OnUpdatePurchase " + jsonString); + HandlePurchaseResult(UpdatePurchaseCallback, jsonString); + UpdatePurchaseCallback = null; + } + + // Called from the native SDK - Called when purchase result received from the updatePurchaseWithProduct() method + private void OnUpdatePurchaseWithProduct(string jsonString) + { + Debug.Log("OnUpdatePurchaseWithProduct " + jsonString); + HandlePurchaseResult(UpdatePurchaseWithProductCallback, jsonString); + UpdatePurchaseWithProductCallback = null; + } + + // Called from the native SDK - Called when entitlements received from the promoPurchase() method + private void OnPromoPurchase(string jsonString) + { + Debug.Log("OnPromoPurchase callback " + jsonString); + if (PromoPurchaseCallback != null) { + var callbacks = new List { PromoPurchaseCallback }; + HandleEntitlements(callbacks, jsonString); + } + + PromoPurchaseCallback = null; + _storedPromoProductId = null; + } + + // Called from the native SDK - Called when products received from the products() method + private void OnProducts(string jsonString) + { + Debug.Log("OnProducts " + jsonString); + + if (ProductsCallbacks.Count == 0) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + ProductsCallbacks.ForEach(callback => callback(null, error)); + } + else + { + var products = Mapper.ProductsFromJson(jsonString); + ProductsCallbacks.ForEach(callback => callback(products, null)); + } + + ProductsCallbacks.Clear(); + } + + // Called from the native SDK - Called when offerings received from the offerings() method + private void OnOfferings(string jsonString) + { + Debug.Log("OnOfferings " + jsonString); + + if (OfferingsCallbacks.Count == 0) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + OfferingsCallbacks.ForEach(callback => callback(null, error)); + } + else + { + var offerings = Mapper.OfferingsFromJson(jsonString); + OfferingsCallbacks.ForEach(callback => callback(offerings, null)); + } + + OfferingsCallbacks.Clear(); + } + + // Called from the native SDK - Called when eligibilities received from the checkTrialIntroEligibilityForProductIds() method + private void OnEligibilities(string jsonString) + { + Debug.Log("OnEligibilities " + jsonString); + + if (EligibilitiesCallback == null) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + EligibilitiesCallback(null, error); + } + else + { + Dictionary eligibilities = Mapper.EligibilitiesFromJson(jsonString); + EligibilitiesCallback(eligibilities, null); + } + + EligibilitiesCallback = null; + } + + // Called from the native SDK - Called when user info received from the UserInfo() method + private void OnUserInfo(string jsonString) + { + Debug.Log("OnUserInfo " + jsonString); + + if (UserInfoCallback == null) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + UserInfoCallback(null, error); + } + else + { + User userInfo = Mapper.UserFromJson(jsonString); + UserInfoCallback(userInfo, null); + } + + UserInfoCallback = null; + } + + // Called from the native SDK - Called when deferred or pending purchase occured + private void OnReceivedUpdatedEntitlements(string jsonString) + { + Debug.Log("OnReceivedUpdatedEntitlements " + jsonString); + + if (_onUpdatedEntitlementsReceived == null) + { + return; + } + + Dictionary entitlements = Mapper.EntitlementsFromJson(jsonString); + _onUpdatedEntitlementsReceived(entitlements); + } + + private void OnReceivePromoPurchase(string storeProductId) + { + Debug.Log("OnReceivePromoPurchase " + storeProductId); + + if (_onPromoPurchasesReceived == null) + { + return; + } + + _storedPromoProductId = storeProductId; + _onPromoPurchasesReceived(storeProductId, PromoPurchase); + } + + private void PromoPurchase(Qonversion.OnEntitlementsReceived callback) + { + PromoPurchaseCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.PromoPurchase(_storedPromoProductId, OnPromoPurchaseMethodName); + } + + private void HandleEntitlements(List callbacks, string jsonString) + { + if (callbacks.Count == 0) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + callbacks.ForEach(callback => callback(null, error)); + } + else + { + var entitlements = Mapper.EntitlementsFromJson(jsonString); + callbacks.ForEach(callback => callback(entitlements, null)); + } + } + + private void HandlePurchaseResult(Qonversion.OnPurchaseResultReceived callback, string jsonString) + { + if (callback == null) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + var isCancelled = Mapper.GetIsCancelledFromJson(jsonString); + callback(null, error, isCancelled); + } + else + { + var entitlements = Mapper.EntitlementsFromJson(jsonString); + callback(entitlements, null, false); + } + } + + private IQonversionWrapper GetNativeWrapper() + { + if (_nativeWrapperInstance != null) + { + return _nativeWrapperInstance; + } + + switch (Application.platform) + { + case RuntimePlatform.Android: + _nativeWrapperInstance = new QonversionWrapperAndroid(); + break; + case RuntimePlatform.IPhonePlayer: + _nativeWrapperInstance = new QonversionWrapperIOS(); + break; + default: + _nativeWrapperInstance = new QonversionWrapperNoop(); + break; + } + _nativeWrapperInstance.Initialize(GameObjectName); + + GameObject go = new GameObject(GameObjectName); + go.AddComponent(); + DontDestroyOnLoad(go); + + return _nativeWrapperInstance; + } + } +} diff --git a/Runtime/Scripts/InitDelegate.cs.meta b/Runtime/Scripts/Internal/QonversionInternal.cs.meta similarity index 83% rename from Runtime/Scripts/InitDelegate.cs.meta rename to Runtime/Scripts/Internal/QonversionInternal.cs.meta index 3fe0152..3d73b36 100644 --- a/Runtime/Scripts/InitDelegate.cs.meta +++ b/Runtime/Scripts/Internal/QonversionInternal.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 67b89adb9ad50f74a8161204ac657b36 +guid: 38c50778583feeb4da0934f2fa914b96 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/Scripts/Utils.cs b/Runtime/Scripts/Internal/Utils.cs similarity index 100% rename from Runtime/Scripts/Utils.cs rename to Runtime/Scripts/Internal/Utils.cs diff --git a/Runtime/Scripts/Utils.cs.meta b/Runtime/Scripts/Internal/Utils.cs.meta similarity index 100% rename from Runtime/Scripts/Utils.cs.meta rename to Runtime/Scripts/Internal/Utils.cs.meta diff --git a/Runtime/Scripts/Internal/wrappers.meta b/Runtime/Scripts/Internal/wrappers.meta new file mode 100644 index 0000000..7be01f6 --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bc8c98aad7534db3bf2a3733e1e9b9eb +timeCreated: 1668776043 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations.meta b/Runtime/Scripts/Internal/wrappers/automations.meta new file mode 100644 index 0000000..5c9d6fa --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d39ad171d37c4033a7b7a4c23c0ea18a +timeCreated: 1668776048 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs b/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs new file mode 100644 index 0000000..2b6e9ec --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs @@ -0,0 +1,14 @@ +using JetBrains.Annotations; + +namespace QonversionUnity +{ + internal interface IAutomationsWrapper + { + void Initialize(string gameObjectName); + void InitializeSdk(); + void SetNotificationsToken(string token); + bool HandleNotification(string notification); + [CanBeNull] string GetNotificationCustomPayload(string notification); + void SubscribeOnAutomationEvents(); + } +} diff --git a/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta b/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta new file mode 100644 index 0000000..317587d --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e55580a6da23457280c02026ad96b05d +timeCreated: 1668776004 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs b/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs new file mode 100644 index 0000000..5e0ce89 --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs @@ -0,0 +1,31 @@ +namespace QonversionUnity + { + internal class AutomationsWrapperNoop : IAutomationsWrapper + { + public void Initialize(string gameObjectName) + { + } + + public void InitializeSdk() + { + } + + public void SetNotificationsToken(string token) + { + } + + public bool HandleNotification(string notification) + { + return false; + } + + public string GetNotificationCustomPayload(string notification) + { + return null; + } + + public void SubscribeOnAutomationEvents() + { + } + } + } \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs.meta b/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs.meta new file mode 100644 index 0000000..94ad546 --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 52b5b093639a4d04ab569175864e233a +timeCreated: 1668776080 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/qonversion.meta b/Runtime/Scripts/Internal/wrappers/qonversion.meta new file mode 100644 index 0000000..8c5f0cb --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/qonversion.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b14757828b514a959d4e299c27c50782 +timeCreated: 1668776059 \ No newline at end of file diff --git a/Runtime/Scripts/IQonversionWrapper.cs b/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs similarity index 73% rename from Runtime/Scripts/IQonversionWrapper.cs rename to Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs index 0895a11..72b9be1 100644 --- a/Runtime/Scripts/IQonversionWrapper.cs +++ b/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs @@ -5,14 +5,13 @@ namespace QonversionUnity internal interface IQonversionWrapper { void Initialize(string gameObjectName); + void InitializeSdk(string projectKey, string launchMode, [CanBeNull] string environment, [CanBeNull] string entitlementsCacheLifetime); void StoreSdkInfo(string version, string source); - void SetDebugMode(); void SetAdvertisingID(); - void InitializeSdk(string projectKey, bool observerMode, string callbackName); void SetUserProperty(string key, string value); void SetProperty(UserProperty key, string value); void SyncPurchases(); - void AddAttributionData(string conversionData, AttributionProvider provider); + void AddAttributionData(string conversionData, string providerName); void CheckEntitlements(string callbackName); void Purchase(string productId, string callbackName); void PurchaseProduct(string productId, string offeringId, string callbackName); @@ -25,12 +24,8 @@ internal interface IQonversionWrapper void SetAppleSearchAdsAttributionEnabled(bool enable); void Identify(string userID); void Logout(); + void UserInfo(string callbackName); void PromoPurchase(string storeProductId, string callbackName); - void SetNotificationsToken(string token); - bool HandleNotification(string notification); - [CanBeNull] string GetNotificationCustomPayload(string notification); - void SubscribeOnAutomationEvents(); void PresentCodeRedemptionSheet(); - void SetPermissionsCacheLifetime(string lifetime); } } \ No newline at end of file diff --git a/Runtime/Scripts/IQonversionWrapper.cs.meta b/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs.meta similarity index 100% rename from Runtime/Scripts/IQonversionWrapper.cs.meta rename to Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs.meta diff --git a/Runtime/Scripts/QonversionWrapperNoop.cs b/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs similarity index 75% rename from Runtime/Scripts/QonversionWrapperNoop.cs rename to Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs index 004a56e..a9b3681 100644 --- a/Runtime/Scripts/QonversionWrapperNoop.cs +++ b/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs @@ -5,7 +5,8 @@ internal class QonversionWrapperNoop : IQonversionWrapper public void Initialize(string gameObjectName) { } - public void InitializeSdk(string projectKey, bool observerMode, string callbackName) + + public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime) { } @@ -21,7 +22,7 @@ public void SetProperty(UserProperty key, string value) { } - public void AddAttributionData(string conversionData, AttributionProvider provider) + public void AddAttributionData(string conversionData, string providerName) { } @@ -85,35 +86,16 @@ public void Logout() { } - public void PromoPurchase(string storeProductId, string callbackName) - { - } - - public void SetNotificationsToken(string token) + public void UserInfo(string callbackName) { } - public bool HandleNotification(string notification) - { - return false; - } - - public string GetNotificationCustomPayload(string notification) - { - return null; - } - - public void SubscribeOnAutomationEvents() - { + public void PromoPurchase(string storeProductId, string callbackName) + { } public void PresentCodeRedemptionSheet() { } - - public void SetPermissionsCacheLifetime(string lifetime) - { - - } } } \ No newline at end of file diff --git a/Runtime/Scripts/QonversionWrapperNoop.cs.meta b/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs.meta similarity index 100% rename from Runtime/Scripts/QonversionWrapperNoop.cs.meta rename to Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs.meta diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index 3efd440..bec6a1c 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -1,18 +1,54 @@ -using JetBrains.Annotations; -using QonversionUnity.MiniJSON; using System; using System.Collections.Generic; -using UnityEngine; +using JetBrains.Annotations; namespace QonversionUnity { - public class Qonversion : MonoBehaviour + // ReSharper disable once InconsistentNaming + public interface Qonversion { - public delegate void OnPurchaseResultReceived(Dictionary permissions, QonversionError error, bool isCancelled); - public delegate void OnPermissionsReceived(Dictionary permissions, QonversionError error); + [CanBeNull] private static Qonversion _backingInstance; + + /// + /// Use this variable to get a current initialized instance of the Qonversion SDK. + /// Please, use the property only after calling . + /// Otherwise, trying to access the variable will cause an exception. + /// + /// Current initialized instance of the Qonversion SDK. + /// throws exception if the instance has not been initialized + public static Qonversion GetSharedInstance() + { + if (_backingInstance == null) + { + throw new Exception( + "Qonversion has not been initialized. You should call " + + "the initialize method before accessing the shared instance of Qonversion." + ); + } + + return _backingInstance; + } + + /// + /// An entry point to use Qonversion SDK. Call to initialize Qonversion SDK with required and extra configs. + /// The function is the best way to set additional configs you need to use Qonversion SDK. + /// You still have an option to set a part of additional configs later via calling separated setters. + /// + /// a config that contains key SDK settings. + /// Call to configure and create a QonversionConfig instance. + /// Initialized instance of the Qonversion SDK. + public static Qonversion Initialize(QonversionConfig config) + { + _backingInstance = new QonversionInternal(config); + return _backingInstance; + } + + public delegate void OnPurchaseResultReceived(Dictionary entitlements, QonversionError error, bool isCancelled); + public delegate void OnEntitlementsReceived(Dictionary entitlements, QonversionError error); public delegate void OnProductsReceived(Dictionary products, QonversionError error); public delegate void OnOfferingsReceived(Offerings offerings, QonversionError error); public delegate void OnEligibilitiesReceived(Dictionary eligibilities, QonversionError error); + public delegate void OnUserInfoReceived(User userInfo, QonversionError error); /// /// Delegate fires each time a promo purchase from the App Store happens. @@ -30,384 +66,48 @@ public class Qonversion : MonoBehaviour /// Call the function if your app can handle a promo purchase at the current time. /// Or you can cache the delegate, and call it when the app is ready to make the purchase. /// - /// Callback that will be called when response is received. Returns permissions or potentially a QonversionError. - /// + /// Callback that will be called when response is received. Returns entitlements or potentially a QonversionError. + /// /// - public delegate void StartPromoPurchase(OnPermissionsReceived callback); + public delegate void StartPromoPurchase(OnEntitlementsReceived callback); /// /// Delegate fires each time a user entitlements change asynchronously, /// for example, when a deferred transaction happens. /// - public delegate void OnUpdatedEntitlementsReceived(Dictionary permissions); - - private const string GameObjectName = "QonvesrionRuntimeGameObject"; - private const string OnLaunchMethodName = "OnLaunch"; - private const string OnCheckPermissionsMethodName = "OnCheckPermissions"; - private const string OnPurchaseMethodName = "OnPurchase"; - private const string OnPromoPurchaseMethodName = "OnPromoPurchase"; - private const string OnPurchaseProductMethodName = "OnPurchaseProduct"; - private const string OnUpdatePurchaseMethodName = "OnUpdatePurchase"; - private const string OnUpdatePurchaseWithProductMethodName = "OnUpdatePurchaseWithProduct"; - private const string OnRestoreMethodName = "OnRestore"; - private const string OnProductsMethodName = "OnProducts"; - private const string OnOfferingsMethodName = "OnOfferings"; - private const string OnEligibilitiesMethodName = "OnEligibilities"; - - private const string SdkVersion = "3.7.1"; - private const string SdkSource = "unity"; - - private static IQonversionWrapper _Instance; - private static OnUpdatedEntitlementsReceived _onUpdatedEntitlementsReceived; - - private static OnPromoPurchasesReceived _onPromoPurchasesReceived; - private static string _storedPromoProductId = null; - private static AutomationsDelegate _automationsDelegate; - - private static List CheckPermissionsCallbacks { get; } = new List(); - private static List RestoreCallbacks { get; } = new List(); - private static OnPurchaseResultReceived PurchaseCallback { get; set; } - private static OnPurchaseResultReceived PurchaseProductCallback { get; set; } - private static OnPurchaseResultReceived UpdatePurchaseCallback { get; set; } - private static OnPurchaseResultReceived UpdatePurchaseWithProductCallback { get; set; } - private static List ProductsCallbacks { get; } = new List(); - private static List OfferingsCallbacks { get; } = new List(); - private static OnEligibilitiesReceived EligibilitiesCallback { get; set; } - private static OnPermissionsReceived PromoPurchaseCallback { get; set; } - - private static IQonversionWrapper getFinalInstance() - { - if (_Instance == null) - { - switch (Application.platform) - { - case RuntimePlatform.Android: - _Instance = new QonversionWrapperAndroid(); - break; - case RuntimePlatform.IPhonePlayer: - _Instance = new QonversionWrapperIOS(); - break; - default: - _Instance = new QonversionWrapperNoop(); - break; - } - _Instance.Initialize(GameObjectName); - - GameObject go = new GameObject(GameObjectName); - go.AddComponent(); - DontDestroyOnLoad(go); - } - - return _Instance; - } - - /// - /// This event will be fired when a user initiates a promotional in-app purchase from the App Store. - /// Declare a delegate for the event. - /// If you are not using the PromoPurchasesReceived event promo purchases will proceed automatically. - /// - public static event OnPromoPurchasesReceived PromoPurchasesReceived - { - add - { - _onPromoPurchasesReceived += value; - } - remove - { - _onPromoPurchasesReceived -= value; - } - } - - /// - /// This event will be fired for each asynchronous entitlements update, - /// for example, when a deferred transaction happens. - /// - public static event OnUpdatedEntitlementsReceived UpdatedEntitlementsReceived - { - add - { - _onUpdatedEntitlementsReceived += value; - } - remove - { - _onUpdatedEntitlementsReceived -= value; - } - } - - internal static void SetAutomationsDelegate(AutomationsDelegate automationsDelegate) - { - _automationsDelegate = automationsDelegate; - - IQonversionWrapper instance = getFinalInstance(); - instance.SubscribeOnAutomationEvents(); - } - - /// - /// Initializes Qonversion SDK with the given API key. - /// You can get one in your account on https://dash.qonversion.io. - /// - /// Project key to setup the SDK. - /// Set true if you are using observer mode only. - /// Observer mode - /// Installing the Android SDK - public static void Launch(string apiKey, bool observerMode) - { - IQonversionWrapper instance = getFinalInstance(); - instance.StoreSdkInfo(SdkVersion, SdkSource); - instance.InitializeSdk(apiKey, observerMode, OnLaunchMethodName); - } - - /// - /// You can set the flag to distinguish sandbox and production users. - /// To see the sandbox users turn on the Viewing test Data toggle on Qonversion Dashboard - /// - public static void SetDebugMode() - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetDebugMode(); - } - - /// - /// iOS only. - /// On iOS 14.5+, after requesting the app tracking permission using ATT, you need to notify Qonversion if tracking - /// is allowed and IDFA is available. - /// - public static void SetAdvertisingID() - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetAdvertisingID(); - } - - /// - /// Qonversion SDK provides an asynchronous method to set your side User ID that can be used to match users in - /// third-party integrations. - /// - /// Your database user ID. - /// User Identifiers - [Obsolete("Deprecated. Will be removed in a future major release. Use SetProperty(UserProperty.CustomUserId, value) instead.")] - public static void SetUserID(string userID) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetProperty(UserProperty.CustomUserId, userID); - } - - /// - /// Adds custom user property. - /// - /// User properties are attributes you can set on a user level. - /// You can send user properties to third party platforms as well as use them in Qonversion for customer segmentation - /// and analytics. - /// - /// Custom user property key. - /// Property value. - /// User Properties - public static void SetUserProperty(string key, string value) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetUserProperty(key, value); - } - - /// - /// Sets user property for pre-defined case property. - /// - /// User properties are attributes you can set on a user level. - /// You can send user properties to third party platforms as well as use them in Qonversion for customer segmentation - /// and analytics. - /// - /// Defined enum key that will be transformed to string. - /// Property value. - /// User Properties - public static void SetProperty(UserProperty key, string value) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetProperty(key, value); - } + public delegate void OnUpdatedEntitlementsReceived(Dictionary entitlements); /// - /// This method will send all purchases to the Qonversion backend. Call this every time when purchase is handled - /// by your own implementation. - /// - /// //////Warning!////// - /// - /// This method works for Android only. - /// It should only be called if you're using Qonversion SDK in observer mode. + /// This event will be fired when a user initiates a promotional in-app purchase from the App Store. + /// Declare a delegate for the event. + /// If you are not using the PromoPurchasesReceived event promo purchases will proceed automatically. /// - /// Observer mode for Android SDK - public static void SyncPurchases() - { - IQonversionWrapper instance = getFinalInstance(); - instance.SyncPurchases(); - } - - /// - /// iOS only. - /// On iOS 14.0+ shows up a sheet for users to redeem AppStore offer codes. - /// - public static void PresentCodeRedemptionSheet() - { - IQonversionWrapper instance = getFinalInstance(); - instance.PresentCodeRedemptionSheet(); - } - - /// - /// Sends your attribution data to the attribution source. - /// - /// An object containing your attribution data. - /// The attribution source to which the data will be sent. - public static void AddAttributionData(Dictionary conversionData, AttributionProvider attributionProvider) - { - AddAttributionData(conversionData.toJson(), attributionProvider); - } + public event OnPromoPurchasesReceived PromoPurchasesReceived; /// - /// Sends your attribution data to the attribution source. - /// - /// A json string containing your attribution data. - /// The attribution source to which the data will be sent. - public static void AddAttributionData(string conversionData, AttributionProvider attributionProvider) - { - IQonversionWrapper instance = getFinalInstance(); - - instance.AddAttributionData(conversionData, attributionProvider); - } - - /// - /// Enable collecting Apple Search Ads attribution data. "false" by default. - /// - /// A bool value indicating whether Qonversion should collect attribution from Apple Search Ads. - /// - public static void SetAppleSearchAdsAttributionEnabled(bool enable) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetAppleSearchAdsAttributionEnabled(enable); - } - - /// - /// Call this function to link a user to his unique ID in your system and share purchase data. - /// - /// An unique user ID in your system. - /// - public static void Identify(string userID) - { - IQonversionWrapper instance = getFinalInstance(); - instance.Identify(userID); - } - - /// - /// Call this function to unlink a user from his unique ID in your system and his purchase data. + /// This event will be fired for each asynchronous entitlements update, + /// for example, when a deferred transaction happens. /// - /// - public static void Logout() - { - IQonversionWrapper instance = getFinalInstance(); - instance.Logout(); - } + public event OnUpdatedEntitlementsReceived UpdatedEntitlementsReceived; /// - /// You need to call the CheckPermissions method at the start of your app to check if a user has the required - /// permission. - /// - /// This method will check the user receipt and will return the current permissions. - /// - /// If Apple or Google servers are not responding at the time of the request, Qonversion provides the latest - /// permissions data from its database. - /// - /// Callback that will be called when response is received - public static void CheckPermissions(OnPermissionsReceived callback) - { - CheckPermissionsCallbacks.Add(callback); - IQonversionWrapper instance = getFinalInstance(); - instance.CheckEntitlements(OnCheckPermissionsMethodName); - } - - /// - /// Make a purchase and validate that through server-to-server using Qonversion's Backend. + /// Make a purchase and validate it through server-to-server using Qonversion's Backend. /// /// Qonversion product identifier for purchase. /// Callback that will be called when response is received. /// - [Obsolete("Purchase with OnPermissionsReceived callback is deprecated. Consider using Purchase with OnPurchaseResultReceivedCallback instead.")] - public static void Purchase(string productId, OnPermissionsReceived callback) - { - var convertedCallback = ConvertPermissionsCallbackToPurchaseResultCallback(callback); - Purchase(productId, convertedCallback); - } - - /// - /// Make a purchase and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product identifier for purchase. - /// Callback that will be called when response is received. - /// - public static void Purchase(string productId, OnPurchaseResultReceived callback) - { - PurchaseCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.Purchase(productId, OnPurchaseMethodName); - } + public void Purchase(string productId, OnPurchaseResultReceived callback); /// - /// Make a purchase and validate that through server-to-server using Qonversion's Backend. + /// Make a purchase and validate it through server-to-server using Qonversion's Backend. /// /// Qonversion product for purchase. /// Callback that will be called when response is received. /// - [Obsolete("PurchaseProduct with OnPermissionsReceived callback is deprecated. Consider using PurchaseProduct with OnPurchaseResultReceivedCallback instead.")] - public static void PurchaseProduct([NotNull] Product product, OnPermissionsReceived callback) - { - var convertedCallback = ConvertPermissionsCallbackToPurchaseResultCallback(callback); - PurchaseProduct(product, convertedCallback); - } + public void PurchaseProduct([NotNull] Product product, OnPurchaseResultReceived callback); /// - /// Make a purchase and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product for purchase. - /// Callback that will be called when response is received. - /// - public static void PurchaseProduct([NotNull] Product product, OnPurchaseResultReceived callback) - { - if (product == null) - { - callback(null, new QonversionError("PurchaseInvalid", "Product is null"), false); - return; - } - - PurchaseProductCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.PurchaseProduct(product.QonversionId, product.OfferingId, OnPurchaseProductMethodName); - } - - /// - /// Restoring purchases restores users purchases in your app, to maintain access to purchased content. - /// Users sometimes need to restore purchased content, such as when they upgrade to a new phone. - /// - /// Callback that will be called when response is received - public static void Restore(OnPermissionsReceived callback) - { - RestoreCallbacks.Add(callback); - IQonversionWrapper instance = getFinalInstance(); - instance.Restore(OnRestoreMethodName); - } - - /// - /// Update (upgrade/downgrade) subscription and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product identifier for purchase - /// Qonversion product identifier from which the upgrade/downgrade will be initialized - /// Callback that will be called when response is received - /// Proration Mode - /// Proration Mode - /// Update Purchase - [Obsolete("UpdatePurchase with OnPermissionsReceived callback is deprecated. Consider using UpdatePurchase with OnPurchaseResultReceivedCallback instead.")] - public static void UpdatePurchase(string productId, string oldProductId, OnPermissionsReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) - { - var convertedCallback = ConvertPermissionsCallbackToPurchaseResultCallback(callback); - UpdatePurchase(productId, oldProductId, convertedCallback, prorationMode); - } - - /// - /// Update (upgrade/downgrade) subscription and validate that through server-to-server using Qonversion's Backend. + /// Update (upgrade/downgrade) subscription and validate it through server-to-server using Qonversion's Backend. /// /// Qonversion product identifier for purchase /// Qonversion product identifier from which the upgrade/downgrade will be initialized @@ -415,15 +115,15 @@ public static void UpdatePurchase(string productId, string oldProductId, OnPermi /// Proration Mode /// Proration Mode /// Update Purchase - public static void UpdatePurchase(string productId, string oldProductId, OnPurchaseResultReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) - { - UpdatePurchaseCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.UpdatePurchase(productId, oldProductId, prorationMode, OnUpdatePurchaseMethodName); - } + public void UpdatePurchase( + string productId, + string oldProductId, + OnPurchaseResultReceived callback, + ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy + ); /// - /// Update (upgrade/downgrade) subscription and validate that through server-to-server using Qonversion's Backend. + /// Update (upgrade/downgrade) subscription and validate it through server-to-server using Qonversion's Backend. /// /// Qonversion product for purchase /// Qonversion product identifier from which the upgrade/downgrade will be initialized @@ -431,46 +131,19 @@ public static void UpdatePurchase(string productId, string oldProductId, OnPurch /// Proration Mode /// Proration Mode /// Update Purchase - [Obsolete("UpdatePurchaseWithProduct with OnPermissionsReceived callback is deprecated. Consider using UpdatePurchaseWithProduct with OnPurchaseResultReceivedCallback instead.")] - public static void UpdatePurchaseWithProduct([NotNull] Product product, string oldProductId, OnPermissionsReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) - { - var convertedCallback = ConvertPermissionsCallbackToPurchaseResultCallback(callback); - UpdatePurchaseWithProduct(product, oldProductId, convertedCallback, prorationMode); - } - - /// - /// Update (upgrade/downgrade) subscription and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product for purchase - /// Qonversion product identifier from which the upgrade/downgrade will be initialized - /// Callback that will be called when response is received - /// Proration Mode - /// Proration Mode - /// Update Purchase - public static void UpdatePurchaseWithProduct([NotNull] Product product, string oldProductId, OnPurchaseResultReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) - { - if (product == null) - { - callback(null, new QonversionError("PurchaseInvalid", "Product is null"), false); - return; - } - - UpdatePurchaseWithProductCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.UpdatePurchaseWithProduct(product.QonversionId, product.OfferingId, oldProductId, prorationMode, OnUpdatePurchaseWithProductMethodName); - } + public void UpdatePurchaseWithProduct( + [NotNull] Product product, + string oldProductId, + OnPurchaseResultReceived callback, + ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy + ); /// /// Returns Qonversion products in association with Apple and Google Play Store Products. /// /// Callback that will be called when response is received. /// Product Center - public static void Products(OnProductsReceived callback) - { - ProductsCallbacks.Add(callback); - IQonversionWrapper instance = getFinalInstance(); - instance.Products(OnProductsMethodName); - } + public void Products(OnProductsReceived callback); /// /// Return Qonversion Offerings Object. @@ -482,12 +155,7 @@ public static void Products(OnProductsReceived callback) /// /// Offerings /// Product Center - public static void Offerings(OnOfferingsReceived callback) - { - OfferingsCallbacks.Add(callback); - IQonversionWrapper instance = getFinalInstance(); - instance.Offerings(OnOfferingsMethodName); - } + public void Offerings(OnOfferingsReceived callback); /// /// You can check if a user is eligible for an introductory offer, including a free trial. @@ -495,323 +163,117 @@ public static void Offerings(OnOfferingsReceived callback) /// /// Products identifiers that must be checked. /// Callback that will be called when response is received - public static void CheckTrialIntroEligibility(IList productIds, OnEligibilitiesReceived callback) - { - var productIdsJson = Json.Serialize(productIds); + public void CheckTrialIntroEligibility(IList productIds, OnEligibilitiesReceived callback); - EligibilitiesCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.CheckTrialIntroEligibility(productIdsJson, OnEligibilitiesMethodName); - } - /// - /// Permissions cache is used when there are problems with the Qonversion API - /// or internet connection. If so, Qonversion will return the last successfully loaded - /// permissions. The current method allows you to configure how long that cache may be used. - /// The default value is . + /// You need to call the CheckEntitlements method at the start of your app to check if a user has the required + /// entitlement. + /// + /// This method will check the user receipt and will return the current entitlements. + /// + /// If Apple or Google servers are not responding at the time of the request, Qonversion provides the latest + /// entitlements data from its database. /// - /// Desired permissions cache lifetime duration. - public static void SetPermissionsCacheLifetime(EntitlementsCacheLifetime lifetime) { - - var lifetimeKey = Enum.GetName(typeof(EntitlementsCacheLifetime), lifetime); - IQonversionWrapper instance = getFinalInstance(); - instance.SetPermissionsCacheLifetime(lifetimeKey); - } + /// Callback that will be called when response is received + public void CheckEntitlements(OnEntitlementsReceived callback); /// - /// Set push token to Qonversion to enable Qonversion push notifications + /// Restoring purchases restores users purchases in your app, to maintain access to purchased content. + /// Users sometimes need to restore purchased content, such as when they upgrade to a new phone. /// - /// Firebase device token on Android. APNs device token on iOS. - public static void SetNotificationsToken(string token) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetNotificationsToken(token); - } - - public static bool HandleNotification(Dictionary notification) - { - IQonversionWrapper instance = getFinalInstance(); - return instance.HandleNotification(notification.toJson()); - } - - [CanBeNull] - public static Dictionary GetNotificationCustomPayload(Dictionary notification) - { - IQonversionWrapper instance = getFinalInstance(); - var payloadJson = instance.GetNotificationCustomPayload(notification.toJson()); - - if (payloadJson == null) - { - return null; - } - - if (!(Json.Deserialize(payloadJson) is Dictionary response)) - { - Debug.LogError("Could not parse custom notification payload."); - return null; - } - - return response; - } - - // Called from the native SDK - Called when launch completed - private void OnLaunch(string jsonString) - { - Debug.Log("OnLaunch " + jsonString); - } - - // Called from the native SDK - Called when permissions received from the checkPermissions() method - private void OnCheckPermissions(string jsonString) - { - Debug.Log("OnCheckPermissions " + jsonString); - HandlePermissions(CheckPermissionsCallbacks, jsonString); - CheckPermissionsCallbacks.Clear(); - } - - // Called from the native SDK - Called when purchase result received from the purchase() method - private void OnPurchase(string jsonString) - { - Debug.Log("OnPurchase callback " + jsonString); - HandlePurchaseResult(PurchaseCallback, jsonString); - PurchaseCallback = null; - } - - // Called from the native SDK - Called when purchase result received from the purchaseProduct() method - private void OnPurchaseProduct(string jsonString) - { - Debug.Log("OnPurchaseProduct callback " + jsonString); - HandlePurchaseResult(PurchaseProductCallback, jsonString); - PurchaseProductCallback = null; - } - - // Called from the native SDK - Called when permissions received from the restore() method - private void OnRestore(string jsonString) - { - Debug.Log("OnRestore " + jsonString); - HandlePermissions(RestoreCallbacks, jsonString); - RestoreCallbacks.Clear(); - } - - // Called from the native SDK - Called when purchase result received from the updatePurchase() method - private void OnUpdatePurchase(string jsonString) - { - Debug.Log("OnUpdatePurchase " + jsonString); - HandlePurchaseResult(UpdatePurchaseCallback, jsonString); - UpdatePurchaseCallback = null; - } - - // Called from the native SDK - Called when purchase result received from the updatePurchaseWithProduct() method - private void OnUpdatePurchaseWithProduct(string jsonString) - { - Debug.Log("OnUpdatePurchaseWithProduct " + jsonString); - HandlePurchaseResult(UpdatePurchaseWithProductCallback, jsonString); - UpdatePurchaseWithProductCallback = null; - } - - // Called from the native SDK - Called when permissions received from the promoPurchase() method - private void OnPromoPurchase(string jsonString) - { - Debug.Log("OnPromoPurchase callback " + jsonString); - if (PromoPurchaseCallback != null) { - var callbacks = new List { PromoPurchaseCallback }; - HandlePermissions(callbacks, jsonString); - } - - PromoPurchaseCallback = null; - _storedPromoProductId = null; - } - - // Called from the native SDK - Called when products received from the products() method - private void OnProducts(string jsonString) - { - Debug.Log("OnProducts " + jsonString); - - if (ProductsCallbacks.Count == 0) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - ProductsCallbacks.ForEach(callback => callback(null, error)); - } - else - { - var products = Mapper.ProductsFromJson(jsonString); - ProductsCallbacks.ForEach(callback => callback(products, null)); - } - - ProductsCallbacks.Clear(); - } - - // Called from the native SDK - Called when offerings received from the offerings() method - private void OnOfferings(string jsonString) - { - Debug.Log("OnOfferings " + jsonString); - - if (OfferingsCallbacks.Count == 0) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - OfferingsCallbacks.ForEach(callback => callback(null, error)); - } - else - { - var offerings = Mapper.OfferingsFromJson(jsonString); - OfferingsCallbacks.ForEach(callback => callback(offerings, null)); - } - - OfferingsCallbacks.Clear(); - } - - // Called from the native SDK - Called when eligibilities received from the checkTrialIntroEligibilityForProductIds() method - private void OnEligibilities(string jsonString) - { - Debug.Log("OnEligibilities " + jsonString); - - if (EligibilitiesCallback == null) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - EligibilitiesCallback(null, error); - } - else - { - Dictionary eligibilities = Mapper.EligibilitiesFromJson(jsonString); - EligibilitiesCallback(eligibilities, null); - } - - EligibilitiesCallback = null; - } - - // Called from the native SDK - Called when deferred or pending purchase occured - private void OnReceivedUpdatedEntitlements(string jsonString) - { - Debug.Log("OnReceivedUpdatedEntitlements " + jsonString); - - if (_onUpdatedEntitlementsReceived == null) - { - return; - } - - Dictionary permissions = Mapper.PermissionsFromJson(jsonString); - _onUpdatedEntitlementsReceived(permissions); - } - - private void OnReceivePromoPurchase(string storeProductId) - { - Debug.Log("OnReceivePromoPurchase " + storeProductId); - - if (_onPromoPurchasesReceived == null) - { - return; - } - - _storedPromoProductId = storeProductId; - _onPromoPurchasesReceived(storeProductId, PromoPurchase); - } - - private void PromoPurchase(OnPermissionsReceived callback) - { - PromoPurchaseCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.PromoPurchase(_storedPromoProductId, OnPromoPurchaseMethodName); - } - - private void HandlePermissions(List callbacks, string jsonString) - { - if (callbacks.Count == 0) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - callbacks.ForEach(callback => callback(null, error)); - } - else - { - var permissions = Mapper.PermissionsFromJson(jsonString); - callbacks.ForEach(callback => callback(permissions, null)); - } - } - - private void HandlePurchaseResult(OnPurchaseResultReceived callback, string jsonString) - { - if (callback == null) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - var isCancelled = Mapper.GetIsCancelledFromJson(jsonString); - callback(null, error, isCancelled); - } - else - { - var permissions = Mapper.PermissionsFromJson(jsonString); - callback(permissions, null, false); - } - } - - private void OnAutomationsScreenShown(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } + /// Callback that will be called when response is received + public void Restore(OnEntitlementsReceived callback); - string screenId = Mapper.ScreenIdFromJson(jsonString); + /// + /// This method will send all purchases to the Qonversion backend. Call this every time when purchase is handled + /// by your own implementation. + /// + /// //////Warning!////// + /// + /// This method works for Android only. + /// It should only be called if you're using Qonversion SDK in observer mode. + /// + /// Observer mode for Android SDK + public void SyncPurchases(); - _automationsDelegate.OnAutomationsScreenShown(screenId); - } + /// + /// Call this function to link a user to his unique ID in your system and share purchase data. + /// + /// An unique user ID in your system. + /// + public void Identify(string userID); - private void OnAutomationsActionStarted(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } + /// + /// Call this function to unlink a user from his unique ID in your system and his purchase data. + /// + /// + public void Logout(); - ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); - _automationsDelegate.OnAutomationsActionStarted(actionResult); - } + /// + /// This method returns information about the current Qonversion user. + /// + /// Callback that will be called when response is received + public void UserInfo(OnUserInfoReceived callback); - private void OnAutomationsActionFailed(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } + /// + /// Sends your attribution data to the attribution source. + /// + /// An object containing your attribution data. + /// The attribution source to which the data will be sent. + public void Attribution( + Dictionary conversionData, + AttributionProvider attributionProvider + ); - ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); - _automationsDelegate.OnAutomationsActionFailed(actionResult); - } + /// + /// Sends your attribution data to the attribution source. + /// + /// A json string containing your attribution data. + /// The attribution source to which the data will be sent. + public void Attribution(string conversionData, AttributionProvider attributionProvider); - - private void OnAutomationsActionFinished(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } + /// + /// Sets user property for pre-defined case property. + /// + /// User properties are attributes you can set on a user level. + /// You can send user properties to third party platforms as well as use them in Qonversion for customer segmentation + /// and analytics. + /// + /// Defined enum key that will be transformed to string. + /// Property value. + /// User Properties + public void SetProperty(UserProperty key, string value); - ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); - _automationsDelegate.OnAutomationsActionFinished(actionResult); - } + /// + /// Adds custom user property. + /// + /// User properties are attributes you can set on a user level. + /// You can send user properties to third party platforms as well as use them in Qonversion for customer segmentation + /// and analytics. + /// + /// Custom user property key. + /// Property value. + /// User Properties + public void SetUserProperty(string key, string value); - private void OnAutomationsFinished(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } + /// + /// iOS only. + /// On iOS 14.5+, after requesting the app tracking entitlement using ATT, you need to notify Qonversion if tracking + /// is allowed and IDFA is available. + /// + public void SetAdvertisingID(); - _automationsDelegate.OnAutomationsFinished(); - } + /// + /// Enable collecting Apple Search Ads attribution data. "false" by default. + /// + /// A bool value indicating whether Qonversion should collect attribution from Apple Search Ads. + /// + public void SetAppleSearchAdsAttributionEnabled(bool enable); - private static OnPurchaseResultReceived ConvertPermissionsCallbackToPurchaseResultCallback(OnPermissionsReceived callback) - { - return delegate(Dictionary permissions, QonversionError error, bool isCancelled) { - callback(permissions, error); - }; - } + /// + /// iOS only. + /// On iOS 14.0+ shows up a sheet for users to redeem AppStore offer codes. + /// + public void PresentCodeRedemptionSheet(); } } diff --git a/Runtime/Scripts/Qonversion.cs.meta b/Runtime/Scripts/Qonversion.cs.meta index 3d73b36..cd102dc 100644 --- a/Runtime/Scripts/Qonversion.cs.meta +++ b/Runtime/Scripts/Qonversion.cs.meta @@ -1,11 +1,3 @@ fileFormatVersion: 2 -guid: 38c50778583feeb4da0934f2fa914b96 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +guid: 3d153a0da53e4ab38cd2815b94987e82 +timeCreated: 1668681655 \ No newline at end of file diff --git a/Runtime/Scripts/QonversionAndroidHandler.cs b/Runtime/Scripts/QonversionAndroidHandler.cs deleted file mode 100644 index 1ff099e..0000000 --- a/Runtime/Scripts/QonversionAndroidHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using UnityEngine; - -namespace QonversionUnity -{ - internal class QonversionAndroidHandler : AndroidJavaProxy, IQonversionResultHandler - { - private const string QONVERSION_WRAPPER_INTERFACE_PATH = "com.qonversion.unitywrapper.IQonversionResultHandler"; - - public InitDelegate InitComplete; - - public QonversionAndroidHandler(InitDelegate onInitComplete) : base(QONVERSION_WRAPPER_INTERFACE_PATH) - { - InitComplete = onInitComplete; - } - - public void onSuccessInit(string uid) - { - InitComplete?.Invoke(); - } - - public void onErrorInit(string errorMessage) - { - Debug.LogError(string.Format("[Qonversion] onErrorInit Error: {0}", errorMessage)); - } - } -} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionAndroidHandler.cs.meta b/Runtime/Scripts/QonversionAndroidHandler.cs.meta deleted file mode 100644 index 57140d9..0000000 --- a/Runtime/Scripts/QonversionAndroidHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5ce88f53397a401488b208d6a1c156d8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Scripts/QonversionConfig.cs b/Runtime/Scripts/QonversionConfig.cs new file mode 100644 index 0000000..341f97e --- /dev/null +++ b/Runtime/Scripts/QonversionConfig.cs @@ -0,0 +1,18 @@ +namespace QonversionUnity +{ + public class QonversionConfig + { + public readonly string ProjectKey; + public readonly LaunchMode LaunchMode; + public readonly Environment Environment; + public readonly EntitlementsCacheLifetime EntitlementsCacheLifetime; + + public QonversionConfig(string projectKey, LaunchMode launchMode, Environment environment, EntitlementsCacheLifetime entitlementsCacheLifetime) + { + ProjectKey = projectKey; + LaunchMode = launchMode; + Environment = environment; + EntitlementsCacheLifetime = entitlementsCacheLifetime; + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionConfig.cs.meta b/Runtime/Scripts/QonversionConfig.cs.meta new file mode 100644 index 0000000..d0b0f96 --- /dev/null +++ b/Runtime/Scripts/QonversionConfig.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 081671b389ce42258e66635391aa5c2f +timeCreated: 1668682590 \ No newline at end of file diff --git a/Runtime/Scripts/QonversionConfigBuilder.cs b/Runtime/Scripts/QonversionConfigBuilder.cs new file mode 100644 index 0000000..5130841 --- /dev/null +++ b/Runtime/Scripts/QonversionConfigBuilder.cs @@ -0,0 +1,55 @@ +namespace QonversionUnity +{ + public class QonversionConfigBuilder + { + public readonly string ProjectKey; + public readonly LaunchMode LaunchMode; + public Environment Environment; + public EntitlementsCacheLifetime EntitlementsCacheLifetime; + + public QonversionConfigBuilder(string projectKey, LaunchMode launchMode) + { + ProjectKey = projectKey; + LaunchMode = launchMode; + } + + /// + /// Set current application . Used to distinguish sandbox and production users. + /// + /// current environment. + /// builder instance for chain calls. + public QonversionConfigBuilder SetEnvironment(Environment environment) + { + Environment = environment; + return this; + } + + /// + /// Entitlements cache is used when there are problems with the Qonversion API + /// or internet connection. If so, Qonversion will return the last successfully loaded + /// entitlements. The current method allows you to configure how long that cache may be used. + /// The default value is . + /// + /// desired entitlements cache lifetime duration. + /// builder instance for chain calls. + public QonversionConfigBuilder SetEntitlementsCacheLifetime(EntitlementsCacheLifetime lifetime) + { + EntitlementsCacheLifetime = lifetime; + return this; + } + + /// + /// Generate instance with all the provided configurations. + /// + /// the complete instance. + public QonversionConfig Build() + { + return new QonversionConfig( + ProjectKey, + LaunchMode, + Environment, + EntitlementsCacheLifetime + ); + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionConfigBuilder.cs.meta b/Runtime/Scripts/QonversionConfigBuilder.cs.meta new file mode 100644 index 0000000..019c21b --- /dev/null +++ b/Runtime/Scripts/QonversionConfigBuilder.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e965105671494d86988de6e150a1a2a3 +timeCreated: 1668683063 \ No newline at end of file diff --git a/Runtime/Scripts/QonversionLauncher.cs b/Runtime/Scripts/QonversionLauncher.cs deleted file mode 100644 index 3956c64..0000000 --- a/Runtime/Scripts/QonversionLauncher.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace QonversionUnity -{ - public class QonversionLauncher : MonoBehaviour - { - [Tooltip("Your Qonversion Application Access Key. Get from https://dash.qonversion.io/")] - [SerializeField] - protected string m_ApplicationAccessKey; - - [Tooltip("Debug Mode: https://documentation.qonversion.io/docs/debug-mode")] - [SerializeField] - protected bool m_DebugMode; - - [Tooltip("Observer Mode: https://documentation.qonversion.io/docs/observer-mode")] - [SerializeField] - protected bool m_ObserverMode; - - private void Start() - { - if (m_DebugMode) - { - Qonversion.SetDebugMode(); - } - - Qonversion.Launch(m_ApplicationAccessKey, m_ObserverMode); - } - } -} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionLauncher.cs.meta b/Runtime/Scripts/QonversionLauncher.cs.meta deleted file mode 100644 index 1650602..0000000 --- a/Runtime/Scripts/QonversionLauncher.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2a8972452586ad74b907e03decfa6f7b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/iOS/AutomationsWrapperIOS.cs b/Runtime/iOS/AutomationsWrapperIOS.cs new file mode 100644 index 0000000..58621e0 --- /dev/null +++ b/Runtime/iOS/AutomationsWrapperIOS.cs @@ -0,0 +1,76 @@ +#if UNITY_IOS +using System.Runtime.InteropServices; +#endif + +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace QonversionUnity +{ + internal class AutomationsWrapperIOS : IAutomationsWrapper + { +#if UNITY_IOS + [DllImport("__Internal")] + private static extern void _initialize(string gameObjectName); + + [DllImport("__Internal")] + private static extern void _setNotificationsToken(string token); + + [DllImport("__Internal")] + private static extern bool _handleNotification(string notification); + + [DllImport("__Internal")] + private static extern string _getNotificationCustomPayload(string notification); + + [DllImport("__Internal")] + private static extern void _subscribeOnAutomationEvents(); +#endif + + public void Initialize(string gameObjectName) + { +#if UNITY_IOS + _initialize(gameObjectName); +#endif + } + + public void InitializeSdk() + { +#if UNITY_IOS + // todo +#endif + } + + public void SetNotificationsToken(string token) + { +#if UNITY_IOS + _setNotificationsToken(token); +#endif + } + + public bool HandleNotification(string notification) + { +#if UNITY_IOS + return _handleNotification(notification); +#else + return false; +#endif + } + + public string GetNotificationCustomPayload(string notification) + { +#if UNITY_IOS + return _getNotificationCustomPayload(notification); +#else + return null; +#endif + } + + public void SubscribeOnAutomationEvents() + { +#if UNITY_IOS + _subscribeOnAutomationEvents(); +#endif + } + } +} \ No newline at end of file diff --git a/Runtime/iOS/AutomationsWrapperIOS.cs.meta b/Runtime/iOS/AutomationsWrapperIOS.cs.meta new file mode 100644 index 0000000..4a3fc2f --- /dev/null +++ b/Runtime/iOS/AutomationsWrapperIOS.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 833a9b7bdb0a43228b1153c40421e900 +timeCreated: 1668776223 \ No newline at end of file diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index 2f3126a..b1be33d 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -50,6 +50,9 @@ internal class QonversionWrapperIOS : IQonversionWrapper [DllImport("__Internal")] private static extern void _restore(string callbackName); + [DllImport("__Internal")] + private static extern void _userInfo(string callbackName); + [DllImport("__Internal")] private static extern void _purchase(string productID, string callbackName); @@ -68,23 +71,8 @@ internal class QonversionWrapperIOS : IQonversionWrapper [DllImport("__Internal")] private static extern void _promoPurchase(string storeProductId, string callbackName); - [DllImport("__Internal")] - private static extern void _setNotificationsToken(string token); - - [DllImport("__Internal")] - private static extern bool _handleNotification(string notification); - - [DllImport("__Internal")] - private static extern string _getNotificationCustomPayload(string notification); - - [DllImport("__Internal")] - private static extern void _subscribeOnAutomationEvents(); - [DllImport("__Internal")] private static extern void _presentCodeRedemptionSheet(); - - [DllImport("__Internal")] - private static extern void _setPermissionsCacheLifetime(string lifetimeKey); #endif public void Initialize(string gameObjectName) @@ -101,10 +89,10 @@ public void StoreSdkInfo(string version, string source) #endif } - public void InitializeSdk(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime) { #if UNITY_IOS - _launchWithKey(projectKey, callbackName); + // todo #endif } @@ -141,11 +129,10 @@ public void SetProperty(UserProperty key, string value) #endif } - public void AddAttributionData(string conversionData, AttributionProvider provider) + public void AddAttributionData(string conversionData, string providerName) { #if UNITY_IOS - string sourceName = Enum.GetName(typeof(AttributionSource), source); - _addAttributionData(conversionData, sourceName); + _addAttributionData(conversionData, providerName); #endif } @@ -170,6 +157,13 @@ public void Logout() #endif } + public void UserInfo(string callbackName) + { +#if UNITY_IOS + _userInfo(callbackName); +#endif + } + public void PresentCodeRedemptionSheet() { #if UNITY_IOS @@ -238,45 +232,6 @@ public void PromoPurchase(string storeProductId, string callbackName) { #if UNITY_IOS _promoPurchase(storeProductId, callbackName); -#endif - } - - public void SetNotificationsToken(string token) - { -#if UNITY_IOS - _setNotificationsToken(token); -#endif - } - - public bool HandleNotification(string notification) - { -#if UNITY_IOS - return _handleNotification(notification); -#else - return false; -#endif - } - - public string GetNotificationCustomPayload(string notification) - { -#if UNITY_IOS - return _getNotificationCustomPayload(notification); -#else - return null; -#endif - } - - public void SubscribeOnAutomationEvents() - { -#if UNITY_IOS - _subscribeOnAutomationEvents(); -#endif - } - - public void SetPermissionsCacheLifetime(string lifetime) - { -#if UNITY_IOS - _setPermissionsCacheLifetime(lifetime); #endif } } From e7661f2cd57dac8fd013c6163e036bccd9121c66 Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Tue, 22 Nov 2022 11:14:02 +0600 Subject: [PATCH 06/22] Small fix --- Editor/QonversionDependencies.xml | 2 +- Runtime/Scripts/QonversionConfigBuilder.cs | 28 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml index 694dad8..50c4eaf 100644 --- a/Editor/QonversionDependencies.xml +++ b/Editor/QonversionDependencies.xml @@ -1,7 +1,7 @@ - + diff --git a/Runtime/Scripts/QonversionConfigBuilder.cs b/Runtime/Scripts/QonversionConfigBuilder.cs index 5130841..b73978e 100644 --- a/Runtime/Scripts/QonversionConfigBuilder.cs +++ b/Runtime/Scripts/QonversionConfigBuilder.cs @@ -2,25 +2,25 @@ namespace QonversionUnity { public class QonversionConfigBuilder { - public readonly string ProjectKey; - public readonly LaunchMode LaunchMode; - public Environment Environment; - public EntitlementsCacheLifetime EntitlementsCacheLifetime; + private readonly string _projectKey; + private readonly LaunchMode _launchMode; + private Environment _environment; + private EntitlementsCacheLifetime _entitlementsCacheLifetime; public QonversionConfigBuilder(string projectKey, LaunchMode launchMode) { - ProjectKey = projectKey; - LaunchMode = launchMode; + _projectKey = projectKey; + _launchMode = launchMode; } /// - /// Set current application . Used to distinguish sandbox and production users. + /// Set current application . Used to distinguish sandbox and production users. /// /// current environment. /// builder instance for chain calls. public QonversionConfigBuilder SetEnvironment(Environment environment) { - Environment = environment; + _environment = environment; return this; } @@ -28,13 +28,13 @@ public QonversionConfigBuilder SetEnvironment(Environment environment) /// Entitlements cache is used when there are problems with the Qonversion API /// or internet connection. If so, Qonversion will return the last successfully loaded /// entitlements. The current method allows you to configure how long that cache may be used. - /// The default value is . + /// The default value is . /// /// desired entitlements cache lifetime duration. /// builder instance for chain calls. public QonversionConfigBuilder SetEntitlementsCacheLifetime(EntitlementsCacheLifetime lifetime) { - EntitlementsCacheLifetime = lifetime; + _entitlementsCacheLifetime = lifetime; return this; } @@ -45,10 +45,10 @@ public QonversionConfigBuilder SetEntitlementsCacheLifetime(EntitlementsCacheLif public QonversionConfig Build() { return new QonversionConfig( - ProjectKey, - LaunchMode, - Environment, - EntitlementsCacheLifetime + _projectKey, + _launchMode, + _environment, + _entitlementsCacheLifetime ); } } From 839c9803f1263a48d7e759f4a9af8831eb44b9a5 Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Tue, 6 Dec 2022 13:32:20 +0300 Subject: [PATCH 07/22] Small fixes --- Runtime/Scripts/Automations.cs | 4 ++-- Runtime/Scripts/Internal/QonversionInternal.cs | 8 ++------ Runtime/Scripts/Qonversion.cs | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Runtime/Scripts/Automations.cs b/Runtime/Scripts/Automations.cs index faf02f5..bad8720 100644 --- a/Runtime/Scripts/Automations.cs +++ b/Runtime/Scripts/Automations.cs @@ -61,14 +61,14 @@ public static Automations Initialize() /// /// Set push token to Qonversion to enable Qonversion push notifications /// - /// Firebase device token on Android. APNs device token on iOS. + /// Firebase device token for Android. APNs device token for iOS. public abstract void SetNotificationsToken(string token); /// /// Call to handle push notifications sent by Qonversion Automations. /// /// notification payload data - /// true when a push notification was received from Qonversion. Otherwise, returns false, so you need to handle a notification yourself + /// true when a push notification was received from Qonversion. Otherwise, returns false, so you need to handle the notification yourself /// Firebase RemoteMessage data /// APNs notification data public abstract bool HandleNotification(Dictionary notification); diff --git a/Runtime/Scripts/Internal/QonversionInternal.cs b/Runtime/Scripts/Internal/QonversionInternal.cs index 14f5b14..a3ec653 100644 --- a/Runtime/Scripts/Internal/QonversionInternal.cs +++ b/Runtime/Scripts/Internal/QonversionInternal.cs @@ -72,12 +72,8 @@ public QonversionInternal(QonversionConfig config) instance.StoreSdkInfo(SdkVersion, SdkSource); string launchModeKey = Enum.GetName(typeof(LaunchMode), config.LaunchMode); - string environmentKey = config.Environment == null - ? Enum.GetName(typeof(Environment), config.Environment) - : null; - string cacheLifetimeKey = config.EntitlementsCacheLifetime == null - ? Enum.GetName(typeof(EntitlementsCacheLifetime), config.EntitlementsCacheLifetime) - : null; + string environmentKey = Enum.GetName(typeof(Environment), config.Environment); + string cacheLifetimeKey = Enum.GetName(typeof(EntitlementsCacheLifetime), config.EntitlementsCacheLifetime); instance.InitializeSdk(config.ProjectKey, launchModeKey, environmentKey, cacheLifetimeKey); } diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index bec6a1c..cd6f14b 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -32,7 +32,7 @@ public static Qonversion GetSharedInstance() /// /// An entry point to use Qonversion SDK. Call to initialize Qonversion SDK with required and extra configs. /// The function is the best way to set additional configs you need to use Qonversion SDK. - /// You still have an option to set a part of additional configs later via calling separated setters. + /// You still have an option to set a part of additional configs later via calling separate setters. /// /// a config that contains key SDK settings. /// Call to configure and create a QonversionConfig instance. From 0391ced46c17cc3119a683c6081751eafcec51c5 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 7 Dec 2022 18:50:38 +0400 Subject: [PATCH 08/22] Updated csharp part for noop and ios --- .../Scripts/Internal/QonversionInternal.cs | 4 +- .../qonversion/QonversionWrapperNoop.cs | 4 - Runtime/Scripts/Qonversion.cs | 7 +- Runtime/iOS/QonversionWrapperIOS.cs | 9 +- fastlane.meta | 8 ++ fastlane/README.md.meta | 7 ++ fastlane/fastfile.meta | 7 ++ fastlane/report.xml.meta | 7 ++ img/UnityQonversionLauncher.png.meta | 98 +++++++++++++++++++ 9 files changed, 133 insertions(+), 18 deletions(-) create mode 100644 fastlane.meta create mode 100644 fastlane/README.md.meta create mode 100644 fastlane/fastfile.meta create mode 100644 fastlane/report.xml.meta create mode 100644 img/UnityQonversionLauncher.png.meta diff --git a/Runtime/Scripts/Internal/QonversionInternal.cs b/Runtime/Scripts/Internal/QonversionInternal.cs index a3ec653..103729f 100644 --- a/Runtime/Scripts/Internal/QonversionInternal.cs +++ b/Runtime/Scripts/Internal/QonversionInternal.cs @@ -206,13 +206,13 @@ public void SetUserProperty(string key, string value) instance.SetUserProperty(key, value); } - public void SetAdvertisingID() + public void CollectAdvertisingID() { IQonversionWrapper instance = GetNativeWrapper(); instance.SetAdvertisingID(); } - public void SetAppleSearchAdsAttributionEnabled(bool enable) + public void CollectAppleSearchAdsAttribution() { IQonversionWrapper instance = GetNativeWrapper(); instance.SetAppleSearchAdsAttributionEnabled(enable); diff --git a/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs b/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs index a9b3681..e90d875 100644 --- a/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs +++ b/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs @@ -10,10 +10,6 @@ public void InitializeSdk(string projectKey, string launchMode, string environme { } - public void SetDebugMode() - { - } - public void SetUserProperty(string key, string value) { } diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index cd6f14b..34750ce 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -261,14 +261,13 @@ AttributionProvider attributionProvider /// On iOS 14.5+, after requesting the app tracking entitlement using ATT, you need to notify Qonversion if tracking /// is allowed and IDFA is available. /// - public void SetAdvertisingID(); + public void CollectAdvertisingID(); /// - /// Enable collecting Apple Search Ads attribution data. "false" by default. + /// Collecting Apple Search Ads attribution data. /// - /// A bool value indicating whether Qonversion should collect attribution from Apple Search Ads. /// - public void SetAppleSearchAdsAttributionEnabled(bool enable); + public void collectAppleSearchAdsAttribution(); /// /// iOS only. diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index b1be33d..ae0563d 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -100,13 +100,6 @@ public void SyncPurchases() { } - public void SetDebugMode() - { -#if UNITY_IOS - _setDebugMode(); -#endif - } - public void SetAdvertisingID() { #if UNITY_IOS @@ -129,7 +122,7 @@ public void SetProperty(UserProperty key, string value) #endif } - public void AddAttributionData(string conversionData, string providerName) + public void AttributionData(string conversionData, string providerName) { #if UNITY_IOS _addAttributionData(conversionData, providerName); diff --git a/fastlane.meta b/fastlane.meta new file mode 100644 index 0000000..c89bbe8 --- /dev/null +++ b/fastlane.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 089159a4944c04210aeeacfd063d3601 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/fastlane/README.md.meta b/fastlane/README.md.meta new file mode 100644 index 0000000..cce087c --- /dev/null +++ b/fastlane/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0f7d66a11e8894098917aa1f4ef1507a +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/fastlane/fastfile.meta b/fastlane/fastfile.meta new file mode 100644 index 0000000..a3d1619 --- /dev/null +++ b/fastlane/fastfile.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0490d362f09d34421838ef526cb8839d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/fastlane/report.xml.meta b/fastlane/report.xml.meta new file mode 100644 index 0000000..a220bb7 --- /dev/null +++ b/fastlane/report.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ce3590874b3444ee79db9c2164fd95be +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/img/UnityQonversionLauncher.png.meta b/img/UnityQonversionLauncher.png.meta new file mode 100644 index 0000000..e1575e5 --- /dev/null +++ b/img/UnityQonversionLauncher.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 721fa4cd076d647b7a88c24f5c0e1aec +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: From 0414837a1933a333ff085a4c9e4a3d9520a13e03 Mon Sep 17 00:00:00 2001 From: Surik Date: Wed, 7 Dec 2022 18:52:54 +0400 Subject: [PATCH 09/22] Fixed errors --- Runtime/Scripts/Internal/QonversionInternal.cs | 2 +- Runtime/Scripts/Qonversion.cs | 2 +- Runtime/iOS/QonversionWrapperIOS.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Runtime/Scripts/Internal/QonversionInternal.cs b/Runtime/Scripts/Internal/QonversionInternal.cs index 103729f..e3a51ba 100644 --- a/Runtime/Scripts/Internal/QonversionInternal.cs +++ b/Runtime/Scripts/Internal/QonversionInternal.cs @@ -215,7 +215,7 @@ public void CollectAdvertisingID() public void CollectAppleSearchAdsAttribution() { IQonversionWrapper instance = GetNativeWrapper(); - instance.SetAppleSearchAdsAttributionEnabled(enable); + instance.SetAppleSearchAdsAttributionEnabled(true); } public void PresentCodeRedemptionSheet() diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index 34750ce..a7cafe8 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -267,7 +267,7 @@ AttributionProvider attributionProvider /// Collecting Apple Search Ads attribution data. /// /// - public void collectAppleSearchAdsAttribution(); + public void CollectAppleSearchAdsAttribution(); /// /// iOS only. diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index ae0563d..9a2edda 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -122,7 +122,7 @@ public void SetProperty(UserProperty key, string value) #endif } - public void AttributionData(string conversionData, string providerName) + public void AddAttributionData(string conversionData, string providerName) { #if UNITY_IOS _addAttributionData(conversionData, providerName); From 55e48ae3ef2e513127e8cf37eaba8660d0287f16 Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Thu, 8 Dec 2022 12:11:18 +0300 Subject: [PATCH 10/22] Small fixes --- .../com/qonversion/unitywrapper/AutomationsWrapper.java | 4 ---- Runtime/Scripts/Internal/QonversionInternal.cs | 2 +- Runtime/Scripts/Qonversion.cs | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java index 8a4d8f2..33be6af 100644 --- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java @@ -34,10 +34,6 @@ public AutomationsWrapper(MessageSender messageSender) { automationsSandwich = new AutomationsSandwich(); } - public void initialize() { - automationsSandwich.initialize(); - } - public void subscribe() { automationsSandwich.setDelegate(this); } diff --git a/Runtime/Scripts/Internal/QonversionInternal.cs b/Runtime/Scripts/Internal/QonversionInternal.cs index e3a51ba..47432b1 100644 --- a/Runtime/Scripts/Internal/QonversionInternal.cs +++ b/Runtime/Scripts/Internal/QonversionInternal.cs @@ -369,7 +369,7 @@ private void OnUserInfo(string jsonString) UserInfoCallback = null; } - // Called from the native SDK - Called when deferred or pending purchase occured + // Called from the native SDK - Called when entitlements update. For example, when pending purchases like SCA, Ask to buy, etc., happen. private void OnReceivedUpdatedEntitlements(string jsonString) { Debug.Log("OnReceivedUpdatedEntitlements " + jsonString); diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index a7cafe8..00e14e8 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -73,7 +73,7 @@ public static Qonversion Initialize(QonversionConfig config) /// /// Delegate fires each time a user entitlements change asynchronously, - /// for example, when a deferred transaction happens. + /// for example, when pending purchases like SCA, Ask to buy, etc., happen. /// public delegate void OnUpdatedEntitlementsReceived(Dictionary entitlements); From dc4df05163355e20e6b7e6db9a5889fe80cf937e Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 8 Dec 2022 15:02:52 +0400 Subject: [PATCH 11/22] Added a part of logic --- Editor/QonversionDependencies.xml | 2 +- .../Plugins/Common/QNUAutomationsDelegate.h | 3 + .../Plugins/Common/QNUAutomationsDelegate.m | 12 ++++ Runtime/iOS/Plugins/QonversionBridge.m | 58 ++++++++----------- Runtime/iOS/QonversionWrapperIOS.cs | 7 ++- 5 files changed, 46 insertions(+), 36 deletions(-) diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml index 50c4eaf..28f038a 100644 --- a/Editor/QonversionDependencies.xml +++ b/Editor/QonversionDependencies.xml @@ -6,6 +6,6 @@ - + diff --git a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h index 3535d4c..47499e1 100644 --- a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h +++ b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h @@ -14,6 +14,9 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithListenerName:(char *)unityListenerName; - (void)subscribe; +- (void)setNotificationsToken:(NSString *)token; +- (BOOL)handleNotification:(NSDictionary *)notificationInfo; +- (NSDictionary *)getNotificationCustomPayload:(NSDictionary *)payload; @end diff --git a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m index 10e4f5f..c36cbcb 100644 --- a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m +++ b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m @@ -47,6 +47,18 @@ - (void)subscribe { [self.automationsSandwich subscribe:self]; } +- (void)setNotificationsToken:(NSString *)token { + [self.automationsSandwich setNotificationToken:token]; +} + +- (BOOL)handleNotification:(NSDictionary *)notificationInfo { + return [self.automationsSandwich handleNotification:notificationInfo]; +} + +- (NSDictionary *)getNotificationCustomPayload:(NSDictionary *)payload { + return [self.automationsSandwich getNotificationCustomPayload:payload]; +} + - (void)automationDidTriggerWithEvent:(NSString * _Nonnull)event payload:(NSDictionary * _Nullable)payload { NSString *methodName = self.automationEvents[event]; diff --git a/Runtime/iOS/Plugins/QonversionBridge.m b/Runtime/iOS/Plugins/QonversionBridge.m index 89237ae..2e3bfae 100644 --- a/Runtime/iOS/Plugins/QonversionBridge.m +++ b/Runtime/iOS/Plugins/QonversionBridge.m @@ -6,24 +6,24 @@ @interface QonversionEventListenerWrapper : NSObject -- (void)qonversionDidReceiveUpdatedPermissions:(NSDictionary * _Nonnull)permissions; +- (void)qonversionDidReceiveUpdatedEntitlements:(NSDictionary * _Nonnull)entitlements; - (void)shouldPurchasePromoProductWith:(NSString * _Nonnull)productId; @end @implementation QonversionEventListenerWrapper -- (void)qonversionDidReceiveUpdatedPermissions:(NSDictionary * _Nonnull)permissions { - [UtilityBridge sendUnityMessage:permissions toMethod:@"OnReceiveUpdatedPurchases" unityListener: unityListenerName]; -} - - (void)shouldPurchasePromoProductWith:(NSString * _Nonnull)productId { UnitySendMessage(unityListenerName, "OnReceivePromoPurchase", productId.UTF8String); } +- (void)qonversionDidReceiveUpdatedEntitlements:(NSDictionary * _Nonnull)entitlements { + [UtilityBridge sendUnityMessage:entitlements toMethod:@"OnReceivedUpdatedEntitlements" unityListener: unityListenerName]; +} + @end -static QNUAutomationsDelegate *automationsDelegate; +static QNUAutomationsDelegate *automationsBridge; static QonversionSandwich *qonversionSandwich; void _initialize(const char* unityListener) { @@ -32,9 +32,20 @@ void _initialize(const char* unityListener) { strcpy(unityListenerName, unityListener); qonversionSandwich = [[QonversionSandwich alloc] initWithQonversionEventListener:[QonversionEventListenerWrapper new]]; + automationsBridge = [[QNUAutomationsDelegate alloc] initWithListenerName:unityListenerName]; +} + +void _initializeSdk(const char* projectKey, const char* launchMode, const char* environment, const char* entitlementsCacheLifetime) { + NSString *keyStr = [UtilityBridge сonvertCStringToNSString:projectKey]; + NSString *launchModeStr = [UtilityBridge сonvertCStringToNSString:launchMode]; + NSString *envStr = [UtilityBridge сonvertCStringToNSString:environment]; + NSString *cacheLifetimeStr = [UtilityBridge сonvertCStringToNSString:entitlementsCacheLifetime]; + + [qonversionSandwich initializeWithProjectKey:keyStr launchModeKey:launchModeStr environmentKey:envStr entitlementsCacheLifetimeKey:cacheLifetimeStr]; automationsDelegate = [[QNUAutomationsDelegate alloc] initWithListenerName:unityListenerName]; } +//_initializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime); void _storeSdkInfo(const char* version, const char* source) { NSString *versionStr = [UtilityBridge сonvertCStringToNSString:version]; NSString *sourceStr = [UtilityBridge сonvertCStringToNSString:source]; @@ -42,22 +53,8 @@ void _storeSdkInfo(const char* version, const char* source) { [qonversionSandwich storeSdkInfoWithSource:sourceStr version:versionStr]; } -void _setDebugMode() { - [qonversionSandwich setDebugMode]; -} - -void _launchWithKey(const char* key, const char* unityCallbackName) { - NSString *callbackName = [UtilityBridge сonvertCStringToNSString:unityCallbackName]; - - NSString *projectKey = [UtilityBridge сonvertCStringToNSString:key]; - - [qonversionSandwich launchWithProjectKey:projectKey completion:^(NSDictionary * _Nullable result, SandwichError * _Nullable error) { - [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:unityListenerName]; - }]; -} - void _setAdvertisingID() { - [qonversionSandwich setAdvertisingId]; + [qonversionSandwich collectAdvertisingId]; } void _presentCodeRedemptionSheet() { @@ -67,7 +64,7 @@ void _presentCodeRedemptionSheet() { } void _setAppleSearchAdsAttributionEnabled(const bool enable) { - [qonversionSandwich setAppleSearchAdsAttributionEnabled:enable]; + [qonversionSandwich collectAppleSearchAdsAttribution]; } void _setProperty(const char* propertyName, const char* value) { @@ -88,7 +85,7 @@ void _addAttributionData(const char* conversionData, const char* provider) { NSDictionary *conversionInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: conversionData]]; NSString *providerStr = [UtilityBridge сonvertCStringToNSString:provider]; - [qonversionSandwich addAttributionDataWithSourceKey:providerStr value:conversionInfo]; + [qonversionSandwich attributionWithProviderKey:providerStr value:conversionInfo]; } void _identify(const char* userId) { @@ -103,7 +100,7 @@ void _logout() { void _checkPermissions(const char* unityCallbackName) { NSString *callbackName = [UtilityBridge сonvertCStringToNSString:unityCallbackName]; - [qonversionSandwich checkPermissions:^(NSDictionary * _Nullable result, SandwichError * _Nullable error) { + [qonversionSandwich checkEntitlements:^(NSDictionary * _Nullable result, SandwichError * _Nullable error) { [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:unityListenerName]; }]; } @@ -179,20 +176,15 @@ void _promoPurchase(const char* storeProductId, const char* unityCallbackName) { }]; } -void _setPermissionsCacheLifetime(const char* lifetimeName) { - NSString *lifetimeNameStr = [UtilityBridge сonvertCStringToNSString:lifetimeName]; - [qonversionSandwich setPermissionsCacheLifetime:lifetimeNameStr]; -} - void _setNotificationsToken(const char* token) { NSString *tokenStr = [UtilityBridge сonvertCStringToNSString:token]; - [qonversionSandwich setNotificationToken:tokenStr]; + [automationsBridge setNotificationsToken:tokenStr]; } bool _handleNotification(const char* notification) { NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]]; - BOOL isQonversionNotification = [qonversionSandwich handleNotification:notificationInfo]; + BOOL isQonversionNotification = [automationsBridge handleNotification:notificationInfo]; return isQonversionNotification; } @@ -200,7 +192,7 @@ bool _handleNotification(const char* notification) { const char* _getNotificationCustomPayload(const char* notification) { NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]]; - NSDictionary *payload = [qonversionSandwich getNotificationCustomPayload:notificationInfo]; + NSDictionary *payload = [automationsBridge getNotificationCustomPayload:notificationInfo]; if (payload == nil) { return nil; @@ -212,5 +204,5 @@ bool _handleNotification(const char* notification) { } void _subscribeOnAutomationEvents() { - [automationsDelegate subscribe]; + [automationsBridge subscribe]; } diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index 9a2edda..c2d97dc 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -14,6 +14,9 @@ internal class QonversionWrapperIOS : IQonversionWrapper [DllImport("__Internal")] private static extern void _initialize(string gameObjectName); + [DllImport("__Internal")] + private static extern void _initializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime); + [DllImport("__Internal")] private static extern void _storeSdkInfo(string version, string source); @@ -66,7 +69,7 @@ internal class QonversionWrapperIOS : IQonversionWrapper private static extern void _offerings(string callbackName); [DllImport("__Internal")] - private static extern void _checkTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName); + private static extern void _checkTrialIntroEligibility(string productIdsJson, string callbackName); [DllImport("__Internal")] private static extern void _promoPurchase(string storeProductId, string callbackName); @@ -92,7 +95,7 @@ public void StoreSdkInfo(string version, string source) public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime) { #if UNITY_IOS - // todo + _initializeSdk(projectKey, launchMode, environment, entitlementsCacheLifetime); #endif } From a3ca953d1ddc920f7f41f4cb6014892a50bc5b13 Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Thu, 8 Dec 2022 18:14:39 +0300 Subject: [PATCH 12/22] Initialization fixes. --- Runtime/Scripts/Automations.cs | 45 +++++++------------ Runtime/Scripts/Dto/Offering.cs | 5 ++- .../Scripts/Internal/AutomationsInternal.cs | 23 ++++++---- .../Scripts/Internal/QonversionInternal.cs | 19 +++++--- Runtime/Scripts/Qonversion.cs | 5 ++- 5 files changed, 48 insertions(+), 49 deletions(-) diff --git a/Runtime/Scripts/Automations.cs b/Runtime/Scripts/Automations.cs index bad8720..14d05c4 100644 --- a/Runtime/Scripts/Automations.cs +++ b/Runtime/Scripts/Automations.cs @@ -1,53 +1,38 @@ using System; using System.Collections.Generic; using JetBrains.Annotations; -using UnityEngine; namespace QonversionUnity { - public abstract class Automations : MonoBehaviour + // ReSharper disable once InconsistentNaming + public interface Automations { [CanBeNull] private static Automations _backingInstance; /// /// Use this variable to get a current initialized instance of the Qonversion Automations. - /// Please, use the property only after calling . - /// Otherwise, trying to access the variable will cause an exception. + /// Please, use Automations only after calling . + /// Otherwise, trying to access the variable will cause an error. /// /// Current initialized instance of the Qonversion Automations. - /// throws exception if the instance has not been initialized + /// throws exception if Qonversion has not been initialized. public static Automations GetSharedInstance() { if (_backingInstance == null) { - throw new Exception( - "Automations has not been initialized. You should call " + - "the initialize method before accessing the shared instance of Automations." - ); - } + try + { + Qonversion.GetSharedInstance(); + } + catch (Exception e) + { + throw new Exception("Qonversion has not been initialized. " + + "Automations should be used after Qonversion is initialized."); + } - return _backingInstance; - } - - /// - /// An entry point to use Qonversion Automations. Call to initialize Automations. - /// Make sure you have initialized first. - /// - /// Initialized instance of the Qonversion Automations. - /// throws exception if has not been initialized - public static Automations Initialize() - { - try - { - Qonversion.GetSharedInstance(); - } - catch (Exception e) - { - throw new Exception("Qonversion has not been initialized. " + - "Automations initialization should be called after Qonversion is initialized."); + _backingInstance = AutomationsInternal.CreateInstance(); } - _backingInstance = new AutomationsInternal(); return _backingInstance; } diff --git a/Runtime/Scripts/Dto/Offering.cs b/Runtime/Scripts/Dto/Offering.cs index 8b34b23..d6e5b0a 100644 --- a/Runtime/Scripts/Dto/Offering.cs +++ b/Runtime/Scripts/Dto/Offering.cs @@ -39,7 +39,8 @@ public override string ToString() public enum QOfferingTag { - None, - Main + Unknown = -1, + None = 0, + Main = 1 } } \ No newline at end of file diff --git a/Runtime/Scripts/Internal/AutomationsInternal.cs b/Runtime/Scripts/Internal/AutomationsInternal.cs index 7fd1867..7ffa069 100644 --- a/Runtime/Scripts/Internal/AutomationsInternal.cs +++ b/Runtime/Scripts/Internal/AutomationsInternal.cs @@ -4,13 +4,22 @@ namespace QonversionUnity { - internal class AutomationsInternal : Automations + internal class AutomationsInternal : MonoBehaviour, Automations { private const string GameObjectName = "QonvesrionAutomationsRuntimeGameObject"; private IAutomationsWrapper _nativeWrapperInstance; private AutomationsDelegate _automationsDelegate; - public override void SetDelegate(AutomationsDelegate automationsDelegate) + public static AutomationsInternal CreateInstance() + { + GameObject go = new GameObject(GameObjectName); + go.AddComponent(); + DontDestroyOnLoad(go); + + return go.GetComponent(); + } + + public void SetDelegate(AutomationsDelegate automationsDelegate) { _automationsDelegate = automationsDelegate; @@ -18,19 +27,19 @@ public override void SetDelegate(AutomationsDelegate automationsDelegate) instance.SubscribeOnAutomationEvents(); } - public override void SetNotificationsToken(string token) + public void SetNotificationsToken(string token) { IAutomationsWrapper instance = GetNativeWrapper(); instance.SetNotificationsToken(token); } - public override bool HandleNotification(Dictionary notification) + public bool HandleNotification(Dictionary notification) { IAutomationsWrapper instance = GetNativeWrapper(); return instance.HandleNotification(notification.toJson()); } - public override Dictionary GetNotificationCustomPayload(Dictionary notification) + public Dictionary GetNotificationCustomPayload(Dictionary notification) { IAutomationsWrapper instance = GetNativeWrapper(); var payloadJson = instance.GetNotificationCustomPayload(notification.toJson()); @@ -69,10 +78,6 @@ private IAutomationsWrapper GetNativeWrapper() break; } _nativeWrapperInstance.Initialize(GameObjectName); - - GameObject go = new GameObject(GameObjectName); - go.AddComponent(); - DontDestroyOnLoad(go); return _nativeWrapperInstance; } diff --git a/Runtime/Scripts/Internal/QonversionInternal.cs b/Runtime/Scripts/Internal/QonversionInternal.cs index 47432b1..d142e38 100644 --- a/Runtime/Scripts/Internal/QonversionInternal.cs +++ b/Runtime/Scripts/Internal/QonversionInternal.cs @@ -45,11 +45,11 @@ internal class QonversionInternal : MonoBehaviour, Qonversion public event Qonversion.OnPromoPurchasesReceived PromoPurchasesReceived { add - { + { _onPromoPurchasesReceived += value; } remove - { + { _onPromoPurchasesReceived -= value; } } @@ -66,7 +66,16 @@ public event Qonversion.OnUpdatedEntitlementsReceived UpdatedEntitlementsReceive } } - public QonversionInternal(QonversionConfig config) + public static QonversionInternal CreateInstance() + { + GameObject go = new GameObject(GameObjectName); + go.AddComponent(); + DontDestroyOnLoad(go); + + return go.GetComponent(); + } + + void Qonversion.InitializeInstance(QonversionConfig config) { IQonversionWrapper instance = GetNativeWrapper(); instance.StoreSdkInfo(SdkVersion, SdkSource); @@ -456,10 +465,6 @@ private IQonversionWrapper GetNativeWrapper() break; } _nativeWrapperInstance.Initialize(GameObjectName); - - GameObject go = new GameObject(GameObjectName); - go.AddComponent(); - DontDestroyOnLoad(go); return _nativeWrapperInstance; } diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index 00e14e8..7f9bce2 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -39,7 +39,8 @@ public static Qonversion GetSharedInstance() /// Initialized instance of the Qonversion SDK. public static Qonversion Initialize(QonversionConfig config) { - _backingInstance = new QonversionInternal(config); + _backingInstance = QonversionInternal.CreateInstance(); + _backingInstance?.InitializeInstance(config); return _backingInstance; } @@ -274,5 +275,7 @@ AttributionProvider attributionProvider /// On iOS 14.0+ shows up a sheet for users to redeem AppStore offer codes. /// public void PresentCodeRedemptionSheet(); + + internal void InitializeInstance(QonversionConfig config); } } From 7d918470032a0b703b885ffb742bb4fb04f58804 Mon Sep 17 00:00:00 2001 From: Surik Date: Thu, 8 Dec 2022 20:10:44 +0400 Subject: [PATCH 13/22] Added missing functions + removed useless functions --- Runtime/iOS/Plugins/QonversionBridge.m | 11 +++++++++-- Runtime/iOS/QonversionWrapperIOS.cs | 6 ------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Runtime/iOS/Plugins/QonversionBridge.m b/Runtime/iOS/Plugins/QonversionBridge.m index 2e3bfae..7e69c43 100644 --- a/Runtime/iOS/Plugins/QonversionBridge.m +++ b/Runtime/iOS/Plugins/QonversionBridge.m @@ -42,7 +42,6 @@ void _initializeSdk(const char* projectKey, const char* launchMode, const char* NSString *cacheLifetimeStr = [UtilityBridge сonvertCStringToNSString:entitlementsCacheLifetime]; [qonversionSandwich initializeWithProjectKey:keyStr launchModeKey:launchModeStr environmentKey:envStr entitlementsCacheLifetimeKey:cacheLifetimeStr]; - automationsDelegate = [[QNUAutomationsDelegate alloc] initWithListenerName:unityListenerName]; } //_initializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime); @@ -93,6 +92,14 @@ void _identify(const char* userId) { [qonversionSandwich identify:userIdStr]; } +void _userInfo(const char* unityCallbackName) { + NSString *callbackName = [UtilityBridge сonvertCStringToNSString:unityCallbackName]; + + [qonversionSandwich userInfo:^(NSDictionary * _Nullable result, SandwichError * _Nullable error) { + [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:unityListenerName]; + }]; +} + void _logout() { [qonversionSandwich logout]; } @@ -148,7 +155,7 @@ void _offerings(const char* unityCallbackName) { }]; } -void _checkTrialIntroEligibilityForProductIds(const char* productIdsJson, const char* unityCallbackName) { +void _checkTrialIntroEligibility(const char* productIdsJson, const char* unityCallbackName) { NSString *callbackName = [UtilityBridge сonvertCStringToNSString:unityCallbackName]; NSString *productIdsJsonStr = [UtilityBridge сonvertCStringToNSString:productIdsJson]; diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index c2d97dc..2624c89 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -20,9 +20,6 @@ internal class QonversionWrapperIOS : IQonversionWrapper [DllImport("__Internal")] private static extern void _storeSdkInfo(string version, string source); - [DllImport("__Internal")] - private static extern void _setDebugMode(); - [DllImport("__Internal")] private static extern void _setAdvertisingID(); @@ -41,9 +38,6 @@ internal class QonversionWrapperIOS : IQonversionWrapper [DllImport("__Internal")] private static extern void _setUserProperty(string key, string value); - [DllImport("__Internal")] - private static extern void _launchWithKey(string key, string callbackName); - [DllImport("__Internal")] private static extern void _addAttributionData(string conversionData, string providerName); From 4ef738c9386573be6f7c583abd5fb301bc10e4b0 Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Mon, 12 Dec 2022 11:55:01 +0300 Subject: [PATCH 14/22] Native Android part of new major release. (#124) * Android native part updates supported. * User info method added. --- Editor/QonversionDependencies.xml | 4 +- .../unitywrapper/AutomationsWrapper.java | 50 ++++++++++++- .../unitywrapper/QonversionWrapper.java | 73 +++++++------------ Runtime/Android/QonversionWrapperAndroid.cs | 12 +-- Runtime/Scripts/IQonversionWrapper.cs | 6 +- Runtime/Scripts/Qonversion.cs | 34 +++++---- Runtime/Scripts/QonversionWrapperNoop.cs | 6 +- Runtime/iOS/QonversionWrapperIOS.cs | 8 +- package.json | 3 +- 9 files changed, 113 insertions(+), 83 deletions(-) diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml index 1f6fd83..694dad8 100644 --- a/Editor/QonversionDependencies.xml +++ b/Editor/QonversionDependencies.xml @@ -1,11 +1,11 @@ - + - + diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java index 3214d1c..8a4d8f2 100644 --- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java @@ -6,6 +6,8 @@ import androidx.annotation.Nullable; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; @@ -15,6 +17,7 @@ import io.qonversion.sandwich.AutomationsEventListener; import io.qonversion.sandwich.AutomationsSandwich; +@SuppressWarnings("UnnecessaryLocalVariable") public class AutomationsWrapper implements AutomationsEventListener { private static final String EVENT_SCREEN_SHOWN = "OnAutomationsScreenShown"; private static final String EVENT_ACTION_STARTED = "OnAutomationsActionStarted"; @@ -31,13 +34,56 @@ public AutomationsWrapper(MessageSender messageSender) { automationsSandwich = new AutomationsSandwich(); } + public void initialize() { + automationsSandwich.initialize(); + } + public void subscribe() { - automationsSandwich.subscribe(this); + automationsSandwich.setDelegate(this); + } + + public void setNotificationsToken(String token) { + automationsSandwich.setNotificationToken(token); + } + + public boolean handleNotification(String notification) { + try { + ObjectMapper mapper = new ObjectMapper(); + + TypeReference> typeRef + = new TypeReference>() { + }; + Map notificationInfo = mapper.readValue(notification, typeRef); + + boolean result = automationsSandwich.handleNotification(notificationInfo); + + return result; + } catch (Exception e) { + return false; + } + } + + @Nullable + public Map getNotificationCustomPayload(String notification) { + try { + ObjectMapper mapper = new ObjectMapper(); + + TypeReference> typeRef + = new TypeReference>() { + }; + Map notificationInfo = mapper.readValue(notification, typeRef); + + Map payload = automationsSandwich.getNotificationCustomPayload(notificationInfo); + + return payload; + } catch (Exception e) { + return null; + } } @Override public void onAutomationEvent(@NonNull Event event, @Nullable Map data) { - String methodName = ""; + String methodName; switch (event) { case ScreenShown: methodName = EVENT_SCREEN_SHOWN; diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java index c545fa2..f0593fe 100644 --- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java @@ -27,7 +27,7 @@ public class QonversionWrapper { public static String TAG = "QonversionWrapper"; - public static String ON_UPDATED_PURCHASES_LISTENER = "OnReceiveUpdatedPurchases"; + public static String ENTITLEMENTS_UPDATE_LISTENER = "OnReceivedUpdatedEntitlements"; private static MessageSender messageSender; private static AutomationsWrapper automationsWrapper; @@ -40,7 +40,7 @@ public static synchronized void initialize(String unityListener) { qonversionSandwich = new QonversionSandwich( application, () -> UnityPlayer.currentActivity, - permissions -> sendMessageToUnity(permissions, ON_UPDATED_PURCHASES_LISTENER) + entitlements -> sendMessageToUnity(entitlements, ENTITLEMENTS_UPDATE_LISTENER) ); automationsWrapper = new AutomationsWrapper(messageSender); } @@ -49,18 +49,25 @@ public static synchronized void storeSdkInfo(String version, String source) { qonversionSandwich.storeSdkInfo(source, version); } - public static synchronized void launch(String projectKey, boolean observerMode, String unityCallbackName) { - qonversionSandwich.launch(projectKey, observerMode, getResultListener(unityCallbackName)); + public static synchronized void initializeSdk( + String projectKey, + String launchModeKey, + @Nullable String environmentKey, + @Nullable String entitlementsCacheLifetimeKey + ) { + qonversionSandwich.initialize( + UnityPlayer.currentActivity, + projectKey, + launchModeKey, + environmentKey, + entitlementsCacheLifetimeKey + ); } public static synchronized void syncPurchases() { qonversionSandwich.syncPurchases(); } - public static synchronized void setDebugMode() { - qonversionSandwich.setDebugMode(); - } - public static synchronized void setProperty(String key, String value) { qonversionSandwich.setDefinedProperty(key, value); } @@ -69,7 +76,7 @@ public static synchronized void setUserProperty(String key, String value) { qonversionSandwich.setCustomProperty(key, value); } - public static synchronized void attribution(String conversionData, String attributionSource) { + public static synchronized void attribution(String conversionData, String attributionProvider) { try { ObjectMapper mapper = new ObjectMapper(); @@ -77,7 +84,7 @@ public static synchronized void attribution(String conversionData, String attrib = new TypeReference>() {}; Map conversionInfo = mapper.readValue(conversionData, typeRef); - qonversionSandwich.addAttributionData(attributionSource, conversionInfo); + qonversionSandwich.addAttributionData(attributionProvider, conversionInfo); } catch (JsonProcessingException e) { handleSerializationException(e); } @@ -91,8 +98,12 @@ public static synchronized void logout() { qonversionSandwich.logout(); } - public static synchronized void checkPermissions(String unityCallbackName) { - qonversionSandwich.checkPermissions(getResultListener(unityCallbackName)); + public static synchronized void userInfo(String unityCallbackName) { + qonversionSandwich.userInfo(getResultListener(unityCallbackName)); + } + + public static synchronized void checkEntitlements(String unityCallbackName) { + qonversionSandwich.checkEntitlements(getResultListener(unityCallbackName)); } public static synchronized void purchase(String productId, String unityCallbackName) { @@ -123,7 +134,7 @@ public static synchronized void offerings(String unityCallbackName) { qonversionSandwich.offerings(getResultListener(unityCallbackName)); } - public static synchronized void checkTrialIntroEligibilityForProductIds(String productIds, String unityCallbackName) { + public static synchronized void checkTrialIntroEligibility(String productIds, String unityCallbackName) { try { ObjectMapper mapper = new ObjectMapper(); TypeReference> typeRef = new TypeReference>() {}; @@ -135,47 +146,17 @@ public static synchronized void checkTrialIntroEligibilityForProductIds(String p } } - public static synchronized void setPermissionsCacheLifetime(String lifetimeKey) { - qonversionSandwich.setPermissionsCacheLifetime(lifetimeKey); - } - public static synchronized void setNotificationsToken(String token) { - qonversionSandwich.setNotificationToken(token); + automationsWrapper.setNotificationsToken(token); } public static synchronized boolean handleNotification(String notification) { - try { - ObjectMapper mapper = new ObjectMapper(); - - TypeReference> typeRef - = new TypeReference>() { - }; - Map notificationInfo = mapper.readValue(notification, typeRef); - - boolean result = qonversionSandwich.handleNotification(notificationInfo); - - return result; - } catch (Exception e) { - return false; - } + return automationsWrapper.handleNotification(notification); } @Nullable public static synchronized Map getNotificationCustomPayload(String notification) { - try { - ObjectMapper mapper = new ObjectMapper(); - - TypeReference> typeRef - = new TypeReference>() { - }; - Map notificationInfo = mapper.readValue(notification, typeRef); - - Map payload = qonversionSandwich.getNotificationCustomPayload(notificationInfo); - - return payload; - } catch (Exception e) { - return null; - } + return automationsWrapper.getNotificationCustomPayload(notification); } public static synchronized void subscribeOnAutomationEvents() { diff --git a/Runtime/Android/QonversionWrapperAndroid.cs b/Runtime/Android/QonversionWrapperAndroid.cs index 3f29fe5..2829f0f 100644 --- a/Runtime/Android/QonversionWrapperAndroid.cs +++ b/Runtime/Android/QonversionWrapperAndroid.cs @@ -17,9 +17,9 @@ public void StoreSdkInfo(string version, string source) CallQonversion("storeSdkInfo", version, source); } - public void Launch(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, bool observerMode, string callbackName) { - CallQonversion("launch", projectKey, observerMode, callbackName); + CallQonversion("initializeSdk", projectKey, observerMode, callbackName); } public void SetDebugMode() @@ -101,9 +101,9 @@ public void Logout() CallQonversion("logout"); } - public void CheckPermissions(string callbackName) + public void CheckEntitlements(string callbackName) { - CallQonversion("checkPermissions", callbackName); + CallQonversion("checkEntitlements", callbackName); } public void Purchase(string productId, string callbackName) @@ -141,9 +141,9 @@ public void Offerings(string callbackName) CallQonversion("offerings", callbackName); } - public void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName) + public void CheckTrialIntroEligibility(string productIdsJson, string callbackName) { - CallQonversion("checkTrialIntroEligibilityForProductIds", productIdsJson, callbackName); + CallQonversion("checkTrialIntroEligibility", productIdsJson, callbackName); } public void SetNotificationsToken(string token) diff --git a/Runtime/Scripts/IQonversionWrapper.cs b/Runtime/Scripts/IQonversionWrapper.cs index 6fce157..4c31e5f 100644 --- a/Runtime/Scripts/IQonversionWrapper.cs +++ b/Runtime/Scripts/IQonversionWrapper.cs @@ -8,12 +8,12 @@ internal interface IQonversionWrapper void StoreSdkInfo(string version, string source); void SetDebugMode(); void SetAdvertisingID(); - void Launch(string projectKey, bool observerMode, string callbackName); + void InitializeSdk(string projectKey, bool observerMode, string callbackName); void SetUserProperty(string key, string value); void SetProperty(UserProperty key, string value); void SyncPurchases(); void AddAttributionData(string conversionData, AttributionSource source); - void CheckPermissions(string callbackName); + void CheckEntitlements(string callbackName); void Purchase(string productId, string callbackName); void PurchaseProduct(string productId, string offeringId, string callbackName); void Restore(string callbackName); @@ -21,7 +21,7 @@ internal interface IQonversionWrapper void UpdatePurchaseWithProduct(string productId, string offeringId, string oldProductId, ProrationMode prorationMode, string callbackName); void Products(string callbackName); void Offerings(string callbackName); - void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName); + void CheckTrialIntroEligibility(string productIdsJson, string callbackName); void SetAppleSearchAdsAttributionEnabled(bool enable); void Identify(string userID); void Logout(); diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index 712af99..9814d0f 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -36,9 +36,10 @@ public class Qonversion : MonoBehaviour public delegate void StartPromoPurchase(OnPermissionsReceived callback); /// - /// Delegate fires each time a deferred transaction happens + /// Delegate fires each time a user entitlements change asynchronously, + /// for example, when a deferred transaction happens. /// - public delegate void OnUpdatedPurchasesReceived(Dictionary permissions); + public delegate void OnUpdatedEntitlementsReceived(Dictionary permissions); private const string GameObjectName = "QonvesrionRuntimeGameObject"; private const string OnLaunchMethodName = "OnLaunch"; @@ -57,7 +58,7 @@ public class Qonversion : MonoBehaviour private const string SdkSource = "unity"; private static IQonversionWrapper _Instance; - private static OnUpdatedPurchasesReceived _onUpdatedPurchasesReceived; + private static OnUpdatedEntitlementsReceived _onUpdatedEntitlementsReceived; private static OnPromoPurchasesReceived _onPromoPurchasesReceived; private static string _storedPromoProductId = null; @@ -118,17 +119,18 @@ public static event OnPromoPurchasesReceived PromoPurchasesReceived } /// - /// This event will be fired each time a deferred transaction happens. + /// This event will be fired for each asynchronous entitlements update, + /// for example, when a deferred transaction happens. /// - public static event OnUpdatedPurchasesReceived UpdatedPurchasesReceived + public static event OnUpdatedEntitlementsReceived UpdatedEntitlementsReceived { add { - _onUpdatedPurchasesReceived += value; + _onUpdatedEntitlementsReceived += value; } remove { - _onUpdatedPurchasesReceived -= value; + _onUpdatedEntitlementsReceived -= value; } } @@ -152,7 +154,7 @@ public static void Launch(string apiKey, bool observerMode) { IQonversionWrapper instance = getFinalInstance(); instance.StoreSdkInfo(SdkVersion, SdkSource); - instance.Launch(apiKey, observerMode, OnLaunchMethodName); + instance.InitializeSdk(apiKey, observerMode, OnLaunchMethodName); } /// @@ -315,7 +317,7 @@ public static void CheckPermissions(OnPermissionsReceived callback) { CheckPermissionsCallbacks.Add(callback); IQonversionWrapper instance = getFinalInstance(); - instance.CheckPermissions(OnCheckPermissionsMethodName); + instance.CheckEntitlements(OnCheckPermissionsMethodName); } /// @@ -493,20 +495,20 @@ public static void Offerings(OnOfferingsReceived callback) /// /// Products identifiers that must be checked. /// Callback that will be called when response is received - public static void CheckTrialIntroEligibilityForProductIds(IList productIds, OnEligibilitiesReceived callback) + public static void CheckTrialIntroEligibility(IList productIds, OnEligibilitiesReceived callback) { var productIdsJson = Json.Serialize(productIds); EligibilitiesCallback = callback; IQonversionWrapper instance = getFinalInstance(); - instance.CheckTrialIntroEligibilityForProductIds(productIdsJson, OnEligibilitiesMethodName); + instance.CheckTrialIntroEligibility(productIdsJson, OnEligibilitiesMethodName); } /// /// Permissions cache is used when there are problems with the Qonversion API /// or internet connection. If so, Qonversion will return the last successfully loaded /// permissions. The current method allows you to configure how long that cache may be used. - /// The default value is . /// /// Desired permissions cache lifetime duration. public static void SetPermissionsCacheLifetime(PermissionsCacheLifetime lifetime) { @@ -682,17 +684,17 @@ private void OnEligibilities(string jsonString) } // Called from the native SDK - Called when deferred or pending purchase occured - private void OnReceiveUpdatedPurchases(string jsonString) + private void OnReceivedUpdatedEntitlements(string jsonString) { - Debug.Log("OnReceiveUpdatedPurchases " + jsonString); + Debug.Log("OnReceivedUpdatedEntitlements " + jsonString); - if (_onUpdatedPurchasesReceived == null) + if (_onUpdatedEntitlementsReceived == null) { return; } Dictionary permissions = Mapper.PermissionsFromJson(jsonString); - _onUpdatedPurchasesReceived(permissions); + _onUpdatedEntitlementsReceived(permissions); } private void OnReceivePromoPurchase(string storeProductId) diff --git a/Runtime/Scripts/QonversionWrapperNoop.cs b/Runtime/Scripts/QonversionWrapperNoop.cs index 58cb925..f0b2cb2 100644 --- a/Runtime/Scripts/QonversionWrapperNoop.cs +++ b/Runtime/Scripts/QonversionWrapperNoop.cs @@ -5,7 +5,7 @@ internal class QonversionWrapperNoop : IQonversionWrapper public void Initialize(string gameObjectName) { } - public void Launch(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, bool observerMode, string callbackName) { } @@ -33,7 +33,7 @@ public void SetAdvertisingID() { } - public void CheckPermissions(string callbackName) + public void CheckEntitlements(string callbackName) { } @@ -69,7 +69,7 @@ public void StoreSdkInfo(string version, string source) { } - public void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName) + public void CheckTrialIntroEligibility(string productIdsJson, string callbackName) { } diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index c4ec360..bec6e48 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -101,7 +101,7 @@ public void StoreSdkInfo(string version, string source) #endif } - public void Launch(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, bool observerMode, string callbackName) { #if UNITY_IOS _launchWithKey(projectKey, callbackName); @@ -177,7 +177,7 @@ public void PresentCodeRedemptionSheet() #endif } - public void CheckPermissions(string callbackName) + public void CheckEntitlements(string callbackName) { #if UNITY_IOS _checkPermissions(callbackName); @@ -227,10 +227,10 @@ public void Offerings(string callbackName) #endif } - public void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName) + public void CheckTrialIntroEligibility(string productIdsJson, string callbackName) { #if UNITY_IOS - _checkTrialIntroEligibilityForProductIds(productIdsJson, callbackName); + _checkTrialIntroEligibility(productIdsJson, callbackName); #endif } diff --git a/package.json b/package.json index 2fb7af6..8040cd0 100644 --- a/package.json +++ b/package.json @@ -29,5 +29,6 @@ "/Runtime.meta", "/Editor", "/Editor.meta" - ] + ], + "dependencies": {} } From 0b1a666b67e77710f9ea7b06c66f085c379ecd29 Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Mon, 12 Dec 2022 17:20:22 +0300 Subject: [PATCH 15/22] C# part of new major release. (#126) * Android native part updates supported. * User info method added. * DTO fixes * Models directory renamed to Dto * CSharp part of major release support. * Small fix * Small fixes * Updated csharp part for noop and ios * Fixed errors * Small fixes * Initialization fixes. * Fixes after testing * Show screen method. * ID to Id * Old C# version support Co-authored-by: Surik --- Editor/QonversionDependencies.xml | 2 +- Runtime/Android/AutomationsWrapperAndroid.cs | 55 ++ .../Android/AutomationsWrapperAndroid.cs.meta | 3 + .../unitywrapper/AutomationsWrapper.java | 110 ++- .../unitywrapper/QonversionWrapper.java | 35 +- .../com/qonversion/unitywrapper/Utils.java | 22 + .../qonversion/unitywrapper/Utils.java.meta | 3 + Runtime/Android/QonversionWrapperAndroid.cs | 61 +- Runtime/Scripts/Automations.cs | 36 +- Runtime/Scripts/{Models.meta => Dto.meta} | 0 .../Scripts/{Models => Dto}/ActionResult.cs | 0 .../{Models => Dto}/ActionResult.cs.meta | 0 .../{Models => Dto}/ActionResultType.cs | 0 .../{Models => Dto}/ActionResultType.cs.meta | 0 .../AttributionProvider.cs} | 2 +- .../AttributionProvider.cs.meta} | 0 .../Scripts/{ => Dto}/AutomationsDelegate.cs | 2 +- .../{ => Dto}/AutomationsDelegate.cs.meta | 0 .../{Models => Dto}/AutomationsEvent.cs | 0 .../{Models => Dto}/AutomationsEvent.cs.meta | 0 .../{Models => Dto}/AutomationsEventType.cs | 0 .../AutomationsEventType.cs.meta | 0 .../Scripts/{Models => Dto}/Eligibility.cs | 0 .../{Models => Dto}/Eligibility.cs.meta | 0 .../{Models => Dto}/EligibilityStatus.cs | 0 .../{Models => Dto}/EligibilityStatus.cs.meta | 0 .../Permission.cs => Dto/Entitlement.cs} | 72 +- .../Entitlement.cs.meta} | 0 .../Scripts/Dto/EntitlementsCacheLifetime.cs | 14 + .../EntitlementsCacheLifetime.cs.meta} | 0 Runtime/Scripts/Dto/Environment.cs | 8 + Runtime/Scripts/Dto/Environment.cs.meta | 3 + Runtime/Scripts/Dto/LaunchMode.cs | 8 + Runtime/Scripts/Dto/LaunchMode.cs.meta | 3 + Runtime/Scripts/{Models => Dto}/Offering.cs | 7 +- .../Scripts/{Models => Dto}/Offering.cs.meta | 0 Runtime/Scripts/{Models => Dto}/Offerings.cs | 0 .../Scripts/{Models => Dto}/Offerings.cs.meta | 0 Runtime/Scripts/{Models => Dto}/Product.cs | 0 .../Scripts/{Models => Dto}/Product.cs.meta | 0 .../Scripts/{Models => Dto}/ProrationMode.cs | 2 +- .../{Models => Dto}/ProrationMode.cs.meta | 0 .../{Models => Dto}/QonversionError.cs | 0 .../{Models => Dto}/QonversionError.cs.meta | 0 .../Scripts/{Models => Dto}/SkProduct.meta | 0 .../{Models => Dto}/SkProduct/SKProduct.cs | 0 .../SkProduct/SKProduct.cs.meta | 0 .../SkProduct/SKProductDiscount.cs | 0 .../SkProduct/SKProductDiscount.cs.meta | 0 .../SkProduct/SKProductSubscriptionPeriod.cs | 0 .../SKProductSubscriptionPeriod.cs.meta | 0 Runtime/Scripts/{Models => Dto}/SkuDetails.cs | 2 +- .../{Models => Dto}/SkuDetails.cs.meta | 0 Runtime/Scripts/Dto/User.cs | 36 + Runtime/Scripts/Dto/User.cs.meta | 3 + .../Scripts/{Models => Dto}/UserProperty.cs | 7 +- .../{Models => Dto}/UserProperty.cs.meta | 0 Runtime/Scripts/IAutomations.cs | 45 + Runtime/Scripts/IAutomations.cs.meta | 3 + Runtime/Scripts/IQonversion.cs | 208 +++++ Runtime/Scripts/IQonversion.cs.meta | 3 + Runtime/Scripts/IQonversionResultHandler.cs | 9 - .../Scripts/IQonversionResultHandler.cs.meta | 11 - Runtime/Scripts/InitDelegate.cs | 7 - Runtime/Scripts/InitEvent.cs | 8 - Runtime/Scripts/InitEvent.cs.meta | 11 - Runtime/Scripts/Internal.meta | 3 + .../Scripts/Internal/AutomationsInternal.cs | 161 ++++ .../Internal/AutomationsInternal.cs.meta | 3 + Runtime/Scripts/{ => Internal}/Constants.cs | 2 +- .../Scripts/{ => Internal}/Constants.cs.meta | 0 Runtime/Scripts/{ => Internal}/Mapper.cs | 41 +- Runtime/Scripts/{ => Internal}/Mapper.cs.meta | 0 .../Scripts/Internal/QonversionInternal.cs | 453 ++++++++++ .../QonversionInternal.cs.meta} | 2 +- Runtime/Scripts/{ => Internal}/Utils.cs | 0 Runtime/Scripts/{ => Internal}/Utils.cs.meta | 0 Runtime/Scripts/Internal/wrappers.meta | 3 + .../Internal/wrappers/automations.meta | 3 + .../automations/AutomationsWrapperNoop.cs | 31 + .../AutomationsWrapperNoop.cs.meta | 3 + .../automations/IAutomationsWrapper.cs | 14 + .../automations/IAutomationsWrapper.cs.meta | 3 + .../Scripts/Internal/wrappers/qonversion.meta | 3 + .../qonversion}/IQonversionWrapper.cs | 11 +- .../qonversion}/IQonversionWrapper.cs.meta | 0 .../qonversion}/QonversionWrapperNoop.cs | 36 +- .../qonversion}/QonversionWrapperNoop.cs.meta | 0 .../Models/PermissionsCacheLifetime.cs | 14 - Runtime/Scripts/Qonversion.cs | 834 +----------------- Runtime/Scripts/Qonversion.cs.meta | 12 +- Runtime/Scripts/QonversionAndroidHandler.cs | 26 - .../Scripts/QonversionAndroidHandler.cs.meta | 11 - Runtime/Scripts/QonversionConfig.cs | 18 + Runtime/Scripts/QonversionConfig.cs.meta | 3 + Runtime/Scripts/QonversionConfigBuilder.cs | 55 ++ .../Scripts/QonversionConfigBuilder.cs.meta | 3 + Runtime/Scripts/QonversionLauncher.cs | 29 - Runtime/Scripts/QonversionLauncher.cs.meta | 11 - Runtime/iOS/AutomationsWrapperIOS.cs | 79 ++ Runtime/iOS/AutomationsWrapperIOS.cs.meta | 3 + Runtime/iOS/QonversionWrapperIOS.cs | 80 +- fastlane.meta | 8 + fastlane/README.md.meta | 7 + fastlane/fastfile.meta | 7 + fastlane/report.xml.meta | 7 + img/UnityQonversionLauncher.png.meta | 98 ++ 107 files changed, 1650 insertions(+), 1228 deletions(-) create mode 100644 Runtime/Android/AutomationsWrapperAndroid.cs create mode 100644 Runtime/Android/AutomationsWrapperAndroid.cs.meta create mode 100644 Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java create mode 100644 Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java.meta rename Runtime/Scripts/{Models.meta => Dto.meta} (100%) rename Runtime/Scripts/{Models => Dto}/ActionResult.cs (100%) rename Runtime/Scripts/{Models => Dto}/ActionResult.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/ActionResultType.cs (100%) rename Runtime/Scripts/{Models => Dto}/ActionResultType.cs.meta (100%) rename Runtime/Scripts/{Models/AttributionSource.cs => Dto/AttributionProvider.cs} (73%) rename Runtime/Scripts/{Models/AttributionSource.cs.meta => Dto/AttributionProvider.cs.meta} (100%) rename Runtime/Scripts/{ => Dto}/AutomationsDelegate.cs (91%) rename Runtime/Scripts/{ => Dto}/AutomationsDelegate.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/AutomationsEvent.cs (100%) rename Runtime/Scripts/{Models => Dto}/AutomationsEvent.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/AutomationsEventType.cs (100%) rename Runtime/Scripts/{Models => Dto}/AutomationsEventType.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/Eligibility.cs (100%) rename Runtime/Scripts/{Models => Dto}/Eligibility.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/EligibilityStatus.cs (100%) rename Runtime/Scripts/{Models => Dto}/EligibilityStatus.cs.meta (100%) rename Runtime/Scripts/{Models/Permission.cs => Dto/Entitlement.cs} (52%) rename Runtime/Scripts/{Models/Permission.cs.meta => Dto/Entitlement.cs.meta} (100%) create mode 100644 Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs rename Runtime/Scripts/{Models/PermissionsCacheLifetime.cs.meta => Dto/EntitlementsCacheLifetime.cs.meta} (100%) create mode 100644 Runtime/Scripts/Dto/Environment.cs create mode 100644 Runtime/Scripts/Dto/Environment.cs.meta create mode 100644 Runtime/Scripts/Dto/LaunchMode.cs create mode 100644 Runtime/Scripts/Dto/LaunchMode.cs.meta rename Runtime/Scripts/{Models => Dto}/Offering.cs (95%) rename Runtime/Scripts/{Models => Dto}/Offering.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/Offerings.cs (100%) rename Runtime/Scripts/{Models => Dto}/Offerings.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/Product.cs (100%) rename Runtime/Scripts/{Models => Dto}/Product.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/ProrationMode.cs (82%) rename Runtime/Scripts/{Models => Dto}/ProrationMode.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/QonversionError.cs (100%) rename Runtime/Scripts/{Models => Dto}/QonversionError.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProduct.cs (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProduct.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProductDiscount.cs (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProductDiscount.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProductSubscriptionPeriod.cs (100%) rename Runtime/Scripts/{Models => Dto}/SkProduct/SKProductSubscriptionPeriod.cs.meta (100%) rename Runtime/Scripts/{Models => Dto}/SkuDetails.cs (99%) rename Runtime/Scripts/{Models => Dto}/SkuDetails.cs.meta (100%) create mode 100644 Runtime/Scripts/Dto/User.cs create mode 100644 Runtime/Scripts/Dto/User.cs.meta rename Runtime/Scripts/{Models => Dto}/UserProperty.cs (66%) rename Runtime/Scripts/{Models => Dto}/UserProperty.cs.meta (100%) create mode 100644 Runtime/Scripts/IAutomations.cs create mode 100644 Runtime/Scripts/IAutomations.cs.meta create mode 100644 Runtime/Scripts/IQonversion.cs create mode 100644 Runtime/Scripts/IQonversion.cs.meta delete mode 100644 Runtime/Scripts/IQonversionResultHandler.cs delete mode 100644 Runtime/Scripts/IQonversionResultHandler.cs.meta delete mode 100644 Runtime/Scripts/InitDelegate.cs delete mode 100644 Runtime/Scripts/InitEvent.cs delete mode 100644 Runtime/Scripts/InitEvent.cs.meta create mode 100644 Runtime/Scripts/Internal.meta create mode 100644 Runtime/Scripts/Internal/AutomationsInternal.cs create mode 100644 Runtime/Scripts/Internal/AutomationsInternal.cs.meta rename Runtime/Scripts/{ => Internal}/Constants.cs (73%) rename Runtime/Scripts/{ => Internal}/Constants.cs.meta (100%) rename Runtime/Scripts/{ => Internal}/Mapper.cs (76%) rename Runtime/Scripts/{ => Internal}/Mapper.cs.meta (100%) create mode 100644 Runtime/Scripts/Internal/QonversionInternal.cs rename Runtime/Scripts/{InitDelegate.cs.meta => Internal/QonversionInternal.cs.meta} (83%) rename Runtime/Scripts/{ => Internal}/Utils.cs (100%) rename Runtime/Scripts/{ => Internal}/Utils.cs.meta (100%) create mode 100644 Runtime/Scripts/Internal/wrappers.meta create mode 100644 Runtime/Scripts/Internal/wrappers/automations.meta create mode 100644 Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs create mode 100644 Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta create mode 100644 Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs create mode 100644 Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta create mode 100644 Runtime/Scripts/Internal/wrappers/qonversion.meta rename Runtime/Scripts/{ => Internal/wrappers/qonversion}/IQonversionWrapper.cs (73%) rename Runtime/Scripts/{ => Internal/wrappers/qonversion}/IQonversionWrapper.cs.meta (100%) rename Runtime/Scripts/{ => Internal/wrappers/qonversion}/QonversionWrapperNoop.cs (73%) rename Runtime/Scripts/{ => Internal/wrappers/qonversion}/QonversionWrapperNoop.cs.meta (100%) delete mode 100644 Runtime/Scripts/Models/PermissionsCacheLifetime.cs delete mode 100644 Runtime/Scripts/QonversionAndroidHandler.cs delete mode 100644 Runtime/Scripts/QonversionAndroidHandler.cs.meta create mode 100644 Runtime/Scripts/QonversionConfig.cs create mode 100644 Runtime/Scripts/QonversionConfig.cs.meta create mode 100644 Runtime/Scripts/QonversionConfigBuilder.cs create mode 100644 Runtime/Scripts/QonversionConfigBuilder.cs.meta delete mode 100644 Runtime/Scripts/QonversionLauncher.cs delete mode 100644 Runtime/Scripts/QonversionLauncher.cs.meta create mode 100644 Runtime/iOS/AutomationsWrapperIOS.cs create mode 100644 Runtime/iOS/AutomationsWrapperIOS.cs.meta create mode 100644 fastlane.meta create mode 100644 fastlane/README.md.meta create mode 100644 fastlane/fastfile.meta create mode 100644 fastlane/report.xml.meta create mode 100644 img/UnityQonversionLauncher.png.meta diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml index 694dad8..50c4eaf 100644 --- a/Editor/QonversionDependencies.xml +++ b/Editor/QonversionDependencies.xml @@ -1,7 +1,7 @@ - + diff --git a/Runtime/Android/AutomationsWrapperAndroid.cs b/Runtime/Android/AutomationsWrapperAndroid.cs new file mode 100644 index 0000000..4aa274a --- /dev/null +++ b/Runtime/Android/AutomationsWrapperAndroid.cs @@ -0,0 +1,55 @@ +using UnityEngine; + +namespace QonversionUnity +{ + internal class AutomationsWrapperAndroid : IAutomationsWrapper + { + public void Initialize(string gameObjectName) + { + CallAutomations("initialize", gameObjectName); + } + + public void SetNotificationsToken(string token) + { + CallAutomations("setNotificationsToken", token); + } + + public bool HandleNotification(string notification) + { + return CallAutomations("handleNotification", notification); + } + + public string GetNotificationCustomPayload(string notification) + { + return CallAutomations("getNotificationCustomPayload", notification); + } + + public void SubscribeOnAutomationEvents() + { + CallAutomations("subscribeOnAutomationEvents"); + } + + public void ShowScreen(string screenId, string callbackName) + { + CallAutomations("showScreen", screenId, callbackName); + } + + private const string AutomationsWrapper = "com.qonversion.unitywrapper.AutomationsWrapper"; + + private static T CallAutomations(string methodName, params object[] args) + { + using (var automations = new AndroidJavaClass(AutomationsWrapper)) + { + return automations.CallStatic(methodName, args); + } + } + + private static void CallAutomations(string methodName, params object[] args) + { + using (var automations = new AndroidJavaClass(AutomationsWrapper)) + { + automations.CallStatic(methodName, args); + } + } + } +} \ No newline at end of file diff --git a/Runtime/Android/AutomationsWrapperAndroid.cs.meta b/Runtime/Android/AutomationsWrapperAndroid.cs.meta new file mode 100644 index 0000000..70fa1d1 --- /dev/null +++ b/Runtime/Android/AutomationsWrapperAndroid.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bf1469979a8544c5b531368ea34cec2f +timeCreated: 1668776137 \ No newline at end of file diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java index 8a4d8f2..613ecb7 100644 --- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.jetbrains.annotations.NotNull; @@ -16,9 +17,11 @@ import io.qonversion.sandwich.AutomationsEventListener; import io.qonversion.sandwich.AutomationsSandwich; +import io.qonversion.sandwich.ResultListener; +import io.qonversion.sandwich.SandwichError; @SuppressWarnings("UnnecessaryLocalVariable") -public class AutomationsWrapper implements AutomationsEventListener { +public class AutomationsWrapper { private static final String EVENT_SCREEN_SHOWN = "OnAutomationsScreenShown"; private static final String EVENT_ACTION_STARTED = "OnAutomationsActionStarted"; private static final String EVENT_ACTION_FAILED = "OnAutomationsActionFailed"; @@ -26,27 +29,23 @@ public class AutomationsWrapper implements AutomationsEventListener { private static final String EVENT_AUTOMATIONS_FINISHED = "OnAutomationsFinished"; public static String TAG = "AutomationsDelegate"; - private final MessageSender messageSender; - private final AutomationsSandwich automationsSandwich; + private static MessageSender messageSender; + private static AutomationsSandwich automationsSandwich; - public AutomationsWrapper(MessageSender messageSender) { - this.messageSender = messageSender; + public static synchronized void initialize(String unityListener) { + messageSender = new MessageSender(unityListener); automationsSandwich = new AutomationsSandwich(); } - public void initialize() { - automationsSandwich.initialize(); + public static synchronized void subscribeOnAutomationEvents() { + automationsSandwich.setDelegate(new EventListener()); } - public void subscribe() { - automationsSandwich.setDelegate(this); - } - - public void setNotificationsToken(String token) { + public static synchronized void setNotificationsToken(String token) { automationsSandwich.setNotificationToken(token); } - public boolean handleNotification(String notification) { + public static synchronized boolean handleNotification(String notification) { try { ObjectMapper mapper = new ObjectMapper(); @@ -64,50 +63,73 @@ public boolean handleNotification(String notification) { } @Nullable - public Map getNotificationCustomPayload(String notification) { + public static synchronized String getNotificationCustomPayload(String notification) { try { - ObjectMapper mapper = new ObjectMapper(); + final ObjectMapper mapper = new ObjectMapper(); - TypeReference> typeRef + final TypeReference> typeRef = new TypeReference>() { }; - Map notificationInfo = mapper.readValue(notification, typeRef); + final Map notificationInfo = mapper.readValue(notification, typeRef); - Map payload = automationsSandwich.getNotificationCustomPayload(notificationInfo); + final Map payload = automationsSandwich.getNotificationCustomPayload(notificationInfo); + final String json = mapper.writeValueAsString(payload); - return payload; + return json; } catch (Exception e) { return null; } } - @Override - public void onAutomationEvent(@NonNull Event event, @Nullable Map data) { - String methodName; - switch (event) { - case ScreenShown: - methodName = EVENT_SCREEN_SHOWN; - break; - case ActionStarted: - methodName = EVENT_ACTION_STARTED; - break; - case ActionFinished: - methodName = EVENT_ACTION_FINISHED; - break; - case ActionFailed: - methodName = EVENT_ACTION_FAILED; - break; - case AutomationsFinished: - methodName = EVENT_AUTOMATIONS_FINISHED; - break; - default: - return; - } + public static synchronized void showScreen(String screenId, String unityCallbackName) { + automationsSandwich.showScreen(screenId, new ResultListener() { + @Override + public void onSuccess(@NonNull Map data) { + sendMessageToUnity(data, unityCallbackName); + } + + @Override + public void onError(@NonNull SandwichError error) { + handleErrorResponse(error, unityCallbackName); + } + }); + } + + private static void handleErrorResponse(@NotNull SandwichError error, @NotNull String methodName) { + final ObjectNode rootNode = Utils.createErrorNode(error); - sendMessageToUnity(data == null ? new HashMap<>() : data, methodName); + sendMessageToUnity(rootNode, methodName); + } + + static class EventListener implements AutomationsEventListener { + @Override + public void onAutomationEvent(@NonNull Event event, @Nullable Map data) { + String methodName; + switch (event) { + case ScreenShown: + methodName = EVENT_SCREEN_SHOWN; + break; + case ActionStarted: + methodName = EVENT_ACTION_STARTED; + break; + case ActionFinished: + methodName = EVENT_ACTION_FINISHED; + break; + case ActionFailed: + methodName = EVENT_ACTION_FAILED; + break; + case AutomationsFinished: + methodName = EVENT_AUTOMATIONS_FINISHED; + break; + default: + return; + } + + sendMessageToUnity(data == null ? new HashMap<>() : data, methodName); + } } - private void sendMessageToUnity(@NotNull Object objectToConvert, @NotNull String methodName) { + private static void sendMessageToUnity(@NotNull Object objectToConvert, @NotNull String methodName) { try { messageSender.sendMessageToUnity(objectToConvert, methodName); } catch (JsonProcessingException e) { @@ -115,7 +137,7 @@ private void sendMessageToUnity(@NotNull Object objectToConvert, @NotNull String } } - private void handleException(Exception e) { + private static void handleException(Exception e) { Log.e(TAG, "An error occurred while processing automations flow: " + e.getLocalizedMessage()); } } diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java index f0593fe..8508c59 100644 --- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java @@ -30,7 +30,6 @@ public class QonversionWrapper { public static String ENTITLEMENTS_UPDATE_LISTENER = "OnReceivedUpdatedEntitlements"; private static MessageSender messageSender; - private static AutomationsWrapper automationsWrapper; private static QonversionSandwich qonversionSandwich; public static synchronized void initialize(String unityListener) { @@ -42,7 +41,6 @@ public static synchronized void initialize(String unityListener) { () -> UnityPlayer.currentActivity, entitlements -> sendMessageToUnity(entitlements, ENTITLEMENTS_UPDATE_LISTENER) ); - automationsWrapper = new AutomationsWrapper(messageSender); } public static synchronized void storeSdkInfo(String version, String source) { @@ -146,23 +144,6 @@ public static synchronized void checkTrialIntroEligibility(String productIds, St } } - public static synchronized void setNotificationsToken(String token) { - automationsWrapper.setNotificationsToken(token); - } - - public static synchronized boolean handleNotification(String notification) { - return automationsWrapper.handleNotification(notification); - } - - @Nullable - public static synchronized Map getNotificationCustomPayload(String notification) { - return automationsWrapper.getNotificationCustomPayload(notification); - } - - public static synchronized void subscribeOnAutomationEvents() { - automationsWrapper.subscribe(); - } - private static ResultListener getResultListener(@NotNull String methodName) { return new ResultListener() { @Override @@ -187,7 +168,7 @@ public void onSuccess(@NonNull Map data) { @Override public void onError(@NonNull SandwichError error, boolean isCancelled) { final ObjectMapper mapper = new ObjectMapper(); - final ObjectNode rootNode = createErrorNode(error); + final ObjectNode rootNode = Utils.createErrorNode(error); final JsonNode isCancelledNode = mapper.convertValue(isCancelled, JsonNode.class); rootNode.set("isCancelled", isCancelledNode); sendMessageToUnity(rootNode, methodName); @@ -196,23 +177,11 @@ public void onError(@NonNull SandwichError error, boolean isCancelled) { } private static void handleErrorResponse(@NotNull SandwichError error, @NotNull String methodName) { - final ObjectNode rootNode = createErrorNode(error); + final ObjectNode rootNode = Utils.createErrorNode(error); sendMessageToUnity(rootNode, methodName); } - private static ObjectNode createErrorNode(@NotNull SandwichError error) { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode errorNode = mapper.createObjectNode(); - errorNode.put("code", error.getCode()); - errorNode.put("description", error.getDescription()); - errorNode.put("additionalMessage", error.getAdditionalMessage()); - - ObjectNode rootNode = mapper.createObjectNode(); - rootNode.set("error", errorNode); - return rootNode; - } - private static void sendMessageToUnity(@NotNull Object objectToConvert, @NotNull String methodName) { try { messageSender.sendMessageToUnity(objectToConvert, methodName); diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java b/Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java new file mode 100644 index 0000000..987f443 --- /dev/null +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java @@ -0,0 +1,22 @@ +package com.qonversion.unitywrapper; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import org.jetbrains.annotations.NotNull; +import io.qonversion.sandwich.SandwichError; + +public class Utils { + + public static ObjectNode createErrorNode(@NotNull SandwichError error) { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode errorNode = mapper.createObjectNode(); + errorNode.put("code", error.getCode()); + errorNode.put("description", error.getDescription()); + errorNode.put("additionalMessage", error.getAdditionalMessage()); + + ObjectNode rootNode = mapper.createObjectNode(); + rootNode.set("error", errorNode); + return rootNode; + } +} diff --git a/Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java.meta b/Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java.meta new file mode 100644 index 0000000..a2747ed --- /dev/null +++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/Utils.java.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1b5c0dd49367425db4e808bbc38580bf +timeCreated: 1670833335 \ No newline at end of file diff --git a/Runtime/Android/QonversionWrapperAndroid.cs b/Runtime/Android/QonversionWrapperAndroid.cs index 2829f0f..4ab59b9 100644 --- a/Runtime/Android/QonversionWrapperAndroid.cs +++ b/Runtime/Android/QonversionWrapperAndroid.cs @@ -1,6 +1,5 @@ using System; -using System.Collections.Generic; -using QonversionUnity.MiniJSON; +using JetBrains.Annotations; using UnityEngine; namespace QonversionUnity @@ -17,9 +16,9 @@ public void StoreSdkInfo(string version, string source) CallQonversion("storeSdkInfo", version, source); } - public void InitializeSdk(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime) { - CallQonversion("initializeSdk", projectKey, observerMode, callbackName); + CallQonversion("initializeSdk", projectKey, launchMode, environment, entitlementsCacheLifetime); } public void SetDebugMode() @@ -61,29 +60,11 @@ public void SetAppleSearchAdsAttributionEnabled(bool enable) { } - public void AddAttributionData(string conversionData, AttributionSource source) + public void AddAttributionData(string conversionData, string providerName) { - string attibutionSource; - - switch (source) - { - case AttributionSource.AppsFlyer: - attibutionSource = "AppsFlyer"; - break; - case AttributionSource.Branch: - attibutionSource = "Branch"; - break; - case AttributionSource.Adjust: - attibutionSource = "Adjust"; - break; - default: - Debug.LogWarning(string.Format("[Qonversion] Not Supported AttributionSource.{0} on Android platform.", source)); - return; - } - try { - CallQonversion("attribution", conversionData, attibutionSource); + CallQonversion("attribution", conversionData, providerName); } catch (Exception e) { @@ -101,6 +82,11 @@ public void Logout() CallQonversion("logout"); } + public void UserInfo(string callbackName) + { + CallQonversion("userInfo", callbackName); + } + public void CheckEntitlements(string callbackName) { CallQonversion("checkEntitlements", callbackName); @@ -146,24 +132,8 @@ public void CheckTrialIntroEligibility(string productIdsJson, string callbackNam CallQonversion("checkTrialIntroEligibility", productIdsJson, callbackName); } - public void SetNotificationsToken(string token) - { - CallQonversion("setNotificationsToken", token); - } - - public bool HandleNotification(string notification) - { - return CallQonversion("handleNotification", notification); - } - - public string GetNotificationCustomPayload(string notification) - { - return CallQonversion("getNotificationCustomPayload", notification); - } - - public void SubscribeOnAutomationEvents() + public void PromoPurchase(string storeProductId, string callbackName) { - CallQonversion("subscribeOnAutomationEvents"); } private const string QonversionWrapper = "com.qonversion.unitywrapper.QonversionWrapper"; @@ -183,14 +153,5 @@ private static void CallQonversion(string methodName, params object[] args) qonversion.CallStatic(methodName, args); } } - - public void PromoPurchase(string storeProductId, string callbackName) - { - } - - public void SetPermissionsCacheLifetime(string lifetime) - { - CallQonversion("setPermissionsCacheLifetime", lifetime); - } } } \ No newline at end of file diff --git a/Runtime/Scripts/Automations.cs b/Runtime/Scripts/Automations.cs index c9c464a..840b500 100644 --- a/Runtime/Scripts/Automations.cs +++ b/Runtime/Scripts/Automations.cs @@ -1,17 +1,39 @@ -using UnityEngine; +using System; +using JetBrains.Annotations; namespace QonversionUnity { - public partial class Automations : MonoBehaviour + public static class Automations { + [CanBeNull] private static IAutomations _backingInstance; + /// - /// The Automations delegate is responsible for handling in-app screens and actions when push notification is received. - /// Make sure the method is called before Qonversion.handleNotification. + /// Use this variable to get a current initialized instance of the Qonversion Automations. + /// Please, use Automations only after calling . + /// Otherwise, trying to access the variable will cause an error. /// - /// The delegate to handle automations events - public static void SetDelegate(AutomationsDelegate automationsDelegate) + /// Current initialized instance of the Qonversion Automations. + /// throws exception if Qonversion has not been initialized. + public static IAutomations GetSharedInstance() { - Qonversion.SetAutomationsDelegate(automationsDelegate); + if (_backingInstance == null) + { + try + { + Qonversion.GetSharedInstance(); + } + catch (Exception e) + { + throw new Exception("Qonversion has not been initialized. " + + "Automations should be used after Qonversion is initialized."); + } + + _backingInstance = AutomationsInternal.CreateInstance(); + } + + return _backingInstance; } + + public delegate void OnShowScreenResponseReceived(QonversionError error); } } diff --git a/Runtime/Scripts/Models.meta b/Runtime/Scripts/Dto.meta similarity index 100% rename from Runtime/Scripts/Models.meta rename to Runtime/Scripts/Dto.meta diff --git a/Runtime/Scripts/Models/ActionResult.cs b/Runtime/Scripts/Dto/ActionResult.cs similarity index 100% rename from Runtime/Scripts/Models/ActionResult.cs rename to Runtime/Scripts/Dto/ActionResult.cs diff --git a/Runtime/Scripts/Models/ActionResult.cs.meta b/Runtime/Scripts/Dto/ActionResult.cs.meta similarity index 100% rename from Runtime/Scripts/Models/ActionResult.cs.meta rename to Runtime/Scripts/Dto/ActionResult.cs.meta diff --git a/Runtime/Scripts/Models/ActionResultType.cs b/Runtime/Scripts/Dto/ActionResultType.cs similarity index 100% rename from Runtime/Scripts/Models/ActionResultType.cs rename to Runtime/Scripts/Dto/ActionResultType.cs diff --git a/Runtime/Scripts/Models/ActionResultType.cs.meta b/Runtime/Scripts/Dto/ActionResultType.cs.meta similarity index 100% rename from Runtime/Scripts/Models/ActionResultType.cs.meta rename to Runtime/Scripts/Dto/ActionResultType.cs.meta diff --git a/Runtime/Scripts/Models/AttributionSource.cs b/Runtime/Scripts/Dto/AttributionProvider.cs similarity index 73% rename from Runtime/Scripts/Models/AttributionSource.cs rename to Runtime/Scripts/Dto/AttributionProvider.cs index 75b4474..e80b99a 100644 --- a/Runtime/Scripts/Models/AttributionSource.cs +++ b/Runtime/Scripts/Dto/AttributionProvider.cs @@ -1,6 +1,6 @@ namespace QonversionUnity { - public enum AttributionSource + public enum AttributionProvider { AppsFlyer = 0, Branch, diff --git a/Runtime/Scripts/Models/AttributionSource.cs.meta b/Runtime/Scripts/Dto/AttributionProvider.cs.meta similarity index 100% rename from Runtime/Scripts/Models/AttributionSource.cs.meta rename to Runtime/Scripts/Dto/AttributionProvider.cs.meta diff --git a/Runtime/Scripts/AutomationsDelegate.cs b/Runtime/Scripts/Dto/AutomationsDelegate.cs similarity index 91% rename from Runtime/Scripts/AutomationsDelegate.cs rename to Runtime/Scripts/Dto/AutomationsDelegate.cs index 0c569ae..566bb3a 100644 --- a/Runtime/Scripts/AutomationsDelegate.cs +++ b/Runtime/Scripts/Dto/AutomationsDelegate.cs @@ -28,7 +28,7 @@ public abstract class AutomationsDelegate : MonoBehaviour /// /// Called when Automations flow finishes executing an action /// For instance, if the user made a purchase then action.type == QONActionResultTypePurchase - /// Then you can use the method to get available permissions + /// Then you can use the method to get available permissions /// /// executed action public abstract void OnAutomationsActionFinished(ActionResult actionResult); diff --git a/Runtime/Scripts/AutomationsDelegate.cs.meta b/Runtime/Scripts/Dto/AutomationsDelegate.cs.meta similarity index 100% rename from Runtime/Scripts/AutomationsDelegate.cs.meta rename to Runtime/Scripts/Dto/AutomationsDelegate.cs.meta diff --git a/Runtime/Scripts/Models/AutomationsEvent.cs b/Runtime/Scripts/Dto/AutomationsEvent.cs similarity index 100% rename from Runtime/Scripts/Models/AutomationsEvent.cs rename to Runtime/Scripts/Dto/AutomationsEvent.cs diff --git a/Runtime/Scripts/Models/AutomationsEvent.cs.meta b/Runtime/Scripts/Dto/AutomationsEvent.cs.meta similarity index 100% rename from Runtime/Scripts/Models/AutomationsEvent.cs.meta rename to Runtime/Scripts/Dto/AutomationsEvent.cs.meta diff --git a/Runtime/Scripts/Models/AutomationsEventType.cs b/Runtime/Scripts/Dto/AutomationsEventType.cs similarity index 100% rename from Runtime/Scripts/Models/AutomationsEventType.cs rename to Runtime/Scripts/Dto/AutomationsEventType.cs diff --git a/Runtime/Scripts/Models/AutomationsEventType.cs.meta b/Runtime/Scripts/Dto/AutomationsEventType.cs.meta similarity index 100% rename from Runtime/Scripts/Models/AutomationsEventType.cs.meta rename to Runtime/Scripts/Dto/AutomationsEventType.cs.meta diff --git a/Runtime/Scripts/Models/Eligibility.cs b/Runtime/Scripts/Dto/Eligibility.cs similarity index 100% rename from Runtime/Scripts/Models/Eligibility.cs rename to Runtime/Scripts/Dto/Eligibility.cs diff --git a/Runtime/Scripts/Models/Eligibility.cs.meta b/Runtime/Scripts/Dto/Eligibility.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Eligibility.cs.meta rename to Runtime/Scripts/Dto/Eligibility.cs.meta diff --git a/Runtime/Scripts/Models/EligibilityStatus.cs b/Runtime/Scripts/Dto/EligibilityStatus.cs similarity index 100% rename from Runtime/Scripts/Models/EligibilityStatus.cs rename to Runtime/Scripts/Dto/EligibilityStatus.cs diff --git a/Runtime/Scripts/Models/EligibilityStatus.cs.meta b/Runtime/Scripts/Dto/EligibilityStatus.cs.meta similarity index 100% rename from Runtime/Scripts/Models/EligibilityStatus.cs.meta rename to Runtime/Scripts/Dto/EligibilityStatus.cs.meta diff --git a/Runtime/Scripts/Models/Permission.cs b/Runtime/Scripts/Dto/Entitlement.cs similarity index 52% rename from Runtime/Scripts/Models/Permission.cs rename to Runtime/Scripts/Dto/Entitlement.cs index ecde528..5c3ccc3 100644 --- a/Runtime/Scripts/Models/Permission.cs +++ b/Runtime/Scripts/Dto/Entitlement.cs @@ -4,21 +4,21 @@ namespace QonversionUnity { - public class Permission + public class Entitlement { - /// Qonversion Permission ID, like premium. - [Tooltip("Create Permission: https://qonversion.io/docs/create-permission")] - public readonly string PermissionID; + /// Qonversion Entitlement ID, like premium. + [Tooltip("Create Entitlement: https://qonversion.io/docs/create-permission")] + public readonly string Id; /// Product ID created in Qonversion Dashboard. [Tooltip("Create Products: https://qonversion.io/docs/create-products")] - public readonly string ProductID; + public readonly string ProductId; - /// A renew state for an associate product that unlocked permission - public readonly QProductRenewState RenewState; + /// A renew state for an associate product that unlocked entitlement + public readonly QEntitlementRenewState RenewState; - /// A source determining where this permission is originally from - App Store, Play Store, Stripe, etc. - public readonly QPermissionSource Source; + /// A source determining where this entitlement is originally from - App Store, Play Store, Stripe, etc. + public readonly QEntitlementSource Source; /// Purchase date public readonly DateTime StartedDate; @@ -26,17 +26,17 @@ public class Permission /// Expiration date for subscription public readonly DateTime? ExpirationDate; - /// Use for checking permission for current user. + /// Use for checking entitlement for current user. /// Pay attention, isActive == true does not mean that subscription is renewable. - /// Subscription could be canceled, but the user could still have a permission + /// Subscription could be canceled, but the user could still have a entitlement public readonly bool IsActive; - public Permission(Dictionary dict) + public Entitlement(Dictionary dict) { - if (dict.TryGetValue("id", out object value)) PermissionID = value as string; - if (dict.TryGetValue("associatedProduct", out value)) ProductID = value as string; + if (dict.TryGetValue("id", out object value)) Id = value as string; + if (dict.TryGetValue("productId", out value)) ProductId = value as string; if (dict.TryGetValue("renewState", out value)) RenewState = FormatRenewState(value); - Source = dict.TryGetValue("source", out value) ? FormatPermissionSource(value) : QPermissionSource.Unknown; + Source = dict.TryGetValue("source", out value) ? FormatEntitlementSource(value) : QEntitlementSource.Unknown; if (dict.TryGetValue("active", out value)) IsActive = (bool)value; if (dict.TryGetValue("startedTimestamp", out value)) StartedDate = FormatDate(value); if (dict.TryGetValue("expirationTimestamp", out value) && value != null) ExpirationDate = FormatDate(value); @@ -44,8 +44,8 @@ public Permission(Dictionary dict) public override string ToString() { - return $"{nameof(PermissionID)}: {PermissionID}, " + - $"{nameof(ProductID)}: {ProductID}, " + + return $"{nameof(Id)}: {Id}, " + + $"{nameof(ProductId)}: {ProductId}, " + $"{nameof(RenewState)}: {RenewState}, " + $"{nameof(Source)}: {Source}, " + $"{nameof(StartedDate)}: {StartedDate}, " + @@ -61,17 +61,41 @@ private DateTime FormatDate(object time) { return Utils.FormatDate((long) time); } - private QProductRenewState FormatRenewState(object renewState) => - (QProductRenewState)Convert.ToInt32(renewState); + private QEntitlementRenewState FormatRenewState(object renewState) + { + string value = renewState as string; + QEntitlementRenewState result; + switch (value) + { + case "non_renewable": + result = QEntitlementRenewState.NonRenewable; + break; + case "will_renew": + result = QEntitlementRenewState.WillRenew; + break; + case "canceled": + result = QEntitlementRenewState.Canceled; + break; + case "billing_issue": + result = QEntitlementRenewState.BillingIssue; + break; + default: + result = QEntitlementRenewState.Unknown; + break; + } + + return result; + } - private QPermissionSource FormatPermissionSource(object source) { - return Enum.TryParse(source.ToString(), out QPermissionSource parsedSource) + private QEntitlementSource FormatEntitlementSource(object source) + { + return Enum.TryParse(source.ToString(), out QEntitlementSource parsedSource) ? parsedSource - : QPermissionSource.Unknown; + : QEntitlementSource.Unknown; } } - public enum QProductRenewState + public enum QEntitlementRenewState { /// For in-app purchases. NonRenewable = -1, @@ -87,7 +111,7 @@ public enum QProductRenewState BillingIssue = 3 } - public enum QPermissionSource + public enum QEntitlementSource { Unknown, AppStore, diff --git a/Runtime/Scripts/Models/Permission.cs.meta b/Runtime/Scripts/Dto/Entitlement.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Permission.cs.meta rename to Runtime/Scripts/Dto/Entitlement.cs.meta diff --git a/Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs b/Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs new file mode 100644 index 0000000..b9c4593 --- /dev/null +++ b/Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs @@ -0,0 +1,14 @@ +namespace QonversionUnity +{ + public enum EntitlementsCacheLifetime + { + Week, + TwoWeeks, + Month, + TwoMonths, + ThreeMonths, + SixMonths, + Year, + Unlimited + } +} \ No newline at end of file diff --git a/Runtime/Scripts/Models/PermissionsCacheLifetime.cs.meta b/Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs.meta similarity index 100% rename from Runtime/Scripts/Models/PermissionsCacheLifetime.cs.meta rename to Runtime/Scripts/Dto/EntitlementsCacheLifetime.cs.meta diff --git a/Runtime/Scripts/Dto/Environment.cs b/Runtime/Scripts/Dto/Environment.cs new file mode 100644 index 0000000..f28363b --- /dev/null +++ b/Runtime/Scripts/Dto/Environment.cs @@ -0,0 +1,8 @@ +namespace QonversionUnity +{ + public enum Environment + { + Sandbox, + Production + } +} diff --git a/Runtime/Scripts/Dto/Environment.cs.meta b/Runtime/Scripts/Dto/Environment.cs.meta new file mode 100644 index 0000000..417ae4e --- /dev/null +++ b/Runtime/Scripts/Dto/Environment.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1b02fbe89ab349a59491d47e9ca2329d +timeCreated: 1668682691 \ No newline at end of file diff --git a/Runtime/Scripts/Dto/LaunchMode.cs b/Runtime/Scripts/Dto/LaunchMode.cs new file mode 100644 index 0000000..b847756 --- /dev/null +++ b/Runtime/Scripts/Dto/LaunchMode.cs @@ -0,0 +1,8 @@ +namespace QonversionUnity +{ + public enum LaunchMode + { + Analytics, + SubscriptionManagement + } +} \ No newline at end of file diff --git a/Runtime/Scripts/Dto/LaunchMode.cs.meta b/Runtime/Scripts/Dto/LaunchMode.cs.meta new file mode 100644 index 0000000..82beaa8 --- /dev/null +++ b/Runtime/Scripts/Dto/LaunchMode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 24dcbe0f097a40c59733cfbd46312398 +timeCreated: 1668682749 \ No newline at end of file diff --git a/Runtime/Scripts/Models/Offering.cs b/Runtime/Scripts/Dto/Offering.cs similarity index 95% rename from Runtime/Scripts/Models/Offering.cs rename to Runtime/Scripts/Dto/Offering.cs index e47490b..d6e5b0a 100644 --- a/Runtime/Scripts/Models/Offering.cs +++ b/Runtime/Scripts/Dto/Offering.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using JetBrains.Annotations; @@ -39,7 +39,8 @@ public override string ToString() public enum QOfferingTag { - None, - Main + Unknown = -1, + None = 0, + Main = 1 } } \ No newline at end of file diff --git a/Runtime/Scripts/Models/Offering.cs.meta b/Runtime/Scripts/Dto/Offering.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Offering.cs.meta rename to Runtime/Scripts/Dto/Offering.cs.meta diff --git a/Runtime/Scripts/Models/Offerings.cs b/Runtime/Scripts/Dto/Offerings.cs similarity index 100% rename from Runtime/Scripts/Models/Offerings.cs rename to Runtime/Scripts/Dto/Offerings.cs diff --git a/Runtime/Scripts/Models/Offerings.cs.meta b/Runtime/Scripts/Dto/Offerings.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Offerings.cs.meta rename to Runtime/Scripts/Dto/Offerings.cs.meta diff --git a/Runtime/Scripts/Models/Product.cs b/Runtime/Scripts/Dto/Product.cs similarity index 100% rename from Runtime/Scripts/Models/Product.cs rename to Runtime/Scripts/Dto/Product.cs diff --git a/Runtime/Scripts/Models/Product.cs.meta b/Runtime/Scripts/Dto/Product.cs.meta similarity index 100% rename from Runtime/Scripts/Models/Product.cs.meta rename to Runtime/Scripts/Dto/Product.cs.meta diff --git a/Runtime/Scripts/Models/ProrationMode.cs b/Runtime/Scripts/Dto/ProrationMode.cs similarity index 82% rename from Runtime/Scripts/Models/ProrationMode.cs rename to Runtime/Scripts/Dto/ProrationMode.cs index 707c3dd..5176a56 100644 --- a/Runtime/Scripts/Models/ProrationMode.cs +++ b/Runtime/Scripts/Dto/ProrationMode.cs @@ -9,7 +9,7 @@ public enum ProrationMode ImmediateAndChargeProratedPrice, /// Replacement takes effect immediately, and the new price will be charged on next recurrence time. ImmediateWithoutProration, - /// Replacement takes effect when the old plan expires, and the new price will be charged at the same time. + /// Replacement takes effect when the old plan expires, and the new price will be charged at the same time. Deferred } } \ No newline at end of file diff --git a/Runtime/Scripts/Models/ProrationMode.cs.meta b/Runtime/Scripts/Dto/ProrationMode.cs.meta similarity index 100% rename from Runtime/Scripts/Models/ProrationMode.cs.meta rename to Runtime/Scripts/Dto/ProrationMode.cs.meta diff --git a/Runtime/Scripts/Models/QonversionError.cs b/Runtime/Scripts/Dto/QonversionError.cs similarity index 100% rename from Runtime/Scripts/Models/QonversionError.cs rename to Runtime/Scripts/Dto/QonversionError.cs diff --git a/Runtime/Scripts/Models/QonversionError.cs.meta b/Runtime/Scripts/Dto/QonversionError.cs.meta similarity index 100% rename from Runtime/Scripts/Models/QonversionError.cs.meta rename to Runtime/Scripts/Dto/QonversionError.cs.meta diff --git a/Runtime/Scripts/Models/SkProduct.meta b/Runtime/Scripts/Dto/SkProduct.meta similarity index 100% rename from Runtime/Scripts/Models/SkProduct.meta rename to Runtime/Scripts/Dto/SkProduct.meta diff --git a/Runtime/Scripts/Models/SkProduct/SKProduct.cs b/Runtime/Scripts/Dto/SkProduct/SKProduct.cs similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProduct.cs rename to Runtime/Scripts/Dto/SkProduct/SKProduct.cs diff --git a/Runtime/Scripts/Models/SkProduct/SKProduct.cs.meta b/Runtime/Scripts/Dto/SkProduct/SKProduct.cs.meta similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProduct.cs.meta rename to Runtime/Scripts/Dto/SkProduct/SKProduct.cs.meta diff --git a/Runtime/Scripts/Models/SkProduct/SKProductDiscount.cs b/Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProductDiscount.cs rename to Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs diff --git a/Runtime/Scripts/Models/SkProduct/SKProductDiscount.cs.meta b/Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs.meta similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProductDiscount.cs.meta rename to Runtime/Scripts/Dto/SkProduct/SKProductDiscount.cs.meta diff --git a/Runtime/Scripts/Models/SkProduct/SKProductSubscriptionPeriod.cs b/Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProductSubscriptionPeriod.cs rename to Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs diff --git a/Runtime/Scripts/Models/SkProduct/SKProductSubscriptionPeriod.cs.meta b/Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs.meta similarity index 100% rename from Runtime/Scripts/Models/SkProduct/SKProductSubscriptionPeriod.cs.meta rename to Runtime/Scripts/Dto/SkProduct/SKProductSubscriptionPeriod.cs.meta diff --git a/Runtime/Scripts/Models/SkuDetails.cs b/Runtime/Scripts/Dto/SkuDetails.cs similarity index 99% rename from Runtime/Scripts/Models/SkuDetails.cs rename to Runtime/Scripts/Dto/SkuDetails.cs index b943373..ed4a94b 100644 --- a/Runtime/Scripts/Models/SkuDetails.cs +++ b/Runtime/Scripts/Dto/SkuDetails.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; namespace QonversionUnity diff --git a/Runtime/Scripts/Models/SkuDetails.cs.meta b/Runtime/Scripts/Dto/SkuDetails.cs.meta similarity index 100% rename from Runtime/Scripts/Models/SkuDetails.cs.meta rename to Runtime/Scripts/Dto/SkuDetails.cs.meta diff --git a/Runtime/Scripts/Dto/User.cs b/Runtime/Scripts/Dto/User.cs new file mode 100644 index 0000000..ff8e9e3 --- /dev/null +++ b/Runtime/Scripts/Dto/User.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace QonversionUnity +{ + public class User + { + public readonly string QonversionId; + [CanBeNull] public readonly string IdentityId; + + public User(string qonversionId, [CanBeNull] string identityId) + { + QonversionId = qonversionId; + IdentityId = identityId; + } + + public User(Dictionary dict) + { + if (dict.TryGetValue("qonversionId", out var qonversionId) && qonversionId != null) + { + QonversionId = qonversionId as string; + } + + if (dict.TryGetValue("identityId", out var identityId) && identityId != null) + { + IdentityId = identityId as string; + } + } + + public override string ToString() + { + return $"{nameof(QonversionId)}: {QonversionId}, " + + $"{nameof(IdentityId)}: {IdentityId}"; + } + } +} diff --git a/Runtime/Scripts/Dto/User.cs.meta b/Runtime/Scripts/Dto/User.cs.meta new file mode 100644 index 0000000..7eda00b --- /dev/null +++ b/Runtime/Scripts/Dto/User.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e90e3bc36aae4e069c0c373e53427b0c +timeCreated: 1668747828 \ No newline at end of file diff --git a/Runtime/Scripts/Models/UserProperty.cs b/Runtime/Scripts/Dto/UserProperty.cs similarity index 66% rename from Runtime/Scripts/Models/UserProperty.cs rename to Runtime/Scripts/Dto/UserProperty.cs index 6a569c8..46047a0 100644 --- a/Runtime/Scripts/Models/UserProperty.cs +++ b/Runtime/Scripts/Dto/UserProperty.cs @@ -4,12 +4,13 @@ public enum UserProperty { Email, Name, + KochavaDeviceId, AppsFlyerUserId, AdjustAdId, - KochavaDeviceId, CustomUserId, - FacebookAttribution, + FacebookAttribution, // Android only FirebaseAppInstanceId, - AppSetId + AppSetId, // Android only + AdvertisingId, // iOS only } } \ No newline at end of file diff --git a/Runtime/Scripts/Models/UserProperty.cs.meta b/Runtime/Scripts/Dto/UserProperty.cs.meta similarity index 100% rename from Runtime/Scripts/Models/UserProperty.cs.meta rename to Runtime/Scripts/Dto/UserProperty.cs.meta diff --git a/Runtime/Scripts/IAutomations.cs b/Runtime/Scripts/IAutomations.cs new file mode 100644 index 0000000..29d97aa --- /dev/null +++ b/Runtime/Scripts/IAutomations.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace QonversionUnity +{ + public interface IAutomations + { + /// + /// The Automations delegate is responsible for handling in-app screens and actions when push notification is received. + /// Make sure the method is called before Qonversion.handleNotification. + /// + /// The delegate to handle automations events + public void SetDelegate(AutomationsDelegate automationsDelegate); + + /// + /// Set push token to Qonversion to enable Qonversion push notifications + /// + /// Firebase device token for Android. APNs device token for iOS. + public void SetNotificationsToken(string token); + + /// + /// Call to handle push notifications sent by Qonversion Automations. + /// + /// notification payload data + /// true when a push notification was received from Qonversion. Otherwise, returns false, so you need to handle the notification yourself + /// Firebase RemoteMessage data + /// APNs notification data + public bool HandleNotification(Dictionary notification); + + /// + /// Get parsed custom payload, which you added to the notification in the dashboard + /// + /// notification payload data + /// a map with custom payload from the notification or null if it's not provided + [CanBeNull] + public Dictionary GetNotificationCustomPayload(Dictionary notification); + + /// + /// Show the screen using its ID. + /// + /// identifier of the screen which must be shown + /// callback that will be called when response is received + public void ShowScreen(string screenId, Automations.OnShowScreenResponseReceived callback); + } +} diff --git a/Runtime/Scripts/IAutomations.cs.meta b/Runtime/Scripts/IAutomations.cs.meta new file mode 100644 index 0000000..24849f2 --- /dev/null +++ b/Runtime/Scripts/IAutomations.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1bf6adea119149b5a8575fd688405c1d +timeCreated: 1670849785 \ No newline at end of file diff --git a/Runtime/Scripts/IQonversion.cs b/Runtime/Scripts/IQonversion.cs new file mode 100644 index 0000000..6536a31 --- /dev/null +++ b/Runtime/Scripts/IQonversion.cs @@ -0,0 +1,208 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace QonversionUnity +{ + public interface IQonversion + { + /// + /// This event will be fired when a user initiates a promotional in-app purchase from the App Store. + /// Declare a delegate for the event. + /// If you are not using the PromoPurchasesReceived event promo purchases will proceed automatically. + /// + public event Qonversion.OnPromoPurchasesReceived PromoPurchasesReceived; + + /// + /// This event will be fired for each asynchronous entitlements update, + /// for example, when a deferred transaction happens. + /// + public event Qonversion.OnUpdatedEntitlementsReceived UpdatedEntitlementsReceived; + + /// + /// Make a purchase and validate it through server-to-server using Qonversion's Backend. + /// + /// Qonversion product identifier for purchase. + /// Callback that will be called when response is received. + /// + public void Purchase(string productId, Qonversion.OnPurchaseResultReceived callback); + + /// + /// Make a purchase and validate it through server-to-server using Qonversion's Backend. + /// + /// Qonversion product for purchase. + /// Callback that will be called when response is received. + /// + public void PurchaseProduct([NotNull] Product product, Qonversion.OnPurchaseResultReceived callback); + + /// + /// Update (upgrade/downgrade) subscription and validate it through server-to-server using Qonversion's Backend. + /// + /// Qonversion product identifier for purchase + /// Qonversion product identifier from which the upgrade/downgrade will be initialized + /// Callback that will be called when response is received + /// Proration Mode + /// Proration Mode + /// Update Purchase + public void UpdatePurchase( + string productId, + string oldProductId, + Qonversion.OnPurchaseResultReceived callback, + ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy + ); + + /// + /// Update (upgrade/downgrade) subscription and validate it through server-to-server using Qonversion's Backend. + /// + /// Qonversion product for purchase + /// Qonversion product identifier from which the upgrade/downgrade will be initialized + /// Callback that will be called when response is received + /// Proration Mode + /// Proration Mode + /// Update Purchase + public void UpdatePurchaseWithProduct( + [NotNull] Product product, + string oldProductId, + Qonversion.OnPurchaseResultReceived callback, + ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy + ); + + /// + /// Returns Qonversion products in association with Apple and Google Play Store Products. + /// + /// Callback that will be called when response is received. + /// Product Center + public void Products(Qonversion.OnProductsReceived callback); + + /// + /// Return Qonversion Offerings Object. + /// + /// An offering is a group of products that you can offer to a user on a given paywall based on your business logic. + /// For example, you can offer one set of products on a paywall immediately after onboarding and another + /// set of products with discounts later on if a user has not converted. + /// Offerings allow changing the products offered remotely without releasing app updates. + /// + /// Offerings + /// Product Center + public void Offerings(Qonversion.OnOfferingsReceived callback); + + /// + /// You can check if a user is eligible for an introductory offer, including a free trial. + /// You can show only a regular price for users who are not eligible for an introductory offer. + /// + /// Products identifiers that must be checked. + /// Callback that will be called when response is received + public void CheckTrialIntroEligibility(IList productIds, Qonversion.OnEligibilitiesReceived callback); + + /// + /// You need to call the CheckEntitlements method at the start of your app to check if a user has the required + /// entitlement. + /// + /// This method will check the user receipt and will return the current entitlements. + /// + /// If Apple or Google servers are not responding at the time of the request, Qonversion provides the latest + /// entitlements data from its database. + /// + /// Callback that will be called when response is received + public void CheckEntitlements(Qonversion.OnEntitlementsReceived callback); + + /// + /// Restoring purchases restores users purchases in your app, to maintain access to purchased content. + /// Users sometimes need to restore purchased content, such as when they upgrade to a new phone. + /// + /// Callback that will be called when response is received + public void Restore(Qonversion.OnEntitlementsReceived callback); + + /// + /// This method will send all purchases to the Qonversion backend. Call this every time when purchase is handled + /// by your own implementation. + /// + /// //////Warning!////// + /// + /// This method works for Android only. + /// It should only be called if you're using Qonversion SDK in observer mode. + /// + /// Observer mode for Android SDK + public void SyncPurchases(); + + /// + /// Call this function to link a user to his unique ID in your system and share purchase data. + /// + /// An unique user ID in your system. + /// + public void Identify(string userID); + + /// + /// Call this function to unlink a user from his unique ID in your system and his purchase data. + /// + /// + public void Logout(); + + /// + /// This method returns information about the current Qonversion user. + /// + /// Callback that will be called when response is received + public void UserInfo(Qonversion.OnUserInfoReceived callback); + + /// + /// Sends your attribution data to the attribution source. + /// + /// An object containing your attribution data. + /// The attribution source to which the data will be sent. + public void Attribution( + Dictionary conversionData, + AttributionProvider attributionProvider + ); + + /// + /// Sends your attribution data to the attribution source. + /// + /// A json string containing your attribution data. + /// The attribution source to which the data will be sent. + public void Attribution(string conversionData, AttributionProvider attributionProvider); + + /// + /// Sets user property for pre-defined case property. + /// + /// User properties are attributes you can set on a user level. + /// You can send user properties to third party platforms as well as use them in Qonversion for customer segmentation + /// and analytics. + /// + /// Defined enum key that will be transformed to string. + /// Property value. + /// User Properties + public void SetProperty(UserProperty key, string value); + + /// + /// Adds custom user property. + /// + /// User properties are attributes you can set on a user level. + /// You can send user properties to third party platforms as well as use them in Qonversion for customer segmentation + /// and analytics. + /// + /// Custom user property key. + /// Property value. + /// User Properties + public void SetUserProperty(string key, string value); + + /// + /// iOS only. + /// On iOS 14.5+, after requesting the app tracking entitlement using ATT, you need to notify Qonversion if tracking + /// is allowed and IDFA is available. + /// + public void CollectAdvertisingId(); + + /// + /// Collecting Apple Search Ads attribution data. + /// + /// + public void CollectAppleSearchAdsAttribution(); + + /// + /// iOS only. + /// On iOS 14.0+ shows up a sheet for users to redeem AppStore offer codes. + /// + public void PresentCodeRedemptionSheet(); + + internal void InitializeInstance(QonversionConfig config); + } +} diff --git a/Runtime/Scripts/IQonversion.cs.meta b/Runtime/Scripts/IQonversion.cs.meta new file mode 100644 index 0000000..4c29c8a --- /dev/null +++ b/Runtime/Scripts/IQonversion.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9ded0a1938a14b2788563e72c5f7fbd6 +timeCreated: 1670849923 \ No newline at end of file diff --git a/Runtime/Scripts/IQonversionResultHandler.cs b/Runtime/Scripts/IQonversionResultHandler.cs deleted file mode 100644 index b057ae2..0000000 --- a/Runtime/Scripts/IQonversionResultHandler.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace QonversionUnity -{ - internal interface IQonversionResultHandler - { - void onSuccessInit(string uid); - - void onErrorInit(string errorMessage); - } -} \ No newline at end of file diff --git a/Runtime/Scripts/IQonversionResultHandler.cs.meta b/Runtime/Scripts/IQonversionResultHandler.cs.meta deleted file mode 100644 index 9e1310e..0000000 --- a/Runtime/Scripts/IQonversionResultHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0da42bd95a3b8ca4087c7fd255c437d5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Scripts/InitDelegate.cs b/Runtime/Scripts/InitDelegate.cs deleted file mode 100644 index c440e68..0000000 --- a/Runtime/Scripts/InitDelegate.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace QonversionUnity -{ - /// - /// Init delegate. - /// - public delegate void InitDelegate(); -} \ No newline at end of file diff --git a/Runtime/Scripts/InitEvent.cs b/Runtime/Scripts/InitEvent.cs deleted file mode 100644 index 36cb04e..0000000 --- a/Runtime/Scripts/InitEvent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using UnityEngine.Events; - -namespace QonversionUnity -{ - [System.Serializable] - public class InitEvent : UnityEvent - {} -} \ No newline at end of file diff --git a/Runtime/Scripts/InitEvent.cs.meta b/Runtime/Scripts/InitEvent.cs.meta deleted file mode 100644 index ec73118..0000000 --- a/Runtime/Scripts/InitEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e3083807ce0ef5d488edcd762c9afa93 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Scripts/Internal.meta b/Runtime/Scripts/Internal.meta new file mode 100644 index 0000000..43a7970 --- /dev/null +++ b/Runtime/Scripts/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 00384c60219c4bda98b08e4f7c65bc6f +timeCreated: 1668672384 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/AutomationsInternal.cs b/Runtime/Scripts/Internal/AutomationsInternal.cs new file mode 100644 index 0000000..e10235f --- /dev/null +++ b/Runtime/Scripts/Internal/AutomationsInternal.cs @@ -0,0 +1,161 @@ +using System.Collections.Generic; +using QonversionUnity.MiniJSON; +using UnityEngine; + +namespace QonversionUnity +{ + internal class AutomationsInternal : MonoBehaviour, IAutomations + { + private const string GameObjectName = "QonvesrionAutomationsRuntimeGameObject"; + private const string OnShowScreenMethodName = "OnShowScreen"; + + private IAutomationsWrapper _nativeWrapperInstance; + private AutomationsDelegate _automationsDelegate; + + private Automations.OnShowScreenResponseReceived ShowScreenResponseReceivedCallback { get; set; } + + public static AutomationsInternal CreateInstance() + { + GameObject go = new GameObject(GameObjectName); + AutomationsInternal instance = go.AddComponent(); + DontDestroyOnLoad(go); + + return instance; + } + + public void SetDelegate(AutomationsDelegate automationsDelegate) + { + _automationsDelegate = automationsDelegate; + + IAutomationsWrapper instance = GetNativeWrapper(); + instance.SubscribeOnAutomationEvents(); + } + + public void SetNotificationsToken(string token) + { + IAutomationsWrapper instance = GetNativeWrapper(); + instance.SetNotificationsToken(token); + } + + public bool HandleNotification(Dictionary notification) + { + IAutomationsWrapper instance = GetNativeWrapper(); + return instance.HandleNotification(notification.toJson()); + } + + public Dictionary GetNotificationCustomPayload(Dictionary notification) + { + IAutomationsWrapper instance = GetNativeWrapper(); + var payloadJson = instance.GetNotificationCustomPayload(notification.toJson()); + + if (payloadJson == null) + { + return null; + } + + if (!(Json.Deserialize(payloadJson) is Dictionary response)) + { + Debug.LogError("Could not parse custom notification payload."); + return null; + } + + return response; + } + + public void ShowScreen(string screenId, Automations.OnShowScreenResponseReceived callback) + { + ShowScreenResponseReceivedCallback = callback; + + IAutomationsWrapper instance = GetNativeWrapper(); + instance.ShowScreen(screenId, OnShowScreenMethodName); + } + + private IAutomationsWrapper GetNativeWrapper() + { + if (_nativeWrapperInstance != null) + { + return _nativeWrapperInstance; + } + + switch (Application.platform) + { + case RuntimePlatform.Android: + _nativeWrapperInstance = new AutomationsWrapperAndroid(); + break; + case RuntimePlatform.IPhonePlayer: + _nativeWrapperInstance = new AutomationsWrapperIOS(); + break; + default: + _nativeWrapperInstance = new AutomationsWrapperNoop(); + break; + } + _nativeWrapperInstance.Initialize(GameObjectName); + + return _nativeWrapperInstance; + } + + // The below methods are called from native when Automations events occur + private void OnAutomationsScreenShown(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + string screenId = Mapper.ScreenIdFromJson(jsonString); + + _automationsDelegate.OnAutomationsScreenShown(screenId); + } + + private void OnAutomationsActionStarted(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); + _automationsDelegate.OnAutomationsActionStarted(actionResult); + } + + private void OnAutomationsActionFailed(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); + _automationsDelegate.OnAutomationsActionFailed(actionResult); + } + + + private void OnAutomationsActionFinished(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); + _automationsDelegate.OnAutomationsActionFinished(actionResult); + } + + private void OnAutomationsFinished(string jsonString) + { + if (_automationsDelegate == null) + { + return; + } + + _automationsDelegate.OnAutomationsFinished(); + } + + private void OnShowScreen(string jsonString) + { + var error = Mapper.ErrorFromJson(jsonString); + ShowScreenResponseReceivedCallback(error); + ShowScreenResponseReceivedCallback = null; + } + } +} diff --git a/Runtime/Scripts/Internal/AutomationsInternal.cs.meta b/Runtime/Scripts/Internal/AutomationsInternal.cs.meta new file mode 100644 index 0000000..e936d9f --- /dev/null +++ b/Runtime/Scripts/Internal/AutomationsInternal.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c4a786ad04fb4a94b86844c34f317f23 +timeCreated: 1668753627 \ No newline at end of file diff --git a/Runtime/Scripts/Constants.cs b/Runtime/Scripts/Internal/Constants.cs similarity index 73% rename from Runtime/Scripts/Constants.cs rename to Runtime/Scripts/Internal/Constants.cs index 67b0cfc..e3bea8f 100644 --- a/Runtime/Scripts/Constants.cs +++ b/Runtime/Scripts/Internal/Constants.cs @@ -1,6 +1,6 @@ namespace QonversionUnity { - static class Constants + internal static class Constants { public const int SkuDetailsPriceRatio = 1000000; } diff --git a/Runtime/Scripts/Constants.cs.meta b/Runtime/Scripts/Internal/Constants.cs.meta similarity index 100% rename from Runtime/Scripts/Constants.cs.meta rename to Runtime/Scripts/Internal/Constants.cs.meta diff --git a/Runtime/Scripts/Mapper.cs b/Runtime/Scripts/Internal/Mapper.cs similarity index 76% rename from Runtime/Scripts/Mapper.cs rename to Runtime/Scripts/Internal/Mapper.cs index 035baf5..42e87a9 100644 --- a/Runtime/Scripts/Mapper.cs +++ b/Runtime/Scripts/Internal/Mapper.cs @@ -7,20 +7,6 @@ namespace QonversionUnity { internal class Mapper { - internal static string GetLifetimeKey(PermissionsCacheLifetime lifetime) { - var keys = new Dictionary() { - {PermissionsCacheLifetime.WEEK, "Week"}, - {PermissionsCacheLifetime.TWO_WEEKS, "TwoWeeks"}, - {PermissionsCacheLifetime.MONTH, "Month"}, - {PermissionsCacheLifetime.TWO_MONTHS, "TwoMonths"}, - {PermissionsCacheLifetime.THREE_MONTHS, "ThreeMonths"}, - {PermissionsCacheLifetime.SIX_MONTHS, "SixMonths"}, - {PermissionsCacheLifetime.YEAR, "Year"}, - {PermissionsCacheLifetime.UNLIMITED, "Unlimited"} - }; - return keys[lifetime]; - } - internal static bool GetIsCancelledFromJson(string jsonStr) { if (!(Json.Deserialize(jsonStr) is Dictionary result)) @@ -32,22 +18,22 @@ internal static bool GetIsCancelledFromJson(string jsonStr) return result.TryGetValue("isCancelled", out var isCancelled) && Convert.ToBoolean(isCancelled); } - internal static Dictionary PermissionsFromJson(string jsonStr) + internal static Dictionary EntitlementsFromJson(string jsonStr) { - var result = new Dictionary(); + var result = new Dictionary(); - if (!(Json.Deserialize(jsonStr) is Dictionary permissions)) + if (!(Json.Deserialize(jsonStr) is Dictionary entitlements)) { - Debug.LogError("Could not parse QPermissions"); + Debug.LogError("Could not parse QEntitlements"); return result; } - foreach (KeyValuePair permissionPair in permissions) + foreach (KeyValuePair entitlementPair in entitlements) { - if (permissionPair.Value is Dictionary permissionDict) + if (entitlementPair.Value is Dictionary entitlementDict) { - Permission permission = new Permission(permissionDict); - result.Add(permissionPair.Key, permission); + Entitlement entitlement = new Entitlement(entitlementDict); + result.Add(entitlementPair.Key, entitlement); } } @@ -131,6 +117,17 @@ internal static Dictionary EligibilitiesFromJson(string jso return result; } + internal static User UserFromJson(string jsonStr) + { + if (!(Json.Deserialize(jsonStr) is Dictionary userInfo)) + { + Debug.LogError("Could not parse User"); + return new User("", null); + } + + return new User(userInfo); + } + internal static QonversionError ErrorFromJson(string jsonStr) { if (!(Json.Deserialize(jsonStr) is Dictionary dict)) return null; diff --git a/Runtime/Scripts/Mapper.cs.meta b/Runtime/Scripts/Internal/Mapper.cs.meta similarity index 100% rename from Runtime/Scripts/Mapper.cs.meta rename to Runtime/Scripts/Internal/Mapper.cs.meta diff --git a/Runtime/Scripts/Internal/QonversionInternal.cs b/Runtime/Scripts/Internal/QonversionInternal.cs new file mode 100644 index 0000000..9d7afcb --- /dev/null +++ b/Runtime/Scripts/Internal/QonversionInternal.cs @@ -0,0 +1,453 @@ +using JetBrains.Annotations; +using QonversionUnity.MiniJSON; +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace QonversionUnity +{ + internal class QonversionInternal : MonoBehaviour, IQonversion + { + private const string GameObjectName = "QonvesrionRuntimeGameObject"; + private const string OnCheckEntitlementsMethodName = "OnCheckEntitlements"; + private const string OnPurchaseMethodName = "OnPurchase"; + private const string OnPromoPurchaseMethodName = "OnPromoPurchase"; + private const string OnPurchaseProductMethodName = "OnPurchaseProduct"; + private const string OnUpdatePurchaseMethodName = "OnUpdatePurchase"; + private const string OnUpdatePurchaseWithProductMethodName = "OnUpdatePurchaseWithProduct"; + private const string OnRestoreMethodName = "OnRestore"; + private const string OnProductsMethodName = "OnProducts"; + private const string OnOfferingsMethodName = "OnOfferings"; + private const string OnEligibilitiesMethodName = "OnEligibilities"; + private const string OnUserInfoMethodName = "OnUserInfo"; + + private const string SdkVersion = "3.7.1"; + private const string SdkSource = "unity"; + + private IQonversionWrapper _nativeWrapperInstance; + private Qonversion.OnUpdatedEntitlementsReceived _onUpdatedEntitlementsReceived; + + private Qonversion.OnPromoPurchasesReceived _onPromoPurchasesReceived; + private string _storedPromoProductId = null; + + private List CheckEntitlementsCallbacks { get; } = new List(); + private List RestoreCallbacks { get; } = new List(); + private Qonversion.OnPurchaseResultReceived PurchaseCallback { get; set; } + private Qonversion.OnPurchaseResultReceived PurchaseProductCallback { get; set; } + private Qonversion.OnPurchaseResultReceived UpdatePurchaseCallback { get; set; } + private Qonversion.OnPurchaseResultReceived UpdatePurchaseWithProductCallback { get; set; } + private List ProductsCallbacks { get; } = new List(); + private List OfferingsCallbacks { get; } = new List(); + private Qonversion.OnEligibilitiesReceived EligibilitiesCallback { get; set; } + private Qonversion.OnEntitlementsReceived PromoPurchaseCallback { get; set; } + private Qonversion.OnUserInfoReceived UserInfoCallback { get; set; } + + public event Qonversion.OnPromoPurchasesReceived PromoPurchasesReceived + { + add + { + _onPromoPurchasesReceived += value; + } + remove + { + _onPromoPurchasesReceived -= value; + } + } + + public event Qonversion.OnUpdatedEntitlementsReceived UpdatedEntitlementsReceived + { + add + { + _onUpdatedEntitlementsReceived += value; + } + remove + { + _onUpdatedEntitlementsReceived -= value; + } + } + + public static QonversionInternal CreateInstance() + { + GameObject go = new GameObject(GameObjectName); + QonversionInternal instance = go.AddComponent(); + DontDestroyOnLoad(go); + + return instance; + } + + void IQonversion.InitializeInstance(QonversionConfig config) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.StoreSdkInfo(SdkVersion, SdkSource); + + string launchModeKey = Enum.GetName(typeof(LaunchMode), config.LaunchMode); + string environmentKey = Enum.GetName(typeof(Environment), config.Environment); + string cacheLifetimeKey = Enum.GetName(typeof(EntitlementsCacheLifetime), config.EntitlementsCacheLifetime); + + instance.InitializeSdk(config.ProjectKey, launchModeKey, environmentKey, cacheLifetimeKey); + } + + public void Purchase(string productId, Qonversion.OnPurchaseResultReceived callback) + { + PurchaseCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.Purchase(productId, OnPurchaseMethodName); + } + + public void PurchaseProduct([NotNull] Product product, Qonversion.OnPurchaseResultReceived callback) + { + if (product == null) + { + callback(null, new QonversionError("PurchaseInvalid", "Product is null"), false); + return; + } + + PurchaseProductCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.PurchaseProduct(product.QonversionId, product.OfferingId, OnPurchaseProductMethodName); + } + + public void UpdatePurchase(string productId, string oldProductId, Qonversion.OnPurchaseResultReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) + { + UpdatePurchaseCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.UpdatePurchase(productId, oldProductId, prorationMode, OnUpdatePurchaseMethodName); + } + + public void UpdatePurchaseWithProduct([NotNull] Product product, string oldProductId, Qonversion.OnPurchaseResultReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) + { + if (product == null) + { + callback(null, new QonversionError("PurchaseInvalid", "Product is null"), false); + return; + } + + UpdatePurchaseWithProductCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.UpdatePurchaseWithProduct(product.QonversionId, product.OfferingId, oldProductId, prorationMode, OnUpdatePurchaseWithProductMethodName); + } + + public void Products(Qonversion.OnProductsReceived callback) + { + ProductsCallbacks.Add(callback); + IQonversionWrapper instance = GetNativeWrapper(); + instance.Products(OnProductsMethodName); + } + + public void Offerings(Qonversion.OnOfferingsReceived callback) + { + OfferingsCallbacks.Add(callback); + IQonversionWrapper instance = GetNativeWrapper(); + instance.Offerings(OnOfferingsMethodName); + } + + public void CheckTrialIntroEligibility(IList productIds, Qonversion.OnEligibilitiesReceived callback) + { + var productIdsJson = Json.Serialize(productIds); + + EligibilitiesCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.CheckTrialIntroEligibility(productIdsJson, OnEligibilitiesMethodName); + } + + public void CheckEntitlements(Qonversion.OnEntitlementsReceived callback) + { + CheckEntitlementsCallbacks.Add(callback); + IQonversionWrapper instance = GetNativeWrapper(); + instance.CheckEntitlements(OnCheckEntitlementsMethodName); + } + + public void Restore(Qonversion.OnEntitlementsReceived callback) + { + RestoreCallbacks.Add(callback); + IQonversionWrapper instance = GetNativeWrapper(); + instance.Restore(OnRestoreMethodName); + } + + public void SyncPurchases() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SyncPurchases(); + } + + public void Identify(string userID) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.Identify(userID); + } + + public void Logout() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.Logout(); + } + + public void UserInfo(Qonversion.OnUserInfoReceived callback) + { + UserInfoCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.UserInfo(OnUserInfoMethodName); + } + + public void Attribution(Dictionary conversionData, AttributionProvider attributionProvider) + { + Attribution(conversionData.toJson(), attributionProvider); + } + + public void Attribution(string conversionData, AttributionProvider attributionProvider) + { + string providerName = Enum.GetName(typeof(AttributionProvider), attributionProvider); + + IQonversionWrapper instance = GetNativeWrapper(); + + instance.AddAttributionData(conversionData, providerName); + } + + public void SetProperty(UserProperty key, string value) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SetProperty(key, value); + } + + public void SetUserProperty(string key, string value) + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SetUserProperty(key, value); + } + + public void CollectAdvertisingId() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SetAdvertisingID(); + } + + public void CollectAppleSearchAdsAttribution() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.SetAppleSearchAdsAttributionEnabled(true); + } + + public void PresentCodeRedemptionSheet() + { + IQonversionWrapper instance = GetNativeWrapper(); + instance.PresentCodeRedemptionSheet(); + } + + // Called from the native SDK - Called when entitlements received from the checkEntitlements() method + private void OnCheckEntitlements(string jsonString) + { + HandleEntitlements(CheckEntitlementsCallbacks, jsonString); + CheckEntitlementsCallbacks.Clear(); + } + + // Called from the native SDK - Called when purchase result received from the purchase() method + private void OnPurchase(string jsonString) + { + HandlePurchaseResult(PurchaseCallback, jsonString); + PurchaseCallback = null; + } + + // Called from the native SDK - Called when purchase result received from the purchaseProduct() method + private void OnPurchaseProduct(string jsonString) + { + HandlePurchaseResult(PurchaseProductCallback, jsonString); + PurchaseProductCallback = null; + } + + // Called from the native SDK - Called when entitlements received from the restore() method + private void OnRestore(string jsonString) + { + HandleEntitlements(RestoreCallbacks, jsonString); + RestoreCallbacks.Clear(); + } + + // Called from the native SDK - Called when purchase result received from the updatePurchase() method + private void OnUpdatePurchase(string jsonString) + { + HandlePurchaseResult(UpdatePurchaseCallback, jsonString); + UpdatePurchaseCallback = null; + } + + // Called from the native SDK - Called when purchase result received from the updatePurchaseWithProduct() method + private void OnUpdatePurchaseWithProduct(string jsonString) + { + HandlePurchaseResult(UpdatePurchaseWithProductCallback, jsonString); + UpdatePurchaseWithProductCallback = null; + } + + // Called from the native SDK - Called when entitlements received from the promoPurchase() method + private void OnPromoPurchase(string jsonString) + { + if (PromoPurchaseCallback != null) { + var callbacks = new List { PromoPurchaseCallback }; + HandleEntitlements(callbacks, jsonString); + } + + PromoPurchaseCallback = null; + _storedPromoProductId = null; + } + + // Called from the native SDK - Called when products received from the products() method + private void OnProducts(string jsonString) + { + if (ProductsCallbacks.Count == 0) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + ProductsCallbacks.ForEach(callback => callback(null, error)); + } + else + { + var products = Mapper.ProductsFromJson(jsonString); + ProductsCallbacks.ForEach(callback => callback(products, null)); + } + + ProductsCallbacks.Clear(); + } + + // Called from the native SDK - Called when offerings received from the offerings() method + private void OnOfferings(string jsonString) + { + if (OfferingsCallbacks.Count == 0) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + OfferingsCallbacks.ForEach(callback => callback(null, error)); + } + else + { + var offerings = Mapper.OfferingsFromJson(jsonString); + OfferingsCallbacks.ForEach(callback => callback(offerings, null)); + } + + OfferingsCallbacks.Clear(); + } + + // Called from the native SDK - Called when eligibilities received from the checkTrialIntroEligibilityForProductIds() method + private void OnEligibilities(string jsonString) + { + if (EligibilitiesCallback == null) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + EligibilitiesCallback(null, error); + } + else + { + Dictionary eligibilities = Mapper.EligibilitiesFromJson(jsonString); + EligibilitiesCallback(eligibilities, null); + } + + EligibilitiesCallback = null; + } + + // Called from the native SDK - Called when user info received from the UserInfo() method + private void OnUserInfo(string jsonString) + { + if (UserInfoCallback == null) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + UserInfoCallback(null, error); + } + else + { + User userInfo = Mapper.UserFromJson(jsonString); + UserInfoCallback(userInfo, null); + } + + UserInfoCallback = null; + } + + // Called from the native SDK - Called when entitlements update. For example, when pending purchases like SCA, Ask to buy, etc., happen. + private void OnReceivedUpdatedEntitlements(string jsonString) + { + if (_onUpdatedEntitlementsReceived == null) + { + return; + } + + Dictionary entitlements = Mapper.EntitlementsFromJson(jsonString); + _onUpdatedEntitlementsReceived(entitlements); + } + + private void OnReceivePromoPurchase(string storeProductId) + { + if (_onPromoPurchasesReceived == null) + { + return; + } + + _storedPromoProductId = storeProductId; + _onPromoPurchasesReceived(storeProductId, PromoPurchase); + } + + private void PromoPurchase(Qonversion.OnEntitlementsReceived callback) + { + PromoPurchaseCallback = callback; + IQonversionWrapper instance = GetNativeWrapper(); + instance.PromoPurchase(_storedPromoProductId, OnPromoPurchaseMethodName); + } + + private void HandleEntitlements(List callbacks, string jsonString) + { + if (callbacks.Count == 0) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + callbacks.ForEach(callback => callback(null, error)); + } + else + { + var entitlements = Mapper.EntitlementsFromJson(jsonString); + callbacks.ForEach(callback => callback(entitlements, null)); + } + } + + private void HandlePurchaseResult(Qonversion.OnPurchaseResultReceived callback, string jsonString) + { + if (callback == null) return; + + var error = Mapper.ErrorFromJson(jsonString); + if (error != null) + { + var isCancelled = Mapper.GetIsCancelledFromJson(jsonString); + callback(null, error, isCancelled); + } + else + { + var entitlements = Mapper.EntitlementsFromJson(jsonString); + callback(entitlements, null, false); + } + } + + private IQonversionWrapper GetNativeWrapper() + { + if (_nativeWrapperInstance != null) + { + return _nativeWrapperInstance; + } + + switch (Application.platform) + { + case RuntimePlatform.Android: + _nativeWrapperInstance = new QonversionWrapperAndroid(); + break; + case RuntimePlatform.IPhonePlayer: + _nativeWrapperInstance = new QonversionWrapperIOS(); + break; + default: + _nativeWrapperInstance = new QonversionWrapperNoop(); + break; + } + _nativeWrapperInstance.Initialize(GameObjectName); + + return _nativeWrapperInstance; + } + } +} diff --git a/Runtime/Scripts/InitDelegate.cs.meta b/Runtime/Scripts/Internal/QonversionInternal.cs.meta similarity index 83% rename from Runtime/Scripts/InitDelegate.cs.meta rename to Runtime/Scripts/Internal/QonversionInternal.cs.meta index 3fe0152..3d73b36 100644 --- a/Runtime/Scripts/InitDelegate.cs.meta +++ b/Runtime/Scripts/Internal/QonversionInternal.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 67b89adb9ad50f74a8161204ac657b36 +guid: 38c50778583feeb4da0934f2fa914b96 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/Scripts/Utils.cs b/Runtime/Scripts/Internal/Utils.cs similarity index 100% rename from Runtime/Scripts/Utils.cs rename to Runtime/Scripts/Internal/Utils.cs diff --git a/Runtime/Scripts/Utils.cs.meta b/Runtime/Scripts/Internal/Utils.cs.meta similarity index 100% rename from Runtime/Scripts/Utils.cs.meta rename to Runtime/Scripts/Internal/Utils.cs.meta diff --git a/Runtime/Scripts/Internal/wrappers.meta b/Runtime/Scripts/Internal/wrappers.meta new file mode 100644 index 0000000..7be01f6 --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bc8c98aad7534db3bf2a3733e1e9b9eb +timeCreated: 1668776043 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations.meta b/Runtime/Scripts/Internal/wrappers/automations.meta new file mode 100644 index 0000000..5c9d6fa --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d39ad171d37c4033a7b7a4c23c0ea18a +timeCreated: 1668776048 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs b/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs new file mode 100644 index 0000000..8929d12 --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs @@ -0,0 +1,31 @@ +namespace QonversionUnity +{ + internal class AutomationsWrapperNoop : IAutomationsWrapper + { + public void Initialize(string gameObjectName) + { + } + + public void SetNotificationsToken(string token) + { + } + + public bool HandleNotification(string notification) + { + return false; + } + + public string GetNotificationCustomPayload(string notification) + { + return null; + } + + public void SubscribeOnAutomationEvents() + { + } + + public void ShowScreen(string screenId, string callbackName) + { + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta b/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta new file mode 100644 index 0000000..94ad546 --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 52b5b093639a4d04ab569175864e233a +timeCreated: 1668776080 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs b/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs new file mode 100644 index 0000000..af52d4c --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs @@ -0,0 +1,14 @@ +using JetBrains.Annotations; + +namespace QonversionUnity +{ + internal interface IAutomationsWrapper + { + void Initialize(string gameObjectName); + void SetNotificationsToken(string token); + bool HandleNotification(string notification); + [CanBeNull] string GetNotificationCustomPayload(string notification); + void SubscribeOnAutomationEvents(); + void ShowScreen(string screenId, string callbackName); + } +} diff --git a/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta b/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta new file mode 100644 index 0000000..317587d --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/automations/IAutomationsWrapper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e55580a6da23457280c02026ad96b05d +timeCreated: 1668776004 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/qonversion.meta b/Runtime/Scripts/Internal/wrappers/qonversion.meta new file mode 100644 index 0000000..8c5f0cb --- /dev/null +++ b/Runtime/Scripts/Internal/wrappers/qonversion.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b14757828b514a959d4e299c27c50782 +timeCreated: 1668776059 \ No newline at end of file diff --git a/Runtime/Scripts/IQonversionWrapper.cs b/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs similarity index 73% rename from Runtime/Scripts/IQonversionWrapper.cs rename to Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs index 4c31e5f..72b9be1 100644 --- a/Runtime/Scripts/IQonversionWrapper.cs +++ b/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs @@ -5,14 +5,13 @@ namespace QonversionUnity internal interface IQonversionWrapper { void Initialize(string gameObjectName); + void InitializeSdk(string projectKey, string launchMode, [CanBeNull] string environment, [CanBeNull] string entitlementsCacheLifetime); void StoreSdkInfo(string version, string source); - void SetDebugMode(); void SetAdvertisingID(); - void InitializeSdk(string projectKey, bool observerMode, string callbackName); void SetUserProperty(string key, string value); void SetProperty(UserProperty key, string value); void SyncPurchases(); - void AddAttributionData(string conversionData, AttributionSource source); + void AddAttributionData(string conversionData, string providerName); void CheckEntitlements(string callbackName); void Purchase(string productId, string callbackName); void PurchaseProduct(string productId, string offeringId, string callbackName); @@ -25,12 +24,8 @@ internal interface IQonversionWrapper void SetAppleSearchAdsAttributionEnabled(bool enable); void Identify(string userID); void Logout(); + void UserInfo(string callbackName); void PromoPurchase(string storeProductId, string callbackName); - void SetNotificationsToken(string token); - bool HandleNotification(string notification); - [CanBeNull] string GetNotificationCustomPayload(string notification); - void SubscribeOnAutomationEvents(); void PresentCodeRedemptionSheet(); - void SetPermissionsCacheLifetime(string lifetime); } } \ No newline at end of file diff --git a/Runtime/Scripts/IQonversionWrapper.cs.meta b/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs.meta similarity index 100% rename from Runtime/Scripts/IQonversionWrapper.cs.meta rename to Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs.meta diff --git a/Runtime/Scripts/QonversionWrapperNoop.cs b/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs similarity index 73% rename from Runtime/Scripts/QonversionWrapperNoop.cs rename to Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs index f0b2cb2..d27f65e 100644 --- a/Runtime/Scripts/QonversionWrapperNoop.cs +++ b/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs @@ -1,15 +1,12 @@ namespace QonversionUnity - { +{ internal class QonversionWrapperNoop : IQonversionWrapper { public void Initialize(string gameObjectName) { } - public void InitializeSdk(string projectKey, bool observerMode, string callbackName) - { - } - public void SetDebugMode() + public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime) { } @@ -21,7 +18,7 @@ public void SetProperty(UserProperty key, string value) { } - public void AddAttributionData(string conversionData, AttributionSource source) + public void AddAttributionData(string conversionData, string providerName) { } @@ -85,35 +82,16 @@ public void Logout() { } - public void PromoPurchase(string storeProductId, string callbackName) - { - } - - public void SetNotificationsToken(string token) - { - } - - public bool HandleNotification(string notification) + public void UserInfo(string callbackName) { - return false; } - public string GetNotificationCustomPayload(string notification) - { - return null; - } - - public void SubscribeOnAutomationEvents() - { + public void PromoPurchase(string storeProductId, string callbackName) + { } public void PresentCodeRedemptionSheet() { } - - public void SetPermissionsCacheLifetime(string lifetime) - { - - } } - } \ No newline at end of file +} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionWrapperNoop.cs.meta b/Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs.meta similarity index 100% rename from Runtime/Scripts/QonversionWrapperNoop.cs.meta rename to Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs.meta diff --git a/Runtime/Scripts/Models/PermissionsCacheLifetime.cs b/Runtime/Scripts/Models/PermissionsCacheLifetime.cs deleted file mode 100644 index 2560404..0000000 --- a/Runtime/Scripts/Models/PermissionsCacheLifetime.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace QonversionUnity -{ - public enum PermissionsCacheLifetime - { - WEEK, - TWO_WEEKS, - MONTH, - TWO_MONTHS, - THREE_MONTHS, - SIX_MONTHS, - YEAR, - UNLIMITED - } -} \ No newline at end of file diff --git a/Runtime/Scripts/Qonversion.cs b/Runtime/Scripts/Qonversion.cs index 9814d0f..e3d2129 100644 --- a/Runtime/Scripts/Qonversion.cs +++ b/Runtime/Scripts/Qonversion.cs @@ -1,816 +1,80 @@ -using JetBrains.Annotations; -using QonversionUnity.MiniJSON; using System; using System.Collections.Generic; -using UnityEngine; +using JetBrains.Annotations; namespace QonversionUnity { - public class Qonversion : MonoBehaviour + public static class Qonversion { - public delegate void OnPurchaseResultReceived(Dictionary permissions, QonversionError error, bool isCancelled); - public delegate void OnPermissionsReceived(Dictionary permissions, QonversionError error); - public delegate void OnProductsReceived(Dictionary products, QonversionError error); - public delegate void OnOfferingsReceived(Offerings offerings, QonversionError error); - public delegate void OnEligibilitiesReceived(Dictionary eligibilities, QonversionError error); - - /// - /// Delegate fires each time a promo purchase from the App Store happens. - /// Be sure you define a delegate for the event . - /// Call StartPromoPurchase in case of your app is ready to start promo purchase. - /// Or cache that delegate and call later when you need. - /// - /// StoreKit product identifier - /// A delegate that will start a promo purchase flow. - /// - /// - public delegate void OnPromoPurchasesReceived(string productId, StartPromoPurchase purchaseDelegate); - - /// - /// Call the function if your app can handle a promo purchase at the current time. - /// Or you can cache the delegate, and call it when the app is ready to make the purchase. - /// - /// Callback that will be called when response is received. Returns permissions or potentially a QonversionError. - /// - /// - public delegate void StartPromoPurchase(OnPermissionsReceived callback); - - /// - /// Delegate fires each time a user entitlements change asynchronously, - /// for example, when a deferred transaction happens. - /// - public delegate void OnUpdatedEntitlementsReceived(Dictionary permissions); - - private const string GameObjectName = "QonvesrionRuntimeGameObject"; - private const string OnLaunchMethodName = "OnLaunch"; - private const string OnCheckPermissionsMethodName = "OnCheckPermissions"; - private const string OnPurchaseMethodName = "OnPurchase"; - private const string OnPromoPurchaseMethodName = "OnPromoPurchase"; - private const string OnPurchaseProductMethodName = "OnPurchaseProduct"; - private const string OnUpdatePurchaseMethodName = "OnUpdatePurchase"; - private const string OnUpdatePurchaseWithProductMethodName = "OnUpdatePurchaseWithProduct"; - private const string OnRestoreMethodName = "OnRestore"; - private const string OnProductsMethodName = "OnProducts"; - private const string OnOfferingsMethodName = "OnOfferings"; - private const string OnEligibilitiesMethodName = "OnEligibilities"; - - private const string SdkVersion = "3.7.1"; - private const string SdkSource = "unity"; - - private static IQonversionWrapper _Instance; - private static OnUpdatedEntitlementsReceived _onUpdatedEntitlementsReceived; - - private static OnPromoPurchasesReceived _onPromoPurchasesReceived; - private static string _storedPromoProductId = null; - private static AutomationsDelegate _automationsDelegate; - - private static List CheckPermissionsCallbacks { get; } = new List(); - private static List RestoreCallbacks { get; } = new List(); - private static OnPurchaseResultReceived PurchaseCallback { get; set; } - private static OnPurchaseResultReceived PurchaseProductCallback { get; set; } - private static OnPurchaseResultReceived UpdatePurchaseCallback { get; set; } - private static OnPurchaseResultReceived UpdatePurchaseWithProductCallback { get; set; } - private static List ProductsCallbacks { get; } = new List(); - private static List OfferingsCallbacks { get; } = new List(); - private static OnEligibilitiesReceived EligibilitiesCallback { get; set; } - private static OnPermissionsReceived PromoPurchaseCallback { get; set; } - - private static IQonversionWrapper getFinalInstance() - { - if (_Instance == null) - { - switch (Application.platform) - { - case RuntimePlatform.Android: - _Instance = new QonversionWrapperAndroid(); - break; - case RuntimePlatform.IPhonePlayer: - _Instance = new QonversionWrapperIOS(); - break; - default: - _Instance = new QonversionWrapperNoop(); - break; - } - _Instance.Initialize(GameObjectName); - - GameObject go = new GameObject(GameObjectName); - go.AddComponent(); - DontDestroyOnLoad(go); - } - - return _Instance; - } - - /// - /// This event will be fired when a user initiates a promotional in-app purchase from the App Store. - /// Declare a delegate for the event. - /// If you are not using the PromoPurchasesReceived event promo purchases will proceed automatically. - /// - public static event OnPromoPurchasesReceived PromoPurchasesReceived - { - add - { - _onPromoPurchasesReceived += value; - } - remove - { - _onPromoPurchasesReceived -= value; - } - } - - /// - /// This event will be fired for each asynchronous entitlements update, - /// for example, when a deferred transaction happens. - /// - public static event OnUpdatedEntitlementsReceived UpdatedEntitlementsReceived - { - add - { - _onUpdatedEntitlementsReceived += value; - } - remove - { - _onUpdatedEntitlementsReceived -= value; - } - } - - internal static void SetAutomationsDelegate(AutomationsDelegate automationsDelegate) - { - _automationsDelegate = automationsDelegate; - - IQonversionWrapper instance = getFinalInstance(); - instance.SubscribeOnAutomationEvents(); - } - - /// - /// Initializes Qonversion SDK with the given API key. - /// You can get one in your account on https://dash.qonversion.io. - /// - /// Project key to setup the SDK. - /// Set true if you are using observer mode only. - /// Observer mode - /// Installing the Android SDK - public static void Launch(string apiKey, bool observerMode) - { - IQonversionWrapper instance = getFinalInstance(); - instance.StoreSdkInfo(SdkVersion, SdkSource); - instance.InitializeSdk(apiKey, observerMode, OnLaunchMethodName); - } - - /// - /// You can set the flag to distinguish sandbox and production users. - /// To see the sandbox users turn on the Viewing test Data toggle on Qonversion Dashboard - /// - public static void SetDebugMode() - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetDebugMode(); - } - - /// - /// iOS only. - /// On iOS 14.5+, after requesting the app tracking permission using ATT, you need to notify Qonversion if tracking - /// is allowed and IDFA is available. - /// - public static void SetAdvertisingID() - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetAdvertisingID(); - } - - /// - /// Qonversion SDK provides an asynchronous method to set your side User ID that can be used to match users in - /// third-party integrations. - /// - /// Your database user ID. - /// User Identifiers - [Obsolete("Deprecated. Will be removed in a future major release. Use SetProperty(UserProperty.CustomUserId, value) instead.")] - public static void SetUserID(string userID) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetProperty(UserProperty.CustomUserId, userID); - } - - /// - /// Adds custom user property. - /// - /// User properties are attributes you can set on a user level. - /// You can send user properties to third party platforms as well as use them in Qonversion for customer segmentation - /// and analytics. - /// - /// Custom user property key. - /// Property value. - /// User Properties - public static void SetUserProperty(string key, string value) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetUserProperty(key, value); - } - - /// - /// Sets user property for pre-defined case property. - /// - /// User properties are attributes you can set on a user level. - /// You can send user properties to third party platforms as well as use them in Qonversion for customer segmentation - /// and analytics. - /// - /// Defined enum key that will be transformed to string. - /// Property value. - /// User Properties - public static void SetProperty(UserProperty key, string value) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetProperty(key, value); - } - - /// - /// This method will send all purchases to the Qonversion backend. Call this every time when purchase is handled - /// by your own implementation. - /// - /// //////Warning!////// - /// - /// This method works for Android only. - /// It should only be called if you're using Qonversion SDK in observer mode. - /// - /// Observer mode for Android SDK - public static void SyncPurchases() - { - IQonversionWrapper instance = getFinalInstance(); - instance.SyncPurchases(); - } - - /// - /// iOS only. - /// On iOS 14.0+ shows up a sheet for users to redeem AppStore offer codes. - /// - public static void PresentCodeRedemptionSheet() - { - IQonversionWrapper instance = getFinalInstance(); - instance.PresentCodeRedemptionSheet(); - } - - /// - /// Sends your attribution data to the attribution source. - /// - /// An object containing your attribution data. - /// The attribution source to which the data will be sent. - public static void AddAttributionData(Dictionary conversionData, AttributionSource attributionSource) - { - AddAttributionData(conversionData.toJson(), attributionSource); - } - - /// - /// Sends your attribution data to the attribution source. - /// - /// A json string containing your attribution data. - /// The attribution source to which the data will be sent. - public static void AddAttributionData(string conversionData, AttributionSource attributionSource) - { - IQonversionWrapper instance = getFinalInstance(); - - instance.AddAttributionData(conversionData, attributionSource); - } - - /// - /// Enable collecting Apple Search Ads attribution data. "false" by default. - /// - /// A bool value indicating whether Qonversion should collect attribution from Apple Search Ads. - /// - public static void SetAppleSearchAdsAttributionEnabled(bool enable) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetAppleSearchAdsAttributionEnabled(enable); - } - - /// - /// Call this function to link a user to his unique ID in your system and share purchase data. - /// - /// An unique user ID in your system. - /// - public static void Identify(string userID) - { - IQonversionWrapper instance = getFinalInstance(); - instance.Identify(userID); - } - - /// - /// Call this function to unlink a user from his unique ID in your system and his purchase data. - /// - /// - public static void Logout() - { - IQonversionWrapper instance = getFinalInstance(); - instance.Logout(); - } - - /// - /// You need to call the CheckPermissions method at the start of your app to check if a user has the required - /// permission. - /// - /// This method will check the user receipt and will return the current permissions. - /// - /// If Apple or Google servers are not responding at the time of the request, Qonversion provides the latest - /// permissions data from its database. - /// - /// Callback that will be called when response is received - public static void CheckPermissions(OnPermissionsReceived callback) - { - CheckPermissionsCallbacks.Add(callback); - IQonversionWrapper instance = getFinalInstance(); - instance.CheckEntitlements(OnCheckPermissionsMethodName); - } - - /// - /// Make a purchase and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product identifier for purchase. - /// Callback that will be called when response is received. - /// - [Obsolete("Purchase with OnPermissionsReceived callback is deprecated. Consider using Purchase with OnPurchaseResultReceivedCallback instead.")] - public static void Purchase(string productId, OnPermissionsReceived callback) - { - var convertedCallback = ConvertPermissionsCallbackToPurchaseResultCallback(callback); - Purchase(productId, convertedCallback); - } - - /// - /// Make a purchase and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product identifier for purchase. - /// Callback that will be called when response is received. - /// - public static void Purchase(string productId, OnPurchaseResultReceived callback) - { - PurchaseCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.Purchase(productId, OnPurchaseMethodName); - } - - /// - /// Make a purchase and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product for purchase. - /// Callback that will be called when response is received. - /// - [Obsolete("PurchaseProduct with OnPermissionsReceived callback is deprecated. Consider using PurchaseProduct with OnPurchaseResultReceivedCallback instead.")] - public static void PurchaseProduct([NotNull] Product product, OnPermissionsReceived callback) - { - var convertedCallback = ConvertPermissionsCallbackToPurchaseResultCallback(callback); - PurchaseProduct(product, convertedCallback); - } + [CanBeNull] private static IQonversion _backingInstance; /// - /// Make a purchase and validate that through server-to-server using Qonversion's Backend. + /// Use this variable to get a current initialized instance of the Qonversion SDK. + /// Please, use the property only after calling . + /// Otherwise, trying to access the variable will cause an exception. /// - /// Qonversion product for purchase. - /// Callback that will be called when response is received. - /// - public static void PurchaseProduct([NotNull] Product product, OnPurchaseResultReceived callback) + /// Current initialized instance of the Qonversion SDK. + /// throws exception if the instance has not been initialized + public static IQonversion GetSharedInstance() { - if (product == null) + if (_backingInstance == null) { - callback(null, new QonversionError("PurchaseInvalid", "Product is null"), false); - return; + throw new Exception( + "Qonversion has not been initialized. You should call " + + "the initialize method before accessing the shared instance of Qonversion." + ); } - PurchaseProductCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.PurchaseProduct(product.QonversionId, product.OfferingId, OnPurchaseProductMethodName); - } - - /// - /// Restoring purchases restores users purchases in your app, to maintain access to purchased content. - /// Users sometimes need to restore purchased content, such as when they upgrade to a new phone. - /// - /// Callback that will be called when response is received - public static void Restore(OnPermissionsReceived callback) - { - RestoreCallbacks.Add(callback); - IQonversionWrapper instance = getFinalInstance(); - instance.Restore(OnRestoreMethodName); + return _backingInstance; } /// - /// Update (upgrade/downgrade) subscription and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product identifier for purchase - /// Qonversion product identifier from which the upgrade/downgrade will be initialized - /// Callback that will be called when response is received - /// Proration Mode - /// Proration Mode - /// Update Purchase - [Obsolete("UpdatePurchase with OnPermissionsReceived callback is deprecated. Consider using UpdatePurchase with OnPurchaseResultReceivedCallback instead.")] - public static void UpdatePurchase(string productId, string oldProductId, OnPermissionsReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) - { - var convertedCallback = ConvertPermissionsCallbackToPurchaseResultCallback(callback); - UpdatePurchase(productId, oldProductId, convertedCallback, prorationMode); - } - - /// - /// Update (upgrade/downgrade) subscription and validate that through server-to-server using Qonversion's Backend. + /// An entry point to use Qonversion SDK. Call to initialize Qonversion SDK with required and extra configs. + /// The function is the best way to set additional configs you need to use Qonversion SDK. + /// You still have an option to set a part of additional configs later via calling separate setters. /// - /// Qonversion product identifier for purchase - /// Qonversion product identifier from which the upgrade/downgrade will be initialized - /// Callback that will be called when response is received - /// Proration Mode - /// Proration Mode - /// Update Purchase - public static void UpdatePurchase(string productId, string oldProductId, OnPurchaseResultReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) + /// a config that contains key SDK settings. + /// Call to configure and create a QonversionConfig instance. + /// Initialized instance of the Qonversion SDK. + public static IQonversion Initialize(QonversionConfig config) { - UpdatePurchaseCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.UpdatePurchase(productId, oldProductId, prorationMode, OnUpdatePurchaseMethodName); + _backingInstance = QonversionInternal.CreateInstance(); + _backingInstance?.InitializeInstance(config); + return _backingInstance; } - /// - /// Update (upgrade/downgrade) subscription and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product for purchase - /// Qonversion product identifier from which the upgrade/downgrade will be initialized - /// Callback that will be called when response is received - /// Proration Mode - /// Proration Mode - /// Update Purchase - [Obsolete("UpdatePurchaseWithProduct with OnPermissionsReceived callback is deprecated. Consider using UpdatePurchaseWithProduct with OnPurchaseResultReceivedCallback instead.")] - public static void UpdatePurchaseWithProduct([NotNull] Product product, string oldProductId, OnPermissionsReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) - { - var convertedCallback = ConvertPermissionsCallbackToPurchaseResultCallback(callback); - UpdatePurchaseWithProduct(product, oldProductId, convertedCallback, prorationMode); - } - - /// - /// Update (upgrade/downgrade) subscription and validate that through server-to-server using Qonversion's Backend. - /// - /// Qonversion product for purchase - /// Qonversion product identifier from which the upgrade/downgrade will be initialized - /// Callback that will be called when response is received - /// Proration Mode - /// Proration Mode - /// Update Purchase - public static void UpdatePurchaseWithProduct([NotNull] Product product, string oldProductId, OnPurchaseResultReceived callback, ProrationMode prorationMode = ProrationMode.UnknownSubscriptionUpgradeDowngradePolicy) - { - if (product == null) - { - callback(null, new QonversionError("PurchaseInvalid", "Product is null"), false); - return; - } - - UpdatePurchaseWithProductCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.UpdatePurchaseWithProduct(product.QonversionId, product.OfferingId, oldProductId, prorationMode, OnUpdatePurchaseWithProductMethodName); - } - - /// - /// Returns Qonversion products in association with Apple and Google Play Store Products. - /// - /// Callback that will be called when response is received. - /// Product Center - public static void Products(OnProductsReceived callback) - { - ProductsCallbacks.Add(callback); - IQonversionWrapper instance = getFinalInstance(); - instance.Products(OnProductsMethodName); - } + public delegate void OnPurchaseResultReceived(Dictionary entitlements, QonversionError error, bool isCancelled); + public delegate void OnEntitlementsReceived(Dictionary entitlements, QonversionError error); + public delegate void OnProductsReceived(Dictionary products, QonversionError error); + public delegate void OnOfferingsReceived(Offerings offerings, QonversionError error); + public delegate void OnEligibilitiesReceived(Dictionary eligibilities, QonversionError error); + public delegate void OnUserInfoReceived(User userInfo, QonversionError error); /// - /// Return Qonversion Offerings Object. - /// - /// An offering is a group of products that you can offer to a user on a given paywall based on your business logic. - /// For example, you can offer one set of products on a paywall immediately after onboarding and another - /// set of products with discounts later on if a user has not converted. - /// Offerings allow changing the products offered remotely without releasing app updates. + /// Delegate fires each time a promo purchase from the App Store happens. + /// Be sure you define a delegate for the event . + /// Call StartPromoPurchase in case of your app is ready to start promo purchase. + /// Or cache that delegate and call later when you need. /// - /// Offerings - /// Product Center - public static void Offerings(OnOfferingsReceived callback) - { - OfferingsCallbacks.Add(callback); - IQonversionWrapper instance = getFinalInstance(); - instance.Offerings(OnOfferingsMethodName); - } + /// StoreKit product identifier + /// A delegate that will start a promo purchase flow. + /// + /// + public delegate void OnPromoPurchasesReceived(string productId, StartPromoPurchase purchaseDelegate); /// - /// You can check if a user is eligible for an introductory offer, including a free trial. - /// You can show only a regular price for users who are not eligible for an introductory offer. + /// Call the function if your app can handle a promo purchase at the current time. + /// Or you can cache the delegate, and call it when the app is ready to make the purchase. /// - /// Products identifiers that must be checked. - /// Callback that will be called when response is received - public static void CheckTrialIntroEligibility(IList productIds, OnEligibilitiesReceived callback) - { - var productIdsJson = Json.Serialize(productIds); - - EligibilitiesCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.CheckTrialIntroEligibility(productIdsJson, OnEligibilitiesMethodName); - } + /// Callback that will be called when response is received. Returns entitlements or potentially a QonversionError. + /// + /// + public delegate void StartPromoPurchase(OnEntitlementsReceived callback); /// - /// Permissions cache is used when there are problems with the Qonversion API - /// or internet connection. If so, Qonversion will return the last successfully loaded - /// permissions. The current method allows you to configure how long that cache may be used. - /// The default value is . - /// - /// Desired permissions cache lifetime duration. - public static void SetPermissionsCacheLifetime(PermissionsCacheLifetime lifetime) { - var lifetimeKey = Mapper.GetLifetimeKey(lifetime); - IQonversionWrapper instance = getFinalInstance(); - instance.SetPermissionsCacheLifetime(lifetimeKey); - } - - /// - /// Set push token to Qonversion to enable Qonversion push notifications + /// Delegate fires each time a user entitlements change asynchronously, + /// for example, when pending purchases like SCA, Ask to buy, etc., happen. /// - /// Firebase device token on Android. APNs device token on iOS. - public static void SetNotificationsToken(string token) - { - IQonversionWrapper instance = getFinalInstance(); - instance.SetNotificationsToken(token); - } - - public static bool HandleNotification(Dictionary notification) - { - IQonversionWrapper instance = getFinalInstance(); - return instance.HandleNotification(notification.toJson()); - } - - [CanBeNull] - public static Dictionary GetNotificationCustomPayload(Dictionary notification) - { - IQonversionWrapper instance = getFinalInstance(); - var payloadJson = instance.GetNotificationCustomPayload(notification.toJson()); - - if (payloadJson == null) - { - return null; - } - - if (!(Json.Deserialize(payloadJson) is Dictionary response)) - { - Debug.LogError("Could not parse custom notification payload."); - return null; - } - - return response; - } - - // Called from the native SDK - Called when launch completed - private void OnLaunch(string jsonString) - { - Debug.Log("OnLaunch " + jsonString); - } - - // Called from the native SDK - Called when permissions received from the checkPermissions() method - private void OnCheckPermissions(string jsonString) - { - Debug.Log("OnCheckPermissions " + jsonString); - HandlePermissions(CheckPermissionsCallbacks, jsonString); - CheckPermissionsCallbacks.Clear(); - } - - // Called from the native SDK - Called when purchase result received from the purchase() method - private void OnPurchase(string jsonString) - { - Debug.Log("OnPurchase callback " + jsonString); - HandlePurchaseResult(PurchaseCallback, jsonString); - PurchaseCallback = null; - } - - // Called from the native SDK - Called when purchase result received from the purchaseProduct() method - private void OnPurchaseProduct(string jsonString) - { - Debug.Log("OnPurchaseProduct callback " + jsonString); - HandlePurchaseResult(PurchaseProductCallback, jsonString); - PurchaseProductCallback = null; - } - - // Called from the native SDK - Called when permissions received from the restore() method - private void OnRestore(string jsonString) - { - Debug.Log("OnRestore " + jsonString); - HandlePermissions(RestoreCallbacks, jsonString); - RestoreCallbacks.Clear(); - } - - // Called from the native SDK - Called when purchase result received from the updatePurchase() method - private void OnUpdatePurchase(string jsonString) - { - Debug.Log("OnUpdatePurchase " + jsonString); - HandlePurchaseResult(UpdatePurchaseCallback, jsonString); - UpdatePurchaseCallback = null; - } - - // Called from the native SDK - Called when purchase result received from the updatePurchaseWithProduct() method - private void OnUpdatePurchaseWithProduct(string jsonString) - { - Debug.Log("OnUpdatePurchaseWithProduct " + jsonString); - HandlePurchaseResult(UpdatePurchaseWithProductCallback, jsonString); - UpdatePurchaseWithProductCallback = null; - } - - // Called from the native SDK - Called when permissions received from the promoPurchase() method - private void OnPromoPurchase(string jsonString) - { - Debug.Log("OnPromoPurchase callback " + jsonString); - if (PromoPurchaseCallback != null) { - var callbacks = new List { PromoPurchaseCallback }; - HandlePermissions(callbacks, jsonString); - } - - PromoPurchaseCallback = null; - _storedPromoProductId = null; - } - - // Called from the native SDK - Called when products received from the products() method - private void OnProducts(string jsonString) - { - Debug.Log("OnProducts " + jsonString); - - if (ProductsCallbacks.Count == 0) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - ProductsCallbacks.ForEach(callback => callback(null, error)); - } - else - { - var products = Mapper.ProductsFromJson(jsonString); - ProductsCallbacks.ForEach(callback => callback(products, null)); - } - - ProductsCallbacks.Clear(); - } - - // Called from the native SDK - Called when offerings received from the offerings() method - private void OnOfferings(string jsonString) - { - Debug.Log("OnOfferings " + jsonString); - - if (OfferingsCallbacks.Count == 0) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - OfferingsCallbacks.ForEach(callback => callback(null, error)); - } - else - { - var offerings = Mapper.OfferingsFromJson(jsonString); - OfferingsCallbacks.ForEach(callback => callback(offerings, null)); - } - - OfferingsCallbacks.Clear(); - } - - // Called from the native SDK - Called when eligibilities received from the checkTrialIntroEligibilityForProductIds() method - private void OnEligibilities(string jsonString) - { - Debug.Log("OnEligibilities " + jsonString); - - if (EligibilitiesCallback == null) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - EligibilitiesCallback(null, error); - } - else - { - Dictionary eligibilities = Mapper.EligibilitiesFromJson(jsonString); - EligibilitiesCallback(eligibilities, null); - } - - EligibilitiesCallback = null; - } - - // Called from the native SDK - Called when deferred or pending purchase occured - private void OnReceivedUpdatedEntitlements(string jsonString) - { - Debug.Log("OnReceivedUpdatedEntitlements " + jsonString); - - if (_onUpdatedEntitlementsReceived == null) - { - return; - } - - Dictionary permissions = Mapper.PermissionsFromJson(jsonString); - _onUpdatedEntitlementsReceived(permissions); - } - - private void OnReceivePromoPurchase(string storeProductId) - { - Debug.Log("OnReceivePromoPurchase " + storeProductId); - - if (_onPromoPurchasesReceived == null) - { - return; - } - - _storedPromoProductId = storeProductId; - _onPromoPurchasesReceived(storeProductId, PromoPurchase); - } - - private void PromoPurchase(OnPermissionsReceived callback) - { - PromoPurchaseCallback = callback; - IQonversionWrapper instance = getFinalInstance(); - instance.PromoPurchase(_storedPromoProductId, OnPromoPurchaseMethodName); - } - - private void HandlePermissions(List callbacks, string jsonString) - { - if (callbacks.Count == 0) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - callbacks.ForEach(callback => callback(null, error)); - } - else - { - var permissions = Mapper.PermissionsFromJson(jsonString); - callbacks.ForEach(callback => callback(permissions, null)); - } - } - - private void HandlePurchaseResult(OnPurchaseResultReceived callback, string jsonString) - { - if (callback == null) return; - - var error = Mapper.ErrorFromJson(jsonString); - if (error != null) - { - var isCancelled = Mapper.GetIsCancelledFromJson(jsonString); - callback(null, error, isCancelled); - } - else - { - var permissions = Mapper.PermissionsFromJson(jsonString); - callback(permissions, null, false); - } - } - - private void OnAutomationsScreenShown(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } - - string screenId = Mapper.ScreenIdFromJson(jsonString); - - _automationsDelegate.OnAutomationsScreenShown(screenId); - } - - private void OnAutomationsActionStarted(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } - - ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); - _automationsDelegate.OnAutomationsActionStarted(actionResult); - } - - private void OnAutomationsActionFailed(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } - - ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); - _automationsDelegate.OnAutomationsActionFailed(actionResult); - } - - - private void OnAutomationsActionFinished(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } - - ActionResult actionResult = Mapper.ActionResultFromJson(jsonString); - _automationsDelegate.OnAutomationsActionFinished(actionResult); - } - - private void OnAutomationsFinished(string jsonString) - { - if (_automationsDelegate == null) - { - return; - } - - _automationsDelegate.OnAutomationsFinished(); - } - - private static OnPurchaseResultReceived ConvertPermissionsCallbackToPurchaseResultCallback(OnPermissionsReceived callback) - { - return delegate(Dictionary permissions, QonversionError error, bool isCancelled) { - callback(permissions, error); - }; - } + public delegate void OnUpdatedEntitlementsReceived(Dictionary entitlements); } } diff --git a/Runtime/Scripts/Qonversion.cs.meta b/Runtime/Scripts/Qonversion.cs.meta index 3d73b36..cd102dc 100644 --- a/Runtime/Scripts/Qonversion.cs.meta +++ b/Runtime/Scripts/Qonversion.cs.meta @@ -1,11 +1,3 @@ fileFormatVersion: 2 -guid: 38c50778583feeb4da0934f2fa914b96 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +guid: 3d153a0da53e4ab38cd2815b94987e82 +timeCreated: 1668681655 \ No newline at end of file diff --git a/Runtime/Scripts/QonversionAndroidHandler.cs b/Runtime/Scripts/QonversionAndroidHandler.cs deleted file mode 100644 index 1ff099e..0000000 --- a/Runtime/Scripts/QonversionAndroidHandler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using UnityEngine; - -namespace QonversionUnity -{ - internal class QonversionAndroidHandler : AndroidJavaProxy, IQonversionResultHandler - { - private const string QONVERSION_WRAPPER_INTERFACE_PATH = "com.qonversion.unitywrapper.IQonversionResultHandler"; - - public InitDelegate InitComplete; - - public QonversionAndroidHandler(InitDelegate onInitComplete) : base(QONVERSION_WRAPPER_INTERFACE_PATH) - { - InitComplete = onInitComplete; - } - - public void onSuccessInit(string uid) - { - InitComplete?.Invoke(); - } - - public void onErrorInit(string errorMessage) - { - Debug.LogError(string.Format("[Qonversion] onErrorInit Error: {0}", errorMessage)); - } - } -} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionAndroidHandler.cs.meta b/Runtime/Scripts/QonversionAndroidHandler.cs.meta deleted file mode 100644 index 57140d9..0000000 --- a/Runtime/Scripts/QonversionAndroidHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5ce88f53397a401488b208d6a1c156d8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/Scripts/QonversionConfig.cs b/Runtime/Scripts/QonversionConfig.cs new file mode 100644 index 0000000..341f97e --- /dev/null +++ b/Runtime/Scripts/QonversionConfig.cs @@ -0,0 +1,18 @@ +namespace QonversionUnity +{ + public class QonversionConfig + { + public readonly string ProjectKey; + public readonly LaunchMode LaunchMode; + public readonly Environment Environment; + public readonly EntitlementsCacheLifetime EntitlementsCacheLifetime; + + public QonversionConfig(string projectKey, LaunchMode launchMode, Environment environment, EntitlementsCacheLifetime entitlementsCacheLifetime) + { + ProjectKey = projectKey; + LaunchMode = launchMode; + Environment = environment; + EntitlementsCacheLifetime = entitlementsCacheLifetime; + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionConfig.cs.meta b/Runtime/Scripts/QonversionConfig.cs.meta new file mode 100644 index 0000000..d0b0f96 --- /dev/null +++ b/Runtime/Scripts/QonversionConfig.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 081671b389ce42258e66635391aa5c2f +timeCreated: 1668682590 \ No newline at end of file diff --git a/Runtime/Scripts/QonversionConfigBuilder.cs b/Runtime/Scripts/QonversionConfigBuilder.cs new file mode 100644 index 0000000..8f8e023 --- /dev/null +++ b/Runtime/Scripts/QonversionConfigBuilder.cs @@ -0,0 +1,55 @@ +namespace QonversionUnity +{ + public class QonversionConfigBuilder + { + private readonly string _projectKey; + private readonly LaunchMode _launchMode; + private Environment _environment = Environment.Production; + private EntitlementsCacheLifetime _entitlementsCacheLifetime = EntitlementsCacheLifetime.Month; + + public QonversionConfigBuilder(string projectKey, LaunchMode launchMode) + { + _projectKey = projectKey; + _launchMode = launchMode; + } + + /// + /// Set current application . Used to distinguish sandbox and production users. + /// + /// current environment. + /// builder instance for chain calls. + public QonversionConfigBuilder SetEnvironment(Environment environment) + { + _environment = environment; + return this; + } + + /// + /// Entitlements cache is used when there are problems with the Qonversion API + /// or internet connection. If so, Qonversion will return the last successfully loaded + /// entitlements. The current method allows you to configure how long that cache may be used. + /// The default value is . + /// + /// desired entitlements cache lifetime duration. + /// builder instance for chain calls. + public QonversionConfigBuilder SetEntitlementsCacheLifetime(EntitlementsCacheLifetime lifetime) + { + _entitlementsCacheLifetime = lifetime; + return this; + } + + /// + /// Generate instance with all the provided configurations. + /// + /// the complete instance. + public QonversionConfig Build() + { + return new QonversionConfig( + _projectKey, + _launchMode, + _environment, + _entitlementsCacheLifetime + ); + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionConfigBuilder.cs.meta b/Runtime/Scripts/QonversionConfigBuilder.cs.meta new file mode 100644 index 0000000..019c21b --- /dev/null +++ b/Runtime/Scripts/QonversionConfigBuilder.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e965105671494d86988de6e150a1a2a3 +timeCreated: 1668683063 \ No newline at end of file diff --git a/Runtime/Scripts/QonversionLauncher.cs b/Runtime/Scripts/QonversionLauncher.cs deleted file mode 100644 index 3956c64..0000000 --- a/Runtime/Scripts/QonversionLauncher.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace QonversionUnity -{ - public class QonversionLauncher : MonoBehaviour - { - [Tooltip("Your Qonversion Application Access Key. Get from https://dash.qonversion.io/")] - [SerializeField] - protected string m_ApplicationAccessKey; - - [Tooltip("Debug Mode: https://documentation.qonversion.io/docs/debug-mode")] - [SerializeField] - protected bool m_DebugMode; - - [Tooltip("Observer Mode: https://documentation.qonversion.io/docs/observer-mode")] - [SerializeField] - protected bool m_ObserverMode; - - private void Start() - { - if (m_DebugMode) - { - Qonversion.SetDebugMode(); - } - - Qonversion.Launch(m_ApplicationAccessKey, m_ObserverMode); - } - } -} \ No newline at end of file diff --git a/Runtime/Scripts/QonversionLauncher.cs.meta b/Runtime/Scripts/QonversionLauncher.cs.meta deleted file mode 100644 index 1650602..0000000 --- a/Runtime/Scripts/QonversionLauncher.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2a8972452586ad74b907e03decfa6f7b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/iOS/AutomationsWrapperIOS.cs b/Runtime/iOS/AutomationsWrapperIOS.cs new file mode 100644 index 0000000..235d1ad --- /dev/null +++ b/Runtime/iOS/AutomationsWrapperIOS.cs @@ -0,0 +1,79 @@ +#if UNITY_IOS +using System.Runtime.InteropServices; +#endif + +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace QonversionUnity +{ + internal class AutomationsWrapperIOS : IAutomationsWrapper + { +#if UNITY_IOS + [DllImport("__Internal")] + private static extern void _initialize(string gameObjectName); + + [DllImport("__Internal")] + private static extern void _setNotificationsToken(string token); + + [DllImport("__Internal")] + private static extern bool _handleNotification(string notification); + + [DllImport("__Internal")] + private static extern string _getNotificationCustomPayload(string notification); + + [DllImport("__Internal")] + private static extern void _subscribeOnAutomationEvents(); + + [DllImport("__Internal")] + private static extern void _showScreen(string screenId, string callbackName); +#endif + + public void Initialize(string gameObjectName) + { +#if UNITY_IOS + _initialize(gameObjectName); +#endif + } + + public void SetNotificationsToken(string token) + { +#if UNITY_IOS + _setNotificationsToken(token); +#endif + } + + public bool HandleNotification(string notification) + { +#if UNITY_IOS + return _handleNotification(notification); +#else + return false; +#endif + } + + public string GetNotificationCustomPayload(string notification) + { +#if UNITY_IOS + return _getNotificationCustomPayload(notification); +#else + return null; +#endif + } + + public void SubscribeOnAutomationEvents() + { +#if UNITY_IOS + _subscribeOnAutomationEvents(); +#endif + } + + public void ShowScreen(string screenId, string callbackName) + { +#if UNITY_IOS + _showScreen(screenId, callbackName); +#endif + } + } +} \ No newline at end of file diff --git a/Runtime/iOS/AutomationsWrapperIOS.cs.meta b/Runtime/iOS/AutomationsWrapperIOS.cs.meta new file mode 100644 index 0000000..4a3fc2f --- /dev/null +++ b/Runtime/iOS/AutomationsWrapperIOS.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 833a9b7bdb0a43228b1153c40421e900 +timeCreated: 1668776223 \ No newline at end of file diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs index bec6e48..9a2edda 100644 --- a/Runtime/iOS/QonversionWrapperIOS.cs +++ b/Runtime/iOS/QonversionWrapperIOS.cs @@ -50,6 +50,9 @@ internal class QonversionWrapperIOS : IQonversionWrapper [DllImport("__Internal")] private static extern void _restore(string callbackName); + [DllImport("__Internal")] + private static extern void _userInfo(string callbackName); + [DllImport("__Internal")] private static extern void _purchase(string productID, string callbackName); @@ -68,23 +71,8 @@ internal class QonversionWrapperIOS : IQonversionWrapper [DllImport("__Internal")] private static extern void _promoPurchase(string storeProductId, string callbackName); - [DllImport("__Internal")] - private static extern void _setNotificationsToken(string token); - - [DllImport("__Internal")] - private static extern bool _handleNotification(string notification); - - [DllImport("__Internal")] - private static extern string _getNotificationCustomPayload(string notification); - - [DllImport("__Internal")] - private static extern void _subscribeOnAutomationEvents(); - [DllImport("__Internal")] private static extern void _presentCodeRedemptionSheet(); - - [DllImport("__Internal")] - private static extern void _setPermissionsCacheLifetime(string lifetimeKey); #endif public void Initialize(string gameObjectName) @@ -101,10 +89,10 @@ public void StoreSdkInfo(string version, string source) #endif } - public void InitializeSdk(string projectKey, bool observerMode, string callbackName) + public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime) { #if UNITY_IOS - _launchWithKey(projectKey, callbackName); + // todo #endif } @@ -112,13 +100,6 @@ public void SyncPurchases() { } - public void SetDebugMode() - { -#if UNITY_IOS - _setDebugMode(); -#endif - } - public void SetAdvertisingID() { #if UNITY_IOS @@ -141,11 +122,10 @@ public void SetProperty(UserProperty key, string value) #endif } - public void AddAttributionData(string conversionData, AttributionSource source) + public void AddAttributionData(string conversionData, string providerName) { #if UNITY_IOS - string sourceName = Enum.GetName(typeof(AttributionSource), source); - _addAttributionData(conversionData, sourceName); + _addAttributionData(conversionData, providerName); #endif } @@ -170,6 +150,13 @@ public void Logout() #endif } + public void UserInfo(string callbackName) + { +#if UNITY_IOS + _userInfo(callbackName); +#endif + } + public void PresentCodeRedemptionSheet() { #if UNITY_IOS @@ -238,45 +225,6 @@ public void PromoPurchase(string storeProductId, string callbackName) { #if UNITY_IOS _promoPurchase(storeProductId, callbackName); -#endif - } - - public void SetNotificationsToken(string token) - { -#if UNITY_IOS - _setNotificationsToken(token); -#endif - } - - public bool HandleNotification(string notification) - { -#if UNITY_IOS - return _handleNotification(notification); -#else - return false; -#endif - } - - public string GetNotificationCustomPayload(string notification) - { -#if UNITY_IOS - return _getNotificationCustomPayload(notification); -#else - return null; -#endif - } - - public void SubscribeOnAutomationEvents() - { -#if UNITY_IOS - _subscribeOnAutomationEvents(); -#endif - } - - public void SetPermissionsCacheLifetime(string lifetime) - { -#if UNITY_IOS - _setPermissionsCacheLifetime(lifetime); #endif } } diff --git a/fastlane.meta b/fastlane.meta new file mode 100644 index 0000000..c89bbe8 --- /dev/null +++ b/fastlane.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 089159a4944c04210aeeacfd063d3601 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/fastlane/README.md.meta b/fastlane/README.md.meta new file mode 100644 index 0000000..cce087c --- /dev/null +++ b/fastlane/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0f7d66a11e8894098917aa1f4ef1507a +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/fastlane/fastfile.meta b/fastlane/fastfile.meta new file mode 100644 index 0000000..a3d1619 --- /dev/null +++ b/fastlane/fastfile.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0490d362f09d34421838ef526cb8839d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/fastlane/report.xml.meta b/fastlane/report.xml.meta new file mode 100644 index 0000000..a220bb7 --- /dev/null +++ b/fastlane/report.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ce3590874b3444ee79db9c2164fd95be +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/img/UnityQonversionLauncher.png.meta b/img/UnityQonversionLauncher.png.meta new file mode 100644 index 0000000..e1575e5 --- /dev/null +++ b/img/UnityQonversionLauncher.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 721fa4cd076d647b7a88c24f5c0e1aec +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: From 85ed5ca392c65fd7e1fe144713b46a31fdeae0fb Mon Sep 17 00:00:00 2001 From: Surik Date: Mon, 12 Dec 2022 19:12:47 +0400 Subject: [PATCH 16/22] Changed iOS part --- Editor/QonversionDependencies.xml | 4 +- .../AutomationsWrapperNoop.cs.meta | 2 +- .../automations/QonversionWrapperNoop.cs | 31 ----------- .../automations/QonversionWrapperNoop.cs.meta | 3 -- Runtime/iOS/Plugins/AutomationsBridge.m | 52 +++++++++++++++++++ .../Plugins/Common/QNUAutomationsDelegate.h | 1 + .../Plugins/Common/QNUAutomationsDelegate.m | 8 +++ 7 files changed, 64 insertions(+), 37 deletions(-) delete mode 100644 Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs delete mode 100644 Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs.meta create mode 100644 Runtime/iOS/Plugins/AutomationsBridge.m diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml index 50c4eaf..e36a651 100644 --- a/Editor/QonversionDependencies.xml +++ b/Editor/QonversionDependencies.xml @@ -1,11 +1,11 @@ - + - + diff --git a/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta b/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta index 94ad546..cb58df1 100644 --- a/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta +++ b/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta @@ -1,3 +1,3 @@ fileFormatVersion: 2 -guid: 52b5b093639a4d04ab569175864e233a +guid: efc8a0074ad9d48879dfbbec563b3225 timeCreated: 1668776080 \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs b/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs deleted file mode 100644 index 5e0ce89..0000000 --- a/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace QonversionUnity - { - internal class AutomationsWrapperNoop : IAutomationsWrapper - { - public void Initialize(string gameObjectName) - { - } - - public void InitializeSdk() - { - } - - public void SetNotificationsToken(string token) - { - } - - public bool HandleNotification(string notification) - { - return false; - } - - public string GetNotificationCustomPayload(string notification) - { - return null; - } - - public void SubscribeOnAutomationEvents() - { - } - } - } \ No newline at end of file diff --git a/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs.meta b/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs.meta deleted file mode 100644 index 94ad546..0000000 --- a/Runtime/Scripts/Internal/wrappers/automations/QonversionWrapperNoop.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 52b5b093639a4d04ab569175864e233a -timeCreated: 1668776080 \ No newline at end of file diff --git a/Runtime/iOS/Plugins/AutomationsBridge.m b/Runtime/iOS/Plugins/AutomationsBridge.m new file mode 100644 index 0000000..df409fd --- /dev/null +++ b/Runtime/iOS/Plugins/AutomationsBridge.m @@ -0,0 +1,52 @@ +#import "UtilityBridge.h" +#import "QNUAutomationsDelegate.h" +@import QonversionSandwich; + +char* unityListenerName = nil; + +static QNUAutomationsDelegate *automationsBridge; + +void _initialize(const char* unityListener) { + unsigned long len = strlen(unityListener); + unityListenerName = malloc(len + 1); + strcpy(unityListenerName, unityListener); + + automationsBridge = [[QNUAutomationsDelegate alloc] initWithListenerName:unityListenerName]; +} + +void _setNotificationsToken(const char* token) { + NSString *tokenStr = [UtilityBridge сonvertCStringToNSString:token]; + [automationsBridge setNotificationsToken:tokenStr]; +} + +bool _handleNotification(const char* notification) { + NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]]; + + BOOL isQonversionNotification = [automationsBridge handleNotification:notificationInfo]; + + return isQonversionNotification; +} + +const char* _getNotificationCustomPayload(const char* notification) { + NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]]; + + NSDictionary *payload = [automationsBridge getNotificationCustomPayload:notificationInfo]; + + if (payload == nil) { + return nil; + } + + const char *data = [UtilityBridge jsonStringFromObject:payload]; + + return data; +} + +void _showScreen(const char* screenId, const char* unityCallbackName) { + NSString *callbackName = [UtilityBridge сonvertCStringToNSString:unityCallbackName]; + NSString *screenIdStr = [UtilityBridge сonvertCStringToNSString:screenId]; + [automationsBridge showScreenWithId:screenIdStr callbackName:callbackName]; +} + +void _subscribeOnAutomationEvents() { + [automationsBridge subscribe]; +} diff --git a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h index 47499e1..692820f 100644 --- a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h +++ b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h @@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)setNotificationsToken:(NSString *)token; - (BOOL)handleNotification:(NSDictionary *)notificationInfo; - (NSDictionary *)getNotificationCustomPayload:(NSDictionary *)payload; +- (void)showScreenWithId:(NSString *)screenId callbackName:(NSString *)callbackName; @end diff --git a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m index c36cbcb..1c7694c 100644 --- a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m +++ b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m @@ -65,4 +65,12 @@ - (void)automationDidTriggerWithEvent:(NSString * _Nonnull)event payload:(NSDict [UtilityBridge sendUnityMessage:payload ?: @{} toMethod:methodName unityListener: listenerName]; } +- (void)showScreenWithId:(NSString *)screenId callbackName:(NSString *)callbackName { + [self.automationsSandwich showScreen:screenId completion:^(NSDictionary * _Nullable result, SandwichError * _Nullable error) { + if (error) { + [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:listenerName]; + } + }]; +} + @end From 3865ce8aa7b8266ad7bb1de68a88f3faeece9a33 Mon Sep 17 00:00:00 2001 From: Surik Date: Mon, 12 Dec 2022 20:30:30 +0400 Subject: [PATCH 17/22] Removed duplicate symbols --- Runtime/iOS/AutomationsWrapperIOS.cs | 4 +-- Runtime/iOS/Plugins/AutomationsBridge.m | 10 +++--- Runtime/iOS/Plugins/AutomationsBridge.m.meta | 37 ++++++++++++++++++++ Runtime/iOS/Plugins/QonversionBridge.m | 34 ------------------ 4 files changed, 44 insertions(+), 41 deletions(-) create mode 100644 Runtime/iOS/Plugins/AutomationsBridge.m.meta diff --git a/Runtime/iOS/AutomationsWrapperIOS.cs b/Runtime/iOS/AutomationsWrapperIOS.cs index 1c1bf91..ce17f2e 100644 --- a/Runtime/iOS/AutomationsWrapperIOS.cs +++ b/Runtime/iOS/AutomationsWrapperIOS.cs @@ -12,7 +12,7 @@ internal class AutomationsWrapperIOS : IAutomationsWrapper { #if UNITY_IOS [DllImport("__Internal")] - private static extern void _initialize(string gameObjectName); + private static extern void _initializeAutomations(string gameObjectName); [DllImport("__Internal")] private static extern void _setNotificationsToken(string token); @@ -33,7 +33,7 @@ internal class AutomationsWrapperIOS : IAutomationsWrapper public void Initialize(string gameObjectName) { #if UNITY_IOS - _initialize(gameObjectName); + _initializeAutomations(gameObjectName); #endif } public void SetNotificationsToken(string token) diff --git a/Runtime/iOS/Plugins/AutomationsBridge.m b/Runtime/iOS/Plugins/AutomationsBridge.m index df409fd..1c663a7 100644 --- a/Runtime/iOS/Plugins/AutomationsBridge.m +++ b/Runtime/iOS/Plugins/AutomationsBridge.m @@ -2,16 +2,16 @@ #import "QNUAutomationsDelegate.h" @import QonversionSandwich; -char* unityListenerName = nil; +char* automationsUnityListenerName = nil; static QNUAutomationsDelegate *automationsBridge; -void _initialize(const char* unityListener) { +void _initializeAutomations(const char* unityListener) { unsigned long len = strlen(unityListener); - unityListenerName = malloc(len + 1); - strcpy(unityListenerName, unityListener); + automationsUnityListenerName = malloc(len + 1); + strcpy(automationsUnityListenerName, unityListener); - automationsBridge = [[QNUAutomationsDelegate alloc] initWithListenerName:unityListenerName]; + automationsBridge = [[QNUAutomationsDelegate alloc] initWithListenerName:automationsUnityListenerName]; } void _setNotificationsToken(const char* token) { diff --git a/Runtime/iOS/Plugins/AutomationsBridge.m.meta b/Runtime/iOS/Plugins/AutomationsBridge.m.meta new file mode 100644 index 0000000..fe55fb6 --- /dev/null +++ b/Runtime/iOS/Plugins/AutomationsBridge.m.meta @@ -0,0 +1,37 @@ +fileFormatVersion: 2 +guid: 3274bd50e96104e20b153fb581760138 +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 1 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 0 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + iPhone: iOS + second: + enabled: 1 + settings: {} + - first: + tvOS: tvOS + second: + enabled: 1 + settings: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/iOS/Plugins/QonversionBridge.m b/Runtime/iOS/Plugins/QonversionBridge.m index 7e69c43..3b7d4d8 100644 --- a/Runtime/iOS/Plugins/QonversionBridge.m +++ b/Runtime/iOS/Plugins/QonversionBridge.m @@ -1,5 +1,4 @@ #import "UtilityBridge.h" -#import "QNUAutomationsDelegate.h" @import QonversionSandwich; char* unityListenerName = nil; @@ -23,7 +22,6 @@ - (void)qonversionDidReceiveUpdatedEntitlements:(NSDictionary * _ @end -static QNUAutomationsDelegate *automationsBridge; static QonversionSandwich *qonversionSandwich; void _initialize(const char* unityListener) { @@ -32,7 +30,6 @@ void _initialize(const char* unityListener) { strcpy(unityListenerName, unityListener); qonversionSandwich = [[QonversionSandwich alloc] initWithQonversionEventListener:[QonversionEventListenerWrapper new]]; - automationsBridge = [[QNUAutomationsDelegate alloc] initWithListenerName:unityListenerName]; } void _initializeSdk(const char* projectKey, const char* launchMode, const char* environment, const char* entitlementsCacheLifetime) { @@ -182,34 +179,3 @@ void _promoPurchase(const char* storeProductId, const char* unityCallbackName) { [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:unityListenerName]; }]; } - -void _setNotificationsToken(const char* token) { - NSString *tokenStr = [UtilityBridge сonvertCStringToNSString:token]; - [automationsBridge setNotificationsToken:tokenStr]; -} - -bool _handleNotification(const char* notification) { - NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]]; - - BOOL isQonversionNotification = [automationsBridge handleNotification:notificationInfo]; - - return isQonversionNotification; -} - -const char* _getNotificationCustomPayload(const char* notification) { - NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]]; - - NSDictionary *payload = [automationsBridge getNotificationCustomPayload:notificationInfo]; - - if (payload == nil) { - return nil; - } - - const char *data = [UtilityBridge jsonStringFromObject:payload]; - - return data; -} - -void _subscribeOnAutomationEvents() { - [automationsBridge subscribe]; -} From be42d231f825cf0c6335640f5ba9951a68a2caf6 Mon Sep 17 00:00:00 2001 From: Surik Date: Tue, 13 Dec 2022 12:19:10 +0400 Subject: [PATCH 18/22] Fixes after review --- Editor/QonversionDependencies.xml | 2 +- .../.idea/.idea.Scripts.dir/.idea/.gitignore | 13 +++++++++++++ .../.idea/.idea.Scripts.dir/.idea/encodings.xml | 4 ++++ .../.idea/.idea.Scripts.dir/.idea/indexLayout.xml | 8 ++++++++ .../Scripts/.idea/.idea.Scripts.dir/.idea/vcs.xml | 6 ++++++ Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m | 4 +--- Runtime/iOS/Plugins/QonversionBridge.m | 1 - 7 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/.gitignore create mode 100644 Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/encodings.xml create mode 100644 Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/indexLayout.xml create mode 100644 Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/vcs.xml diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml index e36a651..694dad8 100644 --- a/Editor/QonversionDependencies.xml +++ b/Editor/QonversionDependencies.xml @@ -6,6 +6,6 @@ - + diff --git a/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/.gitignore b/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/.gitignore new file mode 100644 index 0000000..27bd7eb --- /dev/null +++ b/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/.idea.Scripts.iml +/projectSettingsUpdater.xml +/contentModel.xml +/modules.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/encodings.xml b/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/indexLayout.xml b/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/vcs.xml b/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/Runtime/Scripts/.idea/.idea.Scripts.dir/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m index 1c7694c..55235e0 100644 --- a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m +++ b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m @@ -67,9 +67,7 @@ - (void)automationDidTriggerWithEvent:(NSString * _Nonnull)event payload:(NSDict - (void)showScreenWithId:(NSString *)screenId callbackName:(NSString *)callbackName { [self.automationsSandwich showScreen:screenId completion:^(NSDictionary * _Nullable result, SandwichError * _Nullable error) { - if (error) { - [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:listenerName]; - } + [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:listenerName]; }]; } diff --git a/Runtime/iOS/Plugins/QonversionBridge.m b/Runtime/iOS/Plugins/QonversionBridge.m index 3b7d4d8..7247469 100644 --- a/Runtime/iOS/Plugins/QonversionBridge.m +++ b/Runtime/iOS/Plugins/QonversionBridge.m @@ -41,7 +41,6 @@ void _initializeSdk(const char* projectKey, const char* launchMode, const char* [qonversionSandwich initializeWithProjectKey:keyStr launchModeKey:launchModeStr environmentKey:envStr entitlementsCacheLifetimeKey:cacheLifetimeStr]; } -//_initializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime); void _storeSdkInfo(const char* version, const char* source) { NSString *versionStr = [UtilityBridge сonvertCStringToNSString:version]; NSString *sourceStr = [UtilityBridge сonvertCStringToNSString:source]; From db0c2e31a5193c5e2359cc4466fe9c2d7289ab85 Mon Sep 17 00:00:00 2001 From: Surik Date: Tue, 13 Dec 2022 17:51:52 +0400 Subject: [PATCH 19/22] Fixed custom payload logic --- Runtime/iOS/Plugins/AutomationsBridge.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Runtime/iOS/Plugins/AutomationsBridge.m b/Runtime/iOS/Plugins/AutomationsBridge.m index 1c663a7..8f5e777 100644 --- a/Runtime/iOS/Plugins/AutomationsBridge.m +++ b/Runtime/iOS/Plugins/AutomationsBridge.m @@ -27,7 +27,7 @@ bool _handleNotification(const char* notification) { return isQonversionNotification; } -const char* _getNotificationCustomPayload(const char* notification) { +char* _getNotificationCustomPayload(const char* notification) { NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]]; NSDictionary *payload = [automationsBridge getNotificationCustomPayload:notificationInfo]; @@ -38,7 +38,10 @@ bool _handleNotification(const char* notification) { const char *data = [UtilityBridge jsonStringFromObject:payload]; - return data; + char* cString = (char*)malloc(strlen(data) + 1); + strcpy(cString, data); + + return cString; } void _showScreen(const char* screenId, const char* unityCallbackName) { From 437856726787eb3ccf6b1d9b15bfd1429e8b4284 Mon Sep 17 00:00:00 2001 From: Kamo Spertsyan Date: Tue, 13 Dec 2022 19:39:40 +0300 Subject: [PATCH 20/22] Added missing attribution providers for Apple (#128) --- Runtime/Scripts/Dto/AttributionProvider.cs | 4 +++- fastlane/fastfile | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Runtime/Scripts/Dto/AttributionProvider.cs b/Runtime/Scripts/Dto/AttributionProvider.cs index e80b99a..2041fce 100644 --- a/Runtime/Scripts/Dto/AttributionProvider.cs +++ b/Runtime/Scripts/Dto/AttributionProvider.cs @@ -4,6 +4,8 @@ public enum AttributionProvider { AppsFlyer = 0, Branch, - Adjust + Adjust, + AppleSearchAds, // ios only + AppleAdServices // ios only } } \ No newline at end of file diff --git a/fastlane/fastfile b/fastlane/fastfile index 5df9606..ed6cdd9 100644 --- a/fastlane/fastfile +++ b/fastlane/fastfile @@ -7,7 +7,7 @@ def update_package_json(new_version) end def update_constant(new_version) - path = "../Runtime/Scripts/Qonversion.cs" + path = "../Runtime/Scripts/Internal/QonversionInternal.cs" regex = /private const string SdkVersion = ".*";/ result_value = "private const string SdkVersion = \"#{new_version}\";" From f5fa719369bb68a7bee4c23881446bdefe2a156b Mon Sep 17 00:00:00 2001 From: SpertsyanKM Date: Wed, 14 Dec 2022 08:33:46 +0000 Subject: [PATCH 21/22] [create-pull-request] automated change --- Runtime/Scripts/Internal/QonversionInternal.cs | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Runtime/Scripts/Internal/QonversionInternal.cs b/Runtime/Scripts/Internal/QonversionInternal.cs index 9d7afcb..eea0c26 100644 --- a/Runtime/Scripts/Internal/QonversionInternal.cs +++ b/Runtime/Scripts/Internal/QonversionInternal.cs @@ -21,7 +21,7 @@ internal class QonversionInternal : MonoBehaviour, IQonversion private const string OnEligibilitiesMethodName = "OnEligibilities"; private const string OnUserInfoMethodName = "OnUserInfo"; - private const string SdkVersion = "3.7.1"; + private const string SdkVersion = "4.0.0"; private const string SdkSource = "unity"; private IQonversionWrapper _nativeWrapperInstance; diff --git a/package.json b/package.json index 8040cd0..ab6f250 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.qonversion.unity", "displayName": "Qonversion", - "version": "3.7.1", + "version": "4.0.0", "unity": "2018.3", "description": "Empower your mobile app marketing and product decisions with precise subscription data.", "author": { From 4d405cc439f05486d5e4f6fc8f72fdfe0b975d3e Mon Sep 17 00:00:00 2001 From: kamospertsyan Date: Wed, 14 Dec 2022 11:35:40 +0300 Subject: [PATCH 22/22] Sandwich version upgrade. --- Editor/QonversionDependencies.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml index 694dad8..8e63191 100644 --- a/Editor/QonversionDependencies.xml +++ b/Editor/QonversionDependencies.xml @@ -1,11 +1,11 @@ - + - +