Skip to content

Commit

Permalink
Release 7.3.0
Browse files Browse the repository at this point in the history
Release 7.3.0
  • Loading branch information
SpertsyanKM committed Apr 4, 2024
2 parents d0f3bdc + 7a3583b commit 3b82184
Show file tree
Hide file tree
Showing 17 changed files with 283 additions and 62 deletions.
4 changes: 2 additions & 2 deletions Editor/QonversionDependencies.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<androidPackages>
<androidPackage spec="io.qonversion.sandwich:sandwich:4.2.0" />
<androidPackage spec="io.qonversion.sandwich:sandwich:4.3.1" />
<androidPackage spec="com.fasterxml.jackson.core:jackson-databind:2.11.1" />
<androidPackage spec="org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.61" />
</androidPackages>
<iosPods>
<iosPod name="QonversionSandwich" version="4.2.0" />
<iosPod name="QonversionSandwich" version="4.3.1" />
</iosPods>
</dependencies>
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,23 @@ public static synchronized void remoteConfig(String contextKey, String unityCall
qonversionSandwich.remoteConfig(contextKey, getRemoteConfigResultListener(contextKey, unityCallbackName));
}

public static synchronized void remoteConfigList(String unityCallbackName) {
qonversionSandwich.remoteConfigList(getResultListener(unityCallbackName));
}

public static synchronized void remoteConfigList(String contextKeysJson, boolean includeEmptyContextKey, String unityCallbackName) {
try {
ObjectMapper mapper = new ObjectMapper();

TypeReference<List<String>> typeRef = new TypeReference<List<String>>() {};
List<String> contextKeys = mapper.readValue(contextKeysJson, typeRef);

qonversionSandwich.remoteConfigList(contextKeys, includeEmptyContextKey, getResultListener(unityCallbackName));
} catch (JsonProcessingException e) {
handleSerializationException(e);
}
}

public static synchronized void attachUserToExperiment(String experimentId, String groupId, String unityCallbackName) {
qonversionSandwich.attachUserToExperiment(experimentId, groupId, getResultListener(unityCallbackName));
}
Expand Down
10 changes: 10 additions & 0 deletions Runtime/Android/QonversionWrapperAndroid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,16 @@ public void RemoteConfig(string contextKey, string callbackName)
CallQonversion("remoteConfig", contextKey, callbackName);
}

public void RemoteConfigList(string callbackName)
{
CallQonversion("remoteConfigList", callbackName);
}

public void RemoteConfigList(string contextKeysJson, bool includeEmptyContextKey, string callbackName)
{
CallQonversion("remoteConfigList", contextKeysJson, includeEmptyContextKey, callbackName);
}

public void AttachUserToExperiment(string experimentId, string groupId, string callbackName)
{
CallQonversion("attachUserToExperiment", experimentId, groupId, callbackName);
Expand Down
42 changes: 42 additions & 0 deletions Runtime/Scripts/Dto/RemoteConfigList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;

namespace QonversionUnity
{
public class RemoteConfigList
{
public readonly List<RemoteConfig> RemoteConfigs;

public RemoteConfigList(Dictionary<string, object> dict)
{
if (dict.TryGetValue("remoteConfigs", out object value) && value is List<object> offerings)
{
RemoteConfigs = Mapper.ConvertObjectsList<RemoteConfig>(offerings);
}
}

[CanBeNull]
public RemoteConfig RemoteConfigForContextKey(String contextKey)
{
return FindRemoteConfig(contextKey);
}

[CanBeNull]
public RemoteConfig RemoteConfigForEmptyContextKey()
{
return FindRemoteConfig(null);
}

[CanBeNull]
private RemoteConfig FindRemoteConfig([CanBeNull] String contextKey)
{
return RemoteConfigs.Find(remoteConfig => remoteConfig.Source.ContextKey == contextKey);
}

public override string ToString()
{
return $"{nameof(RemoteConfigs)}: {Utils.PrintObjectList(RemoteConfigs)}";
}
}
}
3 changes: 3 additions & 0 deletions Runtime/Scripts/Dto/RemoteConfigList.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 20 additions & 2 deletions Runtime/Scripts/IQonversion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public interface IQonversion
/// Use this function to get the remote config with specific payload and experiment info.
/// </summary>
/// <param name="callback">Callback that will be called when response is received.</param>
/// <see href="https://documentation.qonversion.io/docs/experiments-overview">Experiments</see>
/// <see href="https://documentation.qonversion.io/docs/remote-config">Remote Configs</see>
public void RemoteConfig(Qonversion.OnRemoteConfigReceived callback);

/// <summary>
Expand All @@ -83,9 +83,27 @@ public interface IQonversion
/// </summary>
/// <param name="contextKey">Context key to get remote config for.</param>
/// <param name="callback">Callback that will be called when response is received.</param>
/// <see href="https://documentation.qonversion.io/docs/experiments-overview">Experiments</see>
/// <see href="https://documentation.qonversion.io/docs/remote-config">Remote Configs</see>
public void RemoteConfig(string contextKey, Qonversion.OnRemoteConfigReceived callback);

/// <summary>
/// Returns Qonversion remote config objects for all existing context key (including empty one).
/// Use this function to get the remote configs with specific payload and experiment info.
/// </summary>
/// <param name="callback">Callback that will be called when response is received.</param>
/// <see href="https://documentation.qonversion.io/docs/remote-config">Remote Configs</see>
public void RemoteConfigList(Qonversion.OnRemoteConfigListReceived callback);

/// <summary>
/// Returns Qonversion remote config objects by a list of context keys.
/// Use this function to get the remote configs with specific payload and experiment info.
/// </summary>
/// <param name="contextKeys">List of context keys to load remote configs for</param>
/// <param name="includeEmptyContextKey">Set to true if you want to include remote config with empty context key to the result.</param>
/// <param name="callback">Callback that will be called when response is received.</param>
/// <see href="https://documentation.qonversion.io/docs/remote-config">Remote Configs</see>
public void RemoteConfigList(string[] contextKeys, bool includeEmptyContextKey, Qonversion.OnRemoteConfigListReceived callback);

/// <summary>
/// This function should be used for the test purposes only. Do not forget to delete the usage of this function before the release.
/// Use this function to attach the user to the experiment.
Expand Down
11 changes: 11 additions & 0 deletions Runtime/Scripts/Internal/Mapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ internal static RemoteConfig RemoteConfigFromJson(string jsonStr)
return new RemoteConfig(remoteConfig);
}

