diff --git a/Editor/QonversionDependencies.xml b/Editor/QonversionDependencies.xml
index 1f6fd83..8e63191 100644
--- a/Editor/QonversionDependencies.xml
+++ b/Editor/QonversionDependencies.xml
@@ -1,11 +1,11 @@
-
+
-
+
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 3214d1c..613ecb7 100644
--- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java
+++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/AutomationsWrapper.java
@@ -6,6 +6,9 @@
import androidx.annotation.Nullable;
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;
@@ -14,8 +17,11 @@
import io.qonversion.sandwich.AutomationsEventListener;
import io.qonversion.sandwich.AutomationsSandwich;
+import io.qonversion.sandwich.ResultListener;
+import io.qonversion.sandwich.SandwichError;
-public class AutomationsWrapper implements AutomationsEventListener {
+@SuppressWarnings("UnnecessaryLocalVariable")
+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";
@@ -23,45 +29,107 @@ 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 subscribe() {
- automationsSandwich.subscribe(this);
+ public static synchronized void subscribeOnAutomationEvents() {
+ automationsSandwich.setDelegate(new EventListener());
}
- @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 setNotificationsToken(String token) {
+ automationsSandwich.setNotificationToken(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 = automationsSandwich.handleNotification(notificationInfo);
+
+ return result;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ @Nullable
+ public static synchronized String getNotificationCustomPayload(String notification) {
+ try {
+ final ObjectMapper mapper = new ObjectMapper();
+
+ final TypeReference> typeRef
+ = new TypeReference>() {
+ };
+ final Map notificationInfo = mapper.readValue(notification, typeRef);
+
+ final Map payload = automationsSandwich.getNotificationCustomPayload(notificationInfo);
+ final String json = mapper.writeValueAsString(payload);
+
+ return json;
+ } catch (Exception e) {
+ return null;
}
+ }
+
+ 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);
+ }
+ });
+ }
- sendMessageToUnity(data == null ? new HashMap<>() : data, methodName);
+ private static void handleErrorResponse(@NotNull SandwichError error, @NotNull String methodName) {
+ final ObjectNode rootNode = Utils.createErrorNode(error);
+
+ 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) {
@@ -69,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 c545fa2..8508c59 100644
--- a/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java
+++ b/Runtime/Android/Plugins/com/qonversion/unitywrapper/QonversionWrapper.java
@@ -27,10 +27,9 @@
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;
private static QonversionSandwich qonversionSandwich;
public static synchronized void initialize(String unityListener) {
@@ -40,27 +39,33 @@ 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);
}
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 +74,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 +82,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 +96,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 +132,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,53 +144,6 @@ 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);
- }
-
- 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;
- }
- }
-
- @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;
- }
- }
-
- public static synchronized void subscribeOnAutomationEvents() {
- automationsWrapper.subscribe();
- }
-
private static ResultListener getResultListener(@NotNull String methodName) {
return new ResultListener() {
@Override
@@ -206,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);
@@ -215,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 3f29fe5..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 Launch(string projectKey, bool observerMode, string callbackName)
+ public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime)
{
- CallQonversion("launch", 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,9 +82,14 @@ public void Logout()
CallQonversion("logout");
}
- public void CheckPermissions(string callbackName)
+ public void UserInfo(string callbackName)
+ {
+ CallQonversion("userInfo", callbackName);
+ }
+
+ public void CheckEntitlements(string callbackName)
{
- CallQonversion("checkPermissions", callbackName);
+ CallQonversion("checkEntitlements", callbackName);
}
public void Purchase(string productId, string callbackName)
@@ -141,29 +127,13 @@ public void Offerings(string callbackName)
CallQonversion("offerings", callbackName);
}
- public void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName)
- {
- CallQonversion("checkTrialIntroEligibilityForProductIds", productIdsJson, callbackName);
- }
-
- public void SetNotificationsToken(string token)
- {
- CallQonversion("setNotificationsToken", token);
- }
-
- public bool HandleNotification(string notification)
- {
- return CallQonversion("handleNotification", notification);
- }
-
- public string GetNotificationCustomPayload(string notification)
+ public void CheckTrialIntroEligibility(string productIdsJson, string callbackName)
{
- return CallQonversion("getNotificationCustomPayload", notification);
+ CallQonversion("checkTrialIntroEligibility", productIdsJson, callbackName);
}
- 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/.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/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/Dto/AttributionProvider.cs b/Runtime/Scripts/Dto/AttributionProvider.cs
new file mode 100644
index 0000000..2041fce
--- /dev/null
+++ b/Runtime/Scripts/Dto/AttributionProvider.cs
@@ -0,0 +1,11 @@
+namespace QonversionUnity
+{
+ public enum AttributionProvider
+ {
+ AppsFlyer = 0,
+ Branch,
+ Adjust,
+ AppleSearchAds, // ios only
+ AppleAdServices // ios only
+ }
+}
\ No newline at end of file
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..eea0c26
--- /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 = "4.0.0";
+ 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..cb58df1
--- /dev/null
+++ b/Runtime/Scripts/Internal/wrappers/automations/AutomationsWrapperNoop.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: efc8a0074ad9d48879dfbbec563b3225
+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 65%
rename from Runtime/Scripts/IQonversionWrapper.cs
rename to Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs
index 6fce157..72b9be1 100644
--- a/Runtime/Scripts/IQonversionWrapper.cs
+++ b/Runtime/Scripts/Internal/wrappers/qonversion/IQonversionWrapper.cs
@@ -5,15 +5,14 @@ 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 Launch(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 AddAttributionData(string conversionData, string providerName);
+ void CheckEntitlements(string callbackName);
void Purchase(string productId, string callbackName);
void PurchaseProduct(string productId, string offeringId, string callbackName);
void Restore(string callbackName);
@@ -21,16 +20,12 @@ 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();
+ 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 67%
rename from Runtime/Scripts/QonversionWrapperNoop.cs
rename to Runtime/Scripts/Internal/wrappers/qonversion/QonversionWrapperNoop.cs
index 58cb925..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 Launch(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)
{
}
@@ -33,7 +30,7 @@ public void SetAdvertisingID()
{
}
- public void CheckPermissions(string callbackName)
+ public void CheckEntitlements(string callbackName)
{
}
@@ -69,7 +66,7 @@ public void StoreSdkInfo(string version, string source)
{
}
- public void CheckTrialIntroEligibilityForProductIds(string productIdsJson, string callbackName)
+ public void CheckTrialIntroEligibility(string productIdsJson, string callbackName)
{
}
@@ -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/AttributionSource.cs b/Runtime/Scripts/Models/AttributionSource.cs
deleted file mode 100644
index 75b4474..0000000
--- a/Runtime/Scripts/Models/AttributionSource.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace QonversionUnity
-{
- public enum AttributionSource
- {
- AppsFlyer = 0,
- Branch,
- Adjust
- }
-}
\ No newline at end of file
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 712af99..e3d2129 100644
--- a/Runtime/Scripts/Qonversion.cs
+++ b/Runtime/Scripts/Qonversion.cs
@@ -1,814 +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);
+ [CanBeNull] private static IQonversion _backingInstance;
///
- /// 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.
+ /// 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.
///
- /// 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 deferred transaction happens
- ///
- public delegate void OnUpdatedPurchasesReceived(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 OnUpdatedPurchasesReceived _onUpdatedPurchasesReceived;
-
- 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()
+ /// Current initialized instance of the Qonversion SDK.
+ /// throws exception if the instance has not been initialized
+ public static IQonversion GetSharedInstance()
{
- if (_Instance == null)
+ if (_backingInstance == 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);
+ throw new Exception(
+ "Qonversion has not been initialized. You should call " +
+ "the initialize method before accessing the shared instance of Qonversion."
+ );
}
- 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 each time a deferred transaction happens.
- ///
- public static event OnUpdatedPurchasesReceived UpdatedPurchasesReceived
- {
- add
- {
- _onUpdatedPurchasesReceived += value;
- }
- remove
- {
- _onUpdatedPurchasesReceived -= 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.Launch(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);
+ return _backingInstance;
}
///
- /// 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.
+ /// 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.
///
- /// Defined enum key that will be transformed to string.
- /// Property value.
- /// User Properties
- public static void SetProperty(UserProperty key, string value)
+ /// 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)
{
- IQonversionWrapper instance = getFinalInstance();
- instance.SetProperty(key, value);
+ _backingInstance = QonversionInternal.CreateInstance();
+ _backingInstance?.InitializeInstance(config);
+ return _backingInstance;
}
- ///
- /// 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.CheckPermissions(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);
- }
-
- ///
- /// 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.
- ///
- /// 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)
- {
- UpdatePurchaseCallback = callback;
- IQonversionWrapper instance = getFinalInstance();
- instance.UpdatePurchase(productId, oldProductId, prorationMode, OnUpdatePurchaseMethodName);
- }
-
- ///
- /// 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 CheckTrialIntroEligibilityForProductIds(IList productIds, OnEligibilitiesReceived callback)
- {
- var productIdsJson = Json.Serialize(productIds);
-
- EligibilitiesCallback = callback;
- IQonversionWrapper instance = getFinalInstance();
- instance.CheckTrialIntroEligibilityForProductIds(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 OnReceiveUpdatedPurchases(string jsonString)
- {
- Debug.Log("OnReceiveUpdatedPurchases " + jsonString);
-
- if (_onUpdatedPurchasesReceived == null)
- {
- return;
- }
-
- Dictionary permissions = Mapper.PermissionsFromJson(jsonString);
- _onUpdatedPurchasesReceived(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..ce17f2e
--- /dev/null
+++ b/Runtime/iOS/AutomationsWrapperIOS.cs
@@ -0,0 +1,77 @@
+#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 _initializeAutomations(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
+ _initializeAutomations(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/Plugins/AutomationsBridge.m b/Runtime/iOS/Plugins/AutomationsBridge.m
new file mode 100644
index 0000000..8f5e777
--- /dev/null
+++ b/Runtime/iOS/Plugins/AutomationsBridge.m
@@ -0,0 +1,55 @@
+#import "UtilityBridge.h"
+#import "QNUAutomationsDelegate.h"
+@import QonversionSandwich;
+
+char* automationsUnityListenerName = nil;
+
+static QNUAutomationsDelegate *automationsBridge;
+
+void _initializeAutomations(const char* unityListener) {
+ unsigned long len = strlen(unityListener);
+ automationsUnityListenerName = malloc(len + 1);
+ strcpy(automationsUnityListenerName, unityListener);
+
+ automationsBridge = [[QNUAutomationsDelegate alloc] initWithListenerName:automationsUnityListenerName];
+}
+
+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;
+}
+
+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];
+
+ char* cString = (char*)malloc(strlen(data) + 1);
+ strcpy(cString, data);
+
+ return cString;
+}
+
+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/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/Common/QNUAutomationsDelegate.h b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h
index 3535d4c..692820f 100644
--- a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h
+++ b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.h
@@ -14,6 +14,10 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithListenerName:(char *)unityListenerName;
- (void)subscribe;
+- (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 10e4f5f..55235e0 100644
--- a/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m
+++ b/Runtime/iOS/Plugins/Common/QNUAutomationsDelegate.m
@@ -47,10 +47,28 @@ - (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];
[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) {
+ [UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:listenerName];
+ }];
+}
+
@end
diff --git a/Runtime/iOS/Plugins/QonversionBridge.m b/Runtime/iOS/Plugins/QonversionBridge.m
index 89237ae..7247469 100644
--- a/Runtime/iOS/Plugins/QonversionBridge.m
+++ b/Runtime/iOS/Plugins/QonversionBridge.m
@@ -1,29 +1,27 @@
#import "UtilityBridge.h"
-#import "QNUAutomationsDelegate.h"
@import QonversionSandwich;
char* unityListenerName = nil;
@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 QonversionSandwich *qonversionSandwich;
void _initialize(const char* unityListener) {
@@ -32,7 +30,15 @@ void _initialize(const char* unityListener) {
strcpy(unityListenerName, unityListener);
qonversionSandwich = [[QonversionSandwich alloc] initWithQonversionEventListener:[QonversionEventListenerWrapper new]];
- automationsDelegate = [[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];
}
void _storeSdkInfo(const char* version, const char* source) {
@@ -42,22 +48,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 +59,7 @@ void _presentCodeRedemptionSheet() {
}
void _setAppleSearchAdsAttributionEnabled(const bool enable) {
- [qonversionSandwich setAppleSearchAdsAttributionEnabled:enable];
+ [qonversionSandwich collectAppleSearchAdsAttribution];
}
void _setProperty(const char* propertyName, const char* value) {
@@ -88,7 +80,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) {
@@ -96,6 +88,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];
}
@@ -103,7 +103,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];
}];
}
@@ -151,7 +151,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];
@@ -178,39 +178,3 @@ void _promoPurchase(const char* storeProductId, const char* unityCallbackName) {
[UtilityBridge handleResult:result error:error callbackName:callbackName unityListener:unityListenerName];
}];
}
-
-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];
-}
-
-bool _handleNotification(const char* notification) {
- NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]];
-
- BOOL isQonversionNotification = [qonversionSandwich handleNotification:notificationInfo];
-
- return isQonversionNotification;
-}
-
-const char* _getNotificationCustomPayload(const char* notification) {
- NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString: [UtilityBridge сonvertCStringToNSString: notification]];
-
- NSDictionary *payload = [qonversionSandwich getNotificationCustomPayload:notificationInfo];
-
- if (payload == nil) {
- return nil;
- }
-
- const char *data = [UtilityBridge jsonStringFromObject:payload];
-
- return data;
-}
-
-void _subscribeOnAutomationEvents() {
- [automationsDelegate subscribe];
-}
diff --git a/Runtime/iOS/QonversionWrapperIOS.cs b/Runtime/iOS/QonversionWrapperIOS.cs
index c4ec360..2624c89 100644
--- a/Runtime/iOS/QonversionWrapperIOS.cs
+++ b/Runtime/iOS/QonversionWrapperIOS.cs
@@ -15,10 +15,10 @@ internal class QonversionWrapperIOS : IQonversionWrapper
private static extern void _initialize(string gameObjectName);
[DllImport("__Internal")]
- private static extern void _storeSdkInfo(string version, string source);
+ private static extern void _initializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime);
[DllImport("__Internal")]
- private static extern void _setDebugMode();
+ private static extern void _storeSdkInfo(string version, string source);
[DllImport("__Internal")]
private static extern void _setAdvertisingID();
@@ -38,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);
@@ -50,6 +47,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);
@@ -63,28 +63,13 @@ 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);
- [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 +86,10 @@ public void StoreSdkInfo(string version, string source)
#endif
}
- public void Launch(string projectKey, bool observerMode, string callbackName)
+ public void InitializeSdk(string projectKey, string launchMode, string environment, string entitlementsCacheLifetime)
{
#if UNITY_IOS
- _launchWithKey(projectKey, callbackName);
+ _initializeSdk(projectKey, launchMode, environment, entitlementsCacheLifetime);
#endif
}
@@ -112,13 +97,6 @@ public void SyncPurchases()
{
}
- public void SetDebugMode()
- {
-#if UNITY_IOS
- _setDebugMode();
-#endif
- }
-
public void SetAdvertisingID()
{
#if UNITY_IOS
@@ -141,11 +119,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 +147,13 @@ public void Logout()
#endif
}
+ public void UserInfo(string callbackName)
+ {
+#if UNITY_IOS
+ _userInfo(callbackName);
+#endif
+ }
+
public void PresentCodeRedemptionSheet()
{
#if UNITY_IOS
@@ -177,7 +161,7 @@ public void PresentCodeRedemptionSheet()
#endif
}
- public void CheckPermissions(string callbackName)
+ public void CheckEntitlements(string callbackName)
{
#if UNITY_IOS
_checkPermissions(callbackName);
@@ -227,10 +211,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
}
@@ -238,45 +222,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 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}\";"
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:
diff --git a/package.json b/package.json
index 2fb7af6..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": {
@@ -29,5 +29,6 @@
"/Runtime.meta",
"/Editor",
"/Editor.meta"
- ]
+ ],
+ "dependencies": {}
}