Skip to content

Commit

Permalink
Merge pull request #76 from qonversion/release/3.1.0
Browse files Browse the repository at this point in the history
Release/3.1.0
  • Loading branch information
suriksarkisyan authored Aug 11, 2021
2 parents 82ebc1a + 4ca18c1 commit cdca6d0
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 30 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ repositories {
dependencies {
//noinspection GradleDynamicVersion
implementation 'com.facebook.react:react-native:+' // From node_modules
implementation "io.qonversion.android.sdk:sdk:3.0.0"
implementation "io.qonversion.android.sdk:sdk:3.1.0"
}

def configureReactNativePom(def pom) {
Expand Down
84 changes: 67 additions & 17 deletions android/src/main/java/com/reactlibrary/QonversionModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.qonversion.android.sdk.Qonversion;
import com.qonversion.android.sdk.QonversionEligibilityCallback;
import com.qonversion.android.sdk.QonversionError;
import com.qonversion.android.sdk.QonversionErrorCode;
import com.qonversion.android.sdk.QonversionExperimentsCallback;
import com.qonversion.android.sdk.QonversionLaunchCallback;
import com.qonversion.android.sdk.QonversionOfferingsCallback;
Expand All @@ -38,12 +39,15 @@
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;

import android.app.Activity;
import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;

public class QonversionModule extends ReactContextBaseJavaModule {

private final ReactApplicationContext reactContext;
private QonversionSDKInfo sdkInfoToSave;

private static final HashMap<Integer, QUserProperties> userPropertiesMap = new HashMap<Integer, QUserProperties>() {{
put(0, QUserProperties.Email);
put(1, QUserProperties.Name);
Expand All @@ -59,22 +63,49 @@ public QonversionModule(ReactApplicationContext reactContext) {
this.reactContext = reactContext;
}

private void storeSDKInfoToPreferences(QonversionSDKInfo sdkInfo,Activity currentActivity){
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(currentActivity.getApplication()).edit();
editor.putString(sdkInfo.sdkVersionKey, sdkInfo.sdkVersion);
editor.putString(sdkInfo.sourceKey, sdkInfo.source);
editor.apply();
}

private QonversionError generateActivityError () {
return new QonversionError(QonversionErrorCode.UnknownError, "Android current activity is null, cannot perform the process.");
}

@Override
public String getName() {
return "RNQonversion";
}

@ReactMethod
public void storeSDKInfo(String sourceKey, String source, String sdkVersionKey, String sdkVersion) {
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getCurrentActivity().getApplication()).edit();
editor.putString(sdkVersionKey, sdkVersion);
editor.putString(sourceKey, source);
editor.apply();
Activity currentActivity = getCurrentActivity();
QonversionSDKInfo sdkInfo = new QonversionSDKInfo(sourceKey, source, sdkVersionKey, sdkVersion);

if(currentActivity == null){
this.sdkInfoToSave = sdkInfo;
return;
}

storeSDKInfoToPreferences(sdkInfo, currentActivity);
}

@ReactMethod
public void launchWithKey(String key, Boolean observeMode, final Promise promise) {
Qonversion.launch(getCurrentActivity().getApplication(), key, observeMode, new QonversionLaunchCallback()
Activity currentActivity = getCurrentActivity();
if(currentActivity == null){
QonversionError qonversionError = generateActivityError();
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
return;
}

if(this.sdkInfoToSave != null){
storeSDKInfoToPreferences(this.sdkInfoToSave, currentActivity);
}

Qonversion.launch(currentActivity.getApplication(), key, observeMode, new QonversionLaunchCallback()
{
@Override
public void onSuccess(@NotNull QLaunchResult qLaunchResult) {
Expand All @@ -84,14 +115,21 @@ public void onSuccess(@NotNull QLaunchResult qLaunchResult) {

@Override
public void onError(@NotNull QonversionError qonversionError) {
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
rejectWithError(qonversionError, promise);
}
});
}

@ReactMethod
public void purchase(String productId, final Promise promise) {
Qonversion.purchase(getCurrentActivity(), productId, new QonversionPermissionsCallback() {
Activity currentActivity = getCurrentActivity();
if(currentActivity == null){
QonversionError qonversionError = generateActivityError();
promise.reject(qonversionError.getCode().toString(),qonversionError.getDescription());
return;
}

Qonversion.purchase(currentActivity, productId, new QonversionPermissionsCallback() {
@Override
public void onSuccess(@NotNull Map<String, QPermission> map) {
WritableMap result = EntitiesConverter.mapPermissions(map);
Expand All @@ -100,14 +138,21 @@ public void onSuccess(@NotNull Map<String, QPermission> map) {

@Override
public void onError(@NotNull QonversionError qonversionError) {
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
rejectWithError(qonversionError, promise);
}
});
}

@ReactMethod
public void updatePurchaseWithProrationMode(String productId, String oldProductId, Integer prorationMode, final Promise promise) {
Qonversion.updatePurchase(getCurrentActivity(), productId, oldProductId, prorationMode, new QonversionPermissionsCallback() {
Activity currentActivity = getCurrentActivity();
if(currentActivity == null){
QonversionError qonversionError = generateActivityError();
promise.reject(qonversionError.getCode().toString(),qonversionError.getDescription());
return;
}

Qonversion.updatePurchase(currentActivity, productId, oldProductId, prorationMode, new QonversionPermissionsCallback() {
@Override
public void onSuccess(@NotNull Map<String, QPermission> map) {
WritableMap result = EntitiesConverter.mapPermissions(map);
Expand All @@ -116,7 +161,7 @@ public void onSuccess(@NotNull Map<String, QPermission> map) {

@Override
public void onError(@NotNull QonversionError qonversionError) {
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
rejectWithError(qonversionError, promise);
}
});
}
Expand Down Expand Up @@ -183,7 +228,7 @@ public void onSuccess(@NotNull Map<String, QPermission> map) {

@Override
public void onError(@NotNull QonversionError qonversionError) {
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
rejectWithError(qonversionError, promise);
}
});
}
Expand All @@ -199,7 +244,7 @@ public void onSuccess(@NotNull Map<String, QProduct> map) {

@Override
public void onError(@NotNull QonversionError qonversionError) {
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
rejectWithError(qonversionError, promise);
}
});
}
Expand All @@ -214,8 +259,8 @@ public void onSuccess(@NotNull QOfferings offerings) {
}

@Override
public void onError(@NotNull QonversionError error) {
promise.reject(error.getCode().toString(), error.getDescription());
public void onError(@NotNull QonversionError qonversionError) {
rejectWithError(qonversionError, promise);
}
});
}
Expand All @@ -232,7 +277,7 @@ public void onSuccess(@NotNull Map<String, QEligibility> map) {

@Override
public void onError(@NotNull QonversionError qonversionError) {
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
rejectWithError(qonversionError, promise);
}
});
}
Expand All @@ -248,7 +293,7 @@ public void onSuccess(@NotNull Map<String, QExperimentInfo> map) {

@Override
public void onError(@NotNull QonversionError qonversionError) {
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
rejectWithError(qonversionError, promise);
}
});
}
Expand All @@ -264,7 +309,7 @@ public void onSuccess(@NotNull Map<String, QPermission> map) {

@Override
public void onError(@NotNull QonversionError qonversionError) {
promise.reject(qonversionError.getCode().toString(), qonversionError.getDescription());
rejectWithError(qonversionError, promise);
}
});
}
Expand Down Expand Up @@ -293,4 +338,9 @@ public void identify(String userID) {
public void logout() {
Qonversion.logout();
}

private void rejectWithError(@NotNull QonversionError qonversionError, final Promise promise) {
String errorMessage = qonversionError.getDescription() + "\n" + qonversionError.getAdditionalMessage();
promise.reject(qonversionError.getCode().toString(), errorMessage);
}
}
15 changes: 15 additions & 0 deletions android/src/main/java/com/reactlibrary/QonversionSDKInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.reactlibrary;

public class QonversionSDKInfo {
public String sourceKey;
public String source;
public String sdkVersionKey;
public String sdkVersion;

public QonversionSDKInfo(String sourceKey, String source, String sdkVersionKey, String sdkVersion){
this.sourceKey = sourceKey;
this.source = source;
this.sdkVersionKey = sdkVersionKey;
this.sdkVersion = sdkVersion;
}
}
8 changes: 4 additions & 4 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ PODS:
- glog (0.3.5)
- libevent (2.1.12)
- OpenSSL-Universal (1.1.180)
- Qonversion (2.15.0)
- Qonversion (2.16.2)
- RCTRequired (0.63.4)
- RCTTypeSafety (0.63.4):
- FBLazyVector (= 0.63.4)
Expand Down Expand Up @@ -247,7 +247,7 @@ PODS:
- React-jsi (= 0.63.4)
- React-jsinspector (0.63.4)
- react-native-qonversion (2.6.1):
- Qonversion (= 2.15.0)
- Qonversion (= 2.16.2)
- React
- React-RCTActionSheet (0.63.4):
- React-Core/RCTActionSheetHeaders (= 0.63.4)
Expand Down Expand Up @@ -452,7 +452,7 @@ SPEC CHECKSUMS:
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
Qonversion: 034fea872ffa6ec79047745ada7577bb4e02a227
Qonversion: f847c5967b8fb7eb280372ab3cbc63056deae974
RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b
React: b0a957a2c44da4113b0c4c9853d8387f8e64e615
Expand All @@ -463,7 +463,7 @@ SPEC CHECKSUMS:
React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31
React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949
React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a
react-native-qonversion: ff70d28b6fc1df27c1ee55c119e0d2a7a2068f0a
react-native-qonversion: 5ee9a79c99a0f1aa54204c77c609869d596c8af2
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
React-RCTBlob: a97d378b527740cc667e03ebfa183a75231ab0f0
Expand Down
2 changes: 2 additions & 0 deletions ios/EntitiesConverter.m
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ + (NSDictionary *)convertDiscount:(SKProductDiscount *)discount API_AVAILABLE(io

introductoryPrice[@"subscriptionPeriod"] = [introductorySubscriptionPeriod copy];
introductoryPrice[@"paymentMode"] = @(discount.paymentMode);

introductoryPrice[@"currencySymbol"] = discount.priceLocale.currencySymbol;

if (@available(iOS 12.2, *)) {
introductoryPrice[@"identifier"] = discount.identifier;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-native-qonversion",
"title": "React Native Qonversion",
"version": "3.0.0",
"version": "3.1.0",
"description": "Qonversion provides full in-app purchases infrastructure, so you do not need to build your own server for receipt validation. Implement in-app subscriptions, validate user receipts, check subscription status, and provide access to your app features and content using our StoreKit wrapper and Google Play Billing wrapper.",
"main": "build/index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion react-native-qonversion.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ Pod::Spec.new do |s|
s.requires_arc = true

s.dependency "React"
s.dependency "Qonversion", "2.15.0"
s.dependency "Qonversion", "2.16.2"
end
28 changes: 25 additions & 3 deletions src/classes/Mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ type QProductDiscount = {
paymentMode: keyof typeof SKProductDiscountPaymentMode;
identifier?: string;
type: keyof typeof SKProductDiscountType;
currencySymbol: string;
};

type QPermission = {
Expand All @@ -121,6 +122,8 @@ type QOffering = {
products: Array<QProduct>;
};

const skuDetailsPriceRatio = 1000000;

class Mapper {
static convertLaunchResult(launchResult: QLaunchResult): LaunchResult {
const products: Map<string, Product> = this.convertProducts(
Expand Down Expand Up @@ -198,18 +201,33 @@ class Mapper {
let skuDetails: SkuDetails | null = null;
let price: number | undefined;
let currencyCode: string | undefined;
let storeTitle: string | undefined;
let storeDescription: string | undefined;
let prettyIntroductoryPrice: string | undefined;

if (product.storeProduct != null) {
if (Platform.OS === "ios") {
skProduct = Mapper.convertSKProduct(product.storeProduct as QSKProduct);
price = parseFloat(skProduct.price);
currencyCode = skProduct.currencyCode;
storeTitle = skProduct.localizedTitle;
storeDescription = skProduct.localizedDescription;

if (skProduct.productDiscount) {
prettyIntroductoryPrice = skProduct.productDiscount.currencySymbol + skProduct.productDiscount.price;
}
} else {
skuDetails = Mapper.convertSkuDetails(
product.storeProduct as QSkuDetails
);
price = skuDetails.priceAmountMicros / 1000000;
price = skuDetails.priceAmountMicros / skuDetailsPriceRatio;
currencyCode = skuDetails.priceCurrencyCode;
storeTitle = skuDetails.title;
storeDescription = skuDetails.description;

if (skuDetails.introductoryPrice.length > 0) {
prettyIntroductoryPrice = skuDetails.introductoryPrice;
}
}
}

Expand All @@ -223,7 +241,10 @@ class Mapper {
product.prettyPrice,
trialDuration,
price,
currencyCode
currencyCode,
storeTitle,
storeDescription,
prettyIntroductoryPrice
);

return mappedProduct;
Expand Down Expand Up @@ -349,7 +370,8 @@ class Mapper {
subscriptionPeriod,
SKProductDiscountPaymentMode[discount.paymentMode],
discount.identifier,
SKProductDiscountType[discount.type]
SKProductDiscountType[discount.type],
discount.currencySymbol
);
}

Expand Down
11 changes: 10 additions & 1 deletion src/classes/Product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class Product {
trialDuration?: TrialDurations;
price?: number;
currencyCode?: string;
storeTitle?: string;
storeDescription?: string;
prettyIntroductoryPrice?: string;

constructor(
qonversionID: string,
Expand All @@ -24,7 +27,10 @@ class Product {
prettyPrice: string | undefined,
trialDuration: TrialDurations | undefined,
price: number | undefined,
currencyCode: string | undefined
currencyCode: string | undefined,
storeTitle: string | undefined,
storeDescription: string | undefined,
prettyIntroductoryPrice: string | undefined
) {
this.qonversionID = qonversionID;
this.storeID = storeID;
Expand All @@ -36,6 +42,9 @@ class Product {
this.trialDuration = trialDuration;
this.price = price;
this.currencyCode = currencyCode;
this.storeTitle = storeTitle;
this.storeDescription = storeDescription;
this.prettyIntroductoryPrice = prettyIntroductoryPrice;
}
}

Expand Down
Loading

0 comments on commit cdca6d0

Please sign in to comment.