Skip to content

Commit

Permalink
Merge pull request #29 from qonversion/release/3.0.0
Browse files Browse the repository at this point in the history
Release 3.0.0
  • Loading branch information
suriksarkisyan committed Jul 21, 2023
2 parents f631a59 + d3428e7 commit 4ba5465
Show file tree
Hide file tree
Showing 15 changed files with 237 additions and 46 deletions.
2 changes: 1 addition & 1 deletion plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-qonversion",
"version": "2.0.0",
"version": "3.0.0",
"description": "Qonversion Cordova Plugin",
"cordova": {
"id": "cordova-plugin-qonversion",
Expand Down
7 changes: 5 additions & 2 deletions plugin/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<js-module src="www/dto/Offering.js" name="dto/Offering" />
<js-module src="www/dto/Offerings.js" name="dto/Offerings" />
<js-module src="www/dto/Product.js" name="dto/Product" />
<js-module src="www/dto/Experiment.js" name="dto/Experiment" />
<js-module src="www/dto/ExperimentGroup.js" name="dto/ExperimentGroup" />
<js-module src="www/dto/RemoteConfig.js" name="dto/RemoteConfig" />
<js-module src="www/dto/QonversionError.js" name="dto/QonversionError" />
<js-module src="www/dto/User.js" name="dto/User" />
<js-module src="www/dto/storeProducts/SKProduct.js" name="dto/storeProducts/SKProduct" />
Expand All @@ -38,7 +41,7 @@
<param name="android-package" value="com.qonversion.android.sdk.QonversionPlugin"/>
</feature>
</config-file>
<framework src="io.qonversion.sandwich:sandwich:1.5.2" />
<framework src="io.qonversion.sandwich:sandwich:2.0.2" />
<source-file src="src/android/QonversionPlugin.java" target-dir="src/com/qonversion/android/sdk" />
<source-file src="src/android/EntitiesConverter.java" target-dir="src/com/qonversion/android/sdk" />
<source-file src="src/android/Utils.java" target-dir="src/com/qonversion/android/sdk" />
Expand All @@ -56,7 +59,7 @@
<source url="https://github.com/CocoaPods/Specs.git"/>
</config>
<pods use-frameworks="true">
<pod name="QonversionSandwich" spec="1.5.2" />
<pod name="QonversionSandwich" spec="2.0.2" />
</pods>
</podspec>
</platform>
Expand Down
17 changes: 17 additions & 0 deletions plugin/src/android/QonversionPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import io.qonversion.sandwich.PurchaseResultListener;
import io.qonversion.sandwich.QonversionEventsListener;
import io.qonversion.sandwich.QonversionSandwich;
import io.qonversion.sandwich.ResultListener;
import io.qonversion.sandwich.SandwichError;

public class QonversionPlugin extends AnnotatedCordovaPlugin implements QonversionEventsListener {
Expand Down Expand Up @@ -181,6 +183,21 @@ public void restore(CallbackContext callbackContext) {
qonversionSandwich.restore(Utils.getResultListener(callbackContext));
}

@PluginAction(thread = ExecutionThread.UI, actionName = "remoteConfig", isAutofinish = false)
public void remoteConfig(CallbackContext callbackContext) {
qonversionSandwich.remoteConfig(Utils.getResultListener(callbackContext));
}

@PluginAction(thread = ExecutionThread.UI, actionName = "attachUserToExperiment", isAutofinish = false)
public void attachUserToExperiment(String experimentId, String groupId, CallbackContext callbackContext) {
qonversionSandwich.attachUserToExperiment(experimentId, groupId, Utils.getEmptyResultListener(callbackContext));
}

@PluginAction(thread = ExecutionThread.UI, actionName = "detachUserFromExperiment", isAutofinish = false)
public void detachUserFromExperiment(String experimentId, CallbackContext callbackContext) {
qonversionSandwich.detachUserFromExperiment(experimentId, Utils.getEmptyResultListener(callbackContext));
}

@PluginAction(thread = ExecutionThread.WORKER, actionName = "syncPurchases", isAutofinish = false)
public void syncPurchases(CallbackContext callbackContext) {
qonversionSandwich.syncPurchases();
Expand Down
15 changes: 15 additions & 0 deletions plugin/src/android/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
import org.json.JSONObject;

public class Utils {

static ResultListener getEmptyResultListener(CallbackContext callbackContext) {
return new ResultListener() {
@Override
public void onSuccess(@NonNull Map<String, ?> map) {
callbackContext.success(new JSONObject());
}

@Override
public void onError(@NonNull SandwichError sandwichError) {
Utils.rejectWithError(sandwichError, callbackContext);
}
};
}

static ResultListener getResultListener(CallbackContext callbackContext) {
return new ResultListener() {
@Override
Expand Down
3 changes: 3 additions & 0 deletions plugin/src/ios/CDVQonversionPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ NS_ASSUME_NONNULL_BEGIN
- (void)collectAppleSearchAdsAttribution:(CDVInvokedUrlCommand *)command;
- (void)promoPurchase:(CDVInvokedUrlCommand *)command;
- (void)subscribeOnPromoPurchases:(CDVInvokedUrlCommand *)command;
- (void)remoteConfig:(CDVInvokedUrlCommand *)command;
- (void)attachUserToExperiment:(CDVInvokedUrlCommand *)command;
- (void)detachUserFromExperiment:(CDVInvokedUrlCommand *)command;

@end

Expand Down
32 changes: 32 additions & 0 deletions plugin/src/ios/CDVQonversionPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,38 @@ - (void)checkTrialIntroEligibilityForProductIds:(CDVInvokedUrlCommand *)command
}];
}

- (void)remoteConfig:(CDVInvokedUrlCommand *)command {
__block __weak CDVQonversionPlugin *weakSelf = self;
[self.qonversionSandwich remoteConfig:^(NSDictionary<NSString *,id> * _Nullable result, SandwichError * _Nullable error) {
[weakSelf returnCordovaResult:result error:error command:command];
}];
}

- (void)attachUserToExperiment:(CDVInvokedUrlCommand *)command {
__block __weak CDVQonversionPlugin *weakSelf = self;
NSString *experimentId = [command argumentAtIndex:0];
NSString *groupId = [command argumentAtIndex:1];
[self.qonversionSandwich attachUserToExperimentWith:experimentId groupId:groupId completion:^(NSDictionary<NSString *,id> * _Nullable result, SandwichError * _Nullable error) {
if (error) {
[weakSelf returnCordovaResult:nil error:error command:command];
} else {
[weakSelf returnCordovaResult:@{} error:nil command:command];
}
}];
}

- (void)detachUserFromExperiment:(CDVInvokedUrlCommand *)command {
__block __weak CDVQonversionPlugin *weakSelf = self;
NSString *experimentId = [command argumentAtIndex:0];
[self.qonversionSandwich detachUserFromExperimentWith:experimentId completion:^(NSDictionary<NSString *,id> * _Nullable result, SandwichError * _Nullable error) {
if (error) {
[weakSelf returnCordovaResult:nil error:error command:command];
} else {
[weakSelf returnCordovaResult:@{} error:nil command:command];
}
}];
}

- (void)identify:(CDVInvokedUrlCommand *)command {
NSString *identityId = [command argumentAtIndex:0];
[self.qonversionSandwich identify:identityId];
Expand Down
43 changes: 43 additions & 0 deletions plugin/src/plugin/Mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
SKProductDiscountType,
TrialDuration,
TrialDurations,
ExperimentGroupType,
} from "./dto/enums";
import {IntroEligibility} from "./dto/IntroEligibility";
import {Offering} from "./dto/Offering";
Expand All @@ -27,6 +28,9 @@ import {ActionResult} from "./dto/ActionResult";
import {QonversionError} from "./dto/QonversionError";
import {AutomationsEvent} from "./dto/AutomationsEvent";
import {User} from './dto/User';
import RemoteConfig from "./dto/RemoteConfig";
import ExperimentGroup from "./dto/ExperimentGroup";
import Experiment from "./dto/Experiment";

export type QProduct = {
id: string;
Expand Down Expand Up @@ -138,6 +142,23 @@ export type QUser = {
identityId?: string | null;
};

export type QRemoteConfig = {
payload: Map<string, Object>;
experiment?: QExperiment | null;
};

export type QExperiment = {
id: string;
name: string;
group: QExperimentGroup;
}

export type QExperimentGroup = {
id: string;
name: string;
type: string;
}

const skuDetailsPriceRatio = 1000000;

class Mapper {
Expand Down Expand Up @@ -483,6 +504,28 @@ class Mapper {
static convertUserInfo(user: QUser) {
return new User(user.qonversionId, user.identityId);
}

static convertRemoteConfig(remoteConfig: QRemoteConfig): RemoteConfig {
let experiment = null;
if (remoteConfig.experiment) {
const groupType = this.convertGroupType(remoteConfig.experiment.group.type);
const group = new ExperimentGroup(remoteConfig.experiment.group.id, remoteConfig.experiment.group.name, groupType);
experiment = new Experiment(remoteConfig.experiment.id, remoteConfig.experiment.name, group);
}

return new RemoteConfig(remoteConfig.payload, experiment);
}

static convertGroupType(type: String): ExperimentGroupType {
switch (type) {
case "control":
return ExperimentGroupType.CONTROL;
case "treatment":
return ExperimentGroupType.TREATMENT;
default:
return ExperimentGroupType.UNKNOWN;
}
}
}

export default Mapper;
25 changes: 25 additions & 0 deletions plugin/src/plugin/QonversionApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {IntroEligibility} from './dto/IntroEligibility';
import {User} from './dto/User';
import {EntitlementsUpdateListener} from './dto/EntitlementsUpdateListener';
import {PromoPurchasesListener} from './dto/PromoPurchasesListener';
import RemoteConfig from "./dto/RemoteConfig";

export interface QonversionApi {

Expand Down Expand Up @@ -165,6 +166,30 @@ export interface QonversionApi {
*/
userInfo(): Promise<User>;

/**
* Returns Qonversion remote config object
* Use this function to get the remote config with specific payload and experiment info.
* @returns the promise with the remote config.
*/
remoteConfig(): Promise<RemoteConfig>

/**
* 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.
* @param experimentId identifier of the experiment
* @param groupId identifier of the experiment group
* @returns the promise for success result or throws an error otherwise.
*/
attachUserToExperiment(experimentId: string, groupId: string): Promise<void>

/**
* 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 detach the user from the experiment.
* @param experimentId identifier of the experiment
* @returns the promise for success result or throws an error otherwise.
*/
detachUserFromExperiment(experimentId: string): Promise<void>

/**
* Sends your attribution {@link data} to the {@link provider}.
*
Expand Down
25 changes: 23 additions & 2 deletions plugin/src/plugin/QonversionInternal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {UserProperty, ProrationMode, AttributionProvider} from "./dto/enums";
import {IntroEligibility} from "./dto/IntroEligibility";
import Mapper, {QEntitlement, QOfferings, QProduct, QTrialIntroEligibility, QUser} from "./Mapper";
import Mapper, {QEntitlement, QOfferings, QProduct, QTrialIntroEligibility, QUser, QRemoteConfig} from "./Mapper";
import {Offerings} from "./dto/Offerings";
import {Entitlement} from "./dto/Entitlement";
import {Product} from "./dto/Product";
Expand All @@ -10,8 +10,9 @@ import {User} from './dto/User';
import {QonversionApi} from './QonversionApi';
import {QonversionConfig} from './QonversionConfig';
import {EntitlementsUpdateListener} from './dto/EntitlementsUpdateListener';
import RemoteConfig from "./dto/RemoteConfig";

const sdkVersion = "2.0.0";
const sdkVersion = "3.0.0";

export default class QonversionInternal implements QonversionApi {

Expand Down Expand Up @@ -236,6 +237,26 @@ export default class QonversionInternal implements QonversionApi {
return mappedUserInfo;
}

async remoteConfig(): Promise<RemoteConfig> {
let remoteConfig = await callNative<QRemoteConfig>('remoteConfig');
// noinspection UnnecessaryLocalVariableJS
const mappedRemoteConfig: RemoteConfig = Mapper.convertRemoteConfig(
remoteConfig
);

return mappedRemoteConfig;
}

async attachUserToExperiment(experimentId: string, groupId: string): Promise<void> {
await callNative('attachUserToExperiment', [experimentId, groupId]);
return;
}

async detachUserFromExperiment(experimentId: string): Promise<void> {
await callNative('detachUserFromExperiment', [experimentId]);
return;
}

attribution(data: Object, provider: AttributionProvider) {
callNative('attribution', [data, provider]).then(noop);
}
Expand Down
15 changes: 15 additions & 0 deletions plugin/src/plugin/dto/Experiment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import ExperimentGroup from "./ExperimentGroup";

class Experiment {
id: string;
name: string;
group: ExperimentGroup;

constructor(id: string, name: string, group: ExperimentGroup) {
this.id = id;
this.name = name;
this.group = group;
}
}

export default Experiment;
15 changes: 15 additions & 0 deletions plugin/src/plugin/dto/ExperimentGroup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ExperimentGroupType } from "./enums";

class ExperimentGroup {
id: string;
name: string;
type: ExperimentGroupType;

constructor(id: string, name: string, type: ExperimentGroupType) {
this.id = id;
this.name = name;
this.type = type;
}
}

export default ExperimentGroup;
13 changes: 13 additions & 0 deletions plugin/src/plugin/dto/RemoteConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Experiment from "./Experiment";

class RemoteConfig {
payload: Map<string, Object>;
experiment?: Experiment | null;

constructor(payload: Map<string, Object>, experiment: Experiment | null) {
this.payload = payload;
this.experiment = experiment;
}
}

export default RemoteConfig;
6 changes: 6 additions & 0 deletions plugin/src/plugin/dto/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,9 @@ export enum AutomationsEventType {
SUBSCRIPTION_DOWNGRADED = "subscription_downgraded",
SUBSCRIPTION_PRODUCT_CHANGED = "subscription_product_changed",
}

export enum ExperimentGroupType {
UNKNOWN = "unknown",
CONTROL = "control",
TREATMENT = "treatment",
}
12 changes: 5 additions & 7 deletions sample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"main": "index.js",
"scripts": {
"refresh": "cordova plugin rm cordova-plugin-qonversion && cordova plugin add ../plugin --link",
"android": "cordova run android",
"android": "cordova run android -- --gradleArg=-PcdvCompileSdkVersion=33",
"ios": "cordova run ios",
"test": "echo \"Error: no test specified\" && exit 1"
},
Expand All @@ -16,19 +16,17 @@
"author": "Apache Cordova Team",
"license": "Apache-2.0",
"devDependencies": {
"cordova-android": "^10.1.2",
"cordova-android": "^11.0.0",
"cordova-annotated-plugin-android": "^1.0.4",
"cordova-ios": "^6.3.0",
"cordova-plugin-device": "^2.1.0",
"cordova-plugin-qonversion": "file:../plugin"
},
"cordova": {
"platforms": [
"android",
"ios"
"ios",
"android"
],
"plugins": {
"cordova-plugin-qonversion": {}
}
"plugins": {}
}
}
Loading

0 comments on commit 4ba5465

Please sign in to comment.