internal static RemoteConfigList RemoteConfigListFromJson(string jsonStr)
{
if (!(Json.Deserialize(jsonStr) is Dictionary<string, object> remoteConfigList))
{
Debug.LogError("Could not parse RemoteConfigList");
return null;
}

return new RemoteConfigList(remoteConfigList);
}

internal static ActionResult ActionResultFromJson(string jsonStr)
{
if (!(Json.Deserialize(jsonStr) is Dictionary<string, object> actionResult))
Expand Down
66 changes: 59 additions & 7 deletions Runtime/Scripts/Internal/QonversionInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ internal class QonversionInternal : MonoBehaviour, IQonversion
private const string OnProductsMethodName = "OnProducts";
private const string OnOfferingsMethodName = "OnOfferings";
private const string OnRemoteConfigMethodName = "OnRemoteConfig";
private const string OnRemoteConfigListMethodName = "OnRemoteConfigList";
private const string OnRemoteConfigListForContextKeysMethodName = "OnRemoteConfigListForContextKeys";
private const string OnEligibilitiesMethodName = "OnEligibilities";
private const string OnUserInfoMethodName = "OnUserInfo";
private const string OnUserPropertiesMethodName = "OnUserProperties";
private const string OnAttachUserMethodName = "OnAttachUser";
private const string OnDetachUserMethodName = "OnDetachUser";

private const string SdkVersion = "7.2.0";
private const string SdkVersion = "7.3.0";
private const string SdkSource = "unity";

private const string DefaultRemoteConfigContextKey = "";
Expand All @@ -41,6 +43,8 @@ internal class QonversionInternal : MonoBehaviour, IQonversion
private List<Qonversion.OnProductsReceived> ProductsCallbacks { get; } = new List<Qonversion.OnProductsReceived>();
private List<Qonversion.OnOfferingsReceived> OfferingsCallbacks { get; } = new List<Qonversion.OnOfferingsReceived>();
private Dictionary<string, List<Qonversion.OnRemoteConfigReceived>> RemoteConfigCallbacks { get; } = new Dictionary<string, List<Qonversion.OnRemoteConfigReceived>>();
private Qonversion.OnRemoteConfigListReceived RemoteConfigListCallback { get; set; }
private Qonversion.OnRemoteConfigListReceived RemoteConfigListForContextKeysCallback { get; set; }
private Qonversion.OnEligibilitiesReceived EligibilitiesCallback { get; set; }
private Qonversion.OnEntitlementsReceived PromoPurchaseCallback { get; set; }
private Qonversion.OnUserInfoReceived UserInfoCallback { get; set; }
Expand Down Expand Up @@ -142,18 +146,35 @@ public void RemoteConfig(string contextKey, Qonversion.OnRemoteConfigReceived ca
{
LoadRemoteConfig(contextKey, callback);
}

private void LoadRemoteConfig([CanBeNull] string contextKey, Qonversion.OnRemoteConfigReceived callback)
{
var key = contextKey ?? DefaultRemoteConfigContextKey;
if (!RemoteConfigCallbacks.ContainsKey(key)) {
RemoteConfigCallbacks[key] = new List<Qonversion.OnRemoteConfigReceived>();
}

RemoteConfigCallbacks[key].Add(callback);
var instance = GetNativeWrapper();
instance.RemoteConfig(contextKey, OnRemoteConfigMethodName);
}

public void RemoteConfigList(Qonversion.OnRemoteConfigListReceived callback)
{
RemoteConfigListCallback = callback;
var instance = GetNativeWrapper();
instance.RemoteConfigList(OnRemoteConfigListMethodName);
}

public void RemoteConfigList(string[] contextKeys, bool includeEmptyContextKey, Qonversion.OnRemoteConfigListReceived callback)
{
RemoteConfigListForContextKeysCallback = callback;
var contextKeysJson = contextKeys.toJson();

var instance = GetNativeWrapper();
instance.RemoteConfigList(contextKeysJson, includeEmptyContextKey, OnRemoteConfigListForContextKeysMethodName);
}

public void AttachUserToExperiment(string experimentId, string groupId, Qonversion.OnAttachUserResponseReceived callback)
{
AttachUserCallback = callback;
Expand Down Expand Up @@ -229,7 +250,7 @@ public void UserInfo(Qonversion.OnUserInfoReceived callback)
IQonversionWrapper instance = GetNativeWrapper();
instance.UserInfo(OnUserInfoMethodName);
}

public void Attribution(Dictionary<string, object> conversionData, AttributionProvider attributionProvider)
{
Attribution(conversionData.toJson(), attributionProvider);
Expand All @@ -243,14 +264,16 @@ public void Attribution(string conversionData, AttributionProvider attributionPr

instance.AddAttributionData(conversionData, providerName);
}

public void SetUserProperty(UserPropertyKey key, string value)
{
if (key == UserPropertyKey.Custom) {
Debug.LogWarning("Can not set user property with the key `UserPropertyKey.Custom`. " +
if (key == UserPropertyKey.Custom)
{
Debug.LogWarning("Can not set user property with the key `UserPropertyKey.Custom`. " +
"To set custom user property, use the `SetCustomUserProperty` method.");
return;
}

IQonversionWrapper instance = GetNativeWrapper();
instance.SetUserProperty(key, value);
}
Expand All @@ -261,7 +284,8 @@ public void SetCustomUserProperty(string key, string value)
instance.SetCustomUserProperty(key, value);
}

public void UserProperties(Qonversion.OnUserPropertiesReceived callback) {
public void UserProperties(Qonversion.OnUserPropertiesReceived callback)
{
UserPropertiesCallback = callback;
IQonversionWrapper instance = GetNativeWrapper();
instance.UserProperties(OnUserPropertiesMethodName);
Expand Down Expand Up @@ -405,6 +429,34 @@ private void OnRemoteConfig(string jsonString)
}
}

// Called from the native SDK - Called when remoteConfigList received from the remoteConfigList() method without context keys
private void OnRemoteConfigList(string jsonString)
{
OnRemoteConfigListResult(jsonString, RemoteConfigListCallback);
}

// Called from the native SDK - Called when remoteConfigList received from the remoteConfigList() method with context keys
private void OnRemoteConfigListForContextKeys(string jsonString)
{
OnRemoteConfigListResult(jsonString, RemoteConfigListForContextKeysCallback);
}

private void OnRemoteConfigListResult(string jsonString, Qonversion.OnRemoteConfigListReceived callback)
{
if (callback == null) return;

var error = Mapper.ErrorFromJson(jsonString);
if (error != null)
{
callback(null, error);
}
else
{
var remoteConfigList = Mapper.RemoteConfigListFromJson(jsonString);
callback(remoteConfigList, null);
}
}

private void OnAttachUser(string jsonString)
{
if (AttachUserCallback == null) return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using System.Collections.Generic;
using JetBrains.Annotations;

namespace QonversionUnity
{
Expand All @@ -22,6 +23,8 @@ internal interface IQonversionWrapper
void Products(string callbackName);
void Offerings(string callbackName);
void RemoteConfig([CanBeNull] string contextKey, string callbackName);
void RemoteConfigList(string callbackName);
void RemoteConfigList(string contextKeysJson, bool includeEmptyContextKey, string callbackName);
void AttachUserToExperiment(string experimentId, string groupId, string callbackName);
void DetachUserFromExperiment(string experimentId, string callbackName);
void AttachUserToRemoteConfiguration(string remoteConfigurationId, string callbackName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ public void RemoteConfig(string contextKey, string callbackName)
{
}

public void RemoteConfigList(string callbackName)
{
}

public void RemoteConfigList(string contextKeysJson, bool includeEmptyContextKey, string callbackName)
{
}

public void AttachUserToExperiment(string experimentId, string groupId, string callbackName)
{
}
Expand Down
1 change: 1 addition & 0 deletions Runtime/Scripts/Qonversion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public static IQonversion Initialize(QonversionConfig config)
public delegate void OnProductsReceived(Dictionary<string, Product> products, QonversionError error);
public delegate void OnOfferingsReceived(Offerings offerings, QonversionError error);
public delegate void OnRemoteConfigReceived(RemoteConfig remoteConfig, QonversionError error);
public delegate void OnRemoteConfigListReceived(RemoteConfigList remoteConfigList, QonversionError error);
public delegate void OnUserPropertiesReceived(UserProperties userProperties, QonversionError error);
public delegate void OnAttachUserResponseReceived(bool success, QonversionError error);
public delegate void OnEligibilitiesReceived(Dictionary<string, Eligibility> eligibilities, QonversionError error);
Expand Down
14 changes: 7 additions & 7 deletions Runtime/iOS/Plugins/AutomationsBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ void _initializeAutomations(const char* unityListener) {
}

void _setNotificationsToken(const char* token) {
NSString *tokenStr = [UtilityBridge сonvertCStringToNSString:token];
NSString *tokenStr = [UtilityBridge convertCStringToNSString:token];
[automationsBridge setNotificationsToken:tokenStr];
}

bool _handleNotification(const char* notification) {
NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString:[UtilityBridge сonvertCStringToNSString:notification]];
NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString:[UtilityBridge convertCStringToNSString:notification]];

BOOL isQonversionNotification = [automationsBridge handleNotification:notificationInfo];

return isQonversionNotification;
}

char* _getNotificationCustomPayload(const char* notification) {
NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString:[UtilityBridge сonvertCStringToNSString:notification]];
NSDictionary *notificationInfo = [UtilityBridge dictionaryFromJsonString:[UtilityBridge convertCStringToNSString:notification]];

NSDictionary *payload = [automationsBridge getNotificationCustomPayload:notificationInfo];

Expand All @@ -45,8 +45,8 @@ bool _handleNotification(const char* notification) {
}

void _showScreen(const char* screenId, const char* unityCallbackName) {
NSString *callbackName = [UtilityBridge сonvertCStringToNSString:unityCallbackName];
NSString *screenIdStr = [UtilityBridge сonvertCStringToNSString:screenId];
NSString *callbackName = [UtilityBridge convertCStringToNSString:unityCallbackName];
NSString *screenIdStr = [UtilityBridge convertCStringToNSString:screenId];
[automationsBridge showScreenWithId:screenIdStr callbackName:callbackName];
}

Expand All @@ -55,7 +55,7 @@ void _subscribeOnAutomationEvents() {
}

void _setScreenPresentationConfig(const char* configData, const char* screenId) {
NSDictionary *config = [UtilityBridge dictionaryFromJsonString:[UtilityBridge сonvertCStringToNSString:configData]];
NSString *screenIdStr = [UtilityBridge сonvertCStringToNSString:screenId];
NSDictionary *config = [UtilityBridge dictionaryFromJsonString:[UtilityBridge convertCStringToNSString:configData]];
NSString *screenIdStr = [UtilityBridge convertCStringToNSString:screenId];
[automationsBridge setScreenPresentationConfig:config screenId:screenIdStr];
}
3 changes: 2 additions & 1 deletion Runtime/iOS/Plugins/Common/UtilityBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

@interface UtilityBridge : NSObject

+ (NSString*)сonvertCStringToNSString:(const char *)string;
+ (NSString*)convertCStringToNSString:(const char *)string;
+ (NSDictionary*)dictionaryFromJsonString:(NSString*) jsonString;
+ (NSArray*)arrayFromJsonString:(NSString*) jsonString;
+ (NSDictionary *)convertError:(SandwichError *)error;
+ (NSDictionary *)convertSandwichError:(SandwichError *)error;
+ (const char *)jsonStringFromObject:(NSObject *)objectToConvert;
Expand Down
Loading

0 comments on commit 3b82184

Please sign in to comment.