@capgo/native-purchases 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NativePurchases.podspec +17 -0
- package/README.md +137 -0
- package/android/build.gradle +61 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/ee/forgr/nativepurchases/NativePurchasesPlugin.java +195 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +371 -0
- package/dist/esm/definitions.d.ts +305 -0
- package/dist/esm/definitions.js +128 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +19 -0
- package/dist/esm/web.js +28 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +162 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +165 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/NativePurchasesPlugin.h +10 -0
- package/ios/Plugin/NativePurchasesPlugin.m +10 -0
- package/ios/Plugin/NativePurchasesPlugin.swift +102 -0
- package/ios/Plugin/Product+CapacitorPurchasesPlugin.swift +52 -0
- package/package.json +78 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'NativePurchases'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = package['license']
|
|
10
|
+
s.homepage = package['repository']['url']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
+
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
s.ios.deployment_target = '13.0'
|
|
15
|
+
s.dependency 'Capacitor'
|
|
16
|
+
s.swift_version = '5.1'
|
|
17
|
+
end
|
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# native-purchases
|
|
2
|
+
|
|
3
|
+
In-app Subscriptions Made Easy
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install native-purchases
|
|
9
|
+
npx cap sync
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## API
|
|
13
|
+
|
|
14
|
+
<docgen-index>
|
|
15
|
+
|
|
16
|
+
* [`restorePurchases()`](#restorepurchases)
|
|
17
|
+
* [`purchaseProduct(...)`](#purchaseproduct)
|
|
18
|
+
* [`getProducts(...)`](#getproducts)
|
|
19
|
+
* [Interfaces](#interfaces)
|
|
20
|
+
|
|
21
|
+
</docgen-index>
|
|
22
|
+
|
|
23
|
+
<docgen-api>
|
|
24
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
25
|
+
|
|
26
|
+
### restorePurchases()
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
restorePurchases() => any
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Restores a user's previous and links their appUserIDs to any user's also using those .
|
|
33
|
+
|
|
34
|
+
**Returns:** <code>any</code>
|
|
35
|
+
|
|
36
|
+
--------------------
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### purchaseProduct(...)
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
purchaseProduct(options: { productIdentifier: string; quantity: number; }) => any
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| Param | Type |
|
|
46
|
+
| ------------- | ------------------------------------------------------------- |
|
|
47
|
+
| **`options`** | <code>{ productIdentifier: string; quantity: number; }</code> |
|
|
48
|
+
|
|
49
|
+
**Returns:** <code>any</code>
|
|
50
|
+
|
|
51
|
+
--------------------
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
### getProducts(...)
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
getProducts(options: { productIdentifiers: string[]; }) => any
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
| Param | Type |
|
|
61
|
+
| ------------- | ---------------------------------------- |
|
|
62
|
+
| **`options`** | <code>{ productIdentifiers: {}; }</code> |
|
|
63
|
+
|
|
64
|
+
**Returns:** <code>any</code>
|
|
65
|
+
|
|
66
|
+
--------------------
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Interfaces
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
#### CustomerInfo
|
|
73
|
+
|
|
74
|
+
| Prop | Type | Description |
|
|
75
|
+
| ------------------------------------ | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
76
|
+
| **`activeSubscriptions`** | <code>[string]</code> | Set of active subscription skus |
|
|
77
|
+
| **`allPurchasedProductIdentifiers`** | <code>[string]</code> | Set of purchased skus, active and inactive |
|
|
78
|
+
| **`nonSubscriptionTransactions`** | <code>{}</code> | Returns all the non-subscription a user has made. The are ordered by purchase date in ascending order. |
|
|
79
|
+
| **`latestExpirationDate`** | <code>string \| null</code> | The latest expiration date of all purchased skus |
|
|
80
|
+
| **`firstSeen`** | <code>string</code> | The date this user was first seen in RevenueCat. |
|
|
81
|
+
| **`originalAppUserId`** | <code>string</code> | The original App User Id recorded for this user. |
|
|
82
|
+
| **`requestDate`** | <code>string</code> | Date when this info was requested |
|
|
83
|
+
| **`originalApplicationVersion`** | <code>string \| null</code> | Returns the version number for the version of the application when the user bought the app. Use this for grandfathering users when migrating to subscriptions. This corresponds to the value of CFBundleVersion (in iOS) in the Info.plist file when the purchase was originally made. This is always null in Android |
|
|
84
|
+
| **`originalPurchaseDate`** | <code>string \| null</code> | Returns the purchase date for the version of the application when the user bought the app. Use this for grandfathering users when migrating to subscriptions. |
|
|
85
|
+
| **`managementURL`** | <code>string \| null</code> | URL to manage the active subscription of the user. If this user has an active iOS subscription, this will point to the App Store, if the user has an active Play Store subscription it will point there. If there are no active subscriptions it will be null. If there are multiple for different platforms, it will point to the device store. |
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
#### Transaction
|
|
89
|
+
|
|
90
|
+
| Prop | Type | Description |
|
|
91
|
+
| --------------------------- | ------------------- | ------------------------------------------------------------------ |
|
|
92
|
+
| **`transactionIdentifier`** | <code>string</code> | RevenueCat Id associated to the transaction. |
|
|
93
|
+
| **`productIdentifier`** | <code>string</code> | <a href="#product">Product</a> Id associated with the transaction. |
|
|
94
|
+
| **`purchaseDate`** | <code>string</code> | Purchase date of the transaction in ISO 8601 format. |
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
#### Product
|
|
98
|
+
|
|
99
|
+
| Prop | Type | Description |
|
|
100
|
+
| --------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
101
|
+
| **`identifier`** | <code>string</code> | <a href="#product">Product</a> Id. |
|
|
102
|
+
| **`description`** | <code>string</code> | Description of the product. |
|
|
103
|
+
| **`title`** | <code>string</code> | Title of the product. |
|
|
104
|
+
| **`price`** | <code>number</code> | Price of the product in the local currency. |
|
|
105
|
+
| **`priceString`** | <code>string</code> | Formatted price of the item, including its currency sign, such as €3.99. |
|
|
106
|
+
| **`currencyCode`** | <code>string</code> | Currency code for price and original price. |
|
|
107
|
+
| **`currencySymbol`** | <code>string</code> | Currency symbol for price and original price. |
|
|
108
|
+
| **`isFamilyShareable`** | <code>boolean</code> | Boolean indicating if the product is sharable with family |
|
|
109
|
+
| **`subscriptionGroupIdentifier`** | <code>string</code> | Group identifier for the product. |
|
|
110
|
+
| **`subscriptionPeriod`** | <code><a href="#subscriptionperiod">SubscriptionPeriod</a></code> | The <a href="#product">Product</a> subcription group identifier. |
|
|
111
|
+
| **`introductoryPrice`** | <code><a href="#skproductdiscount">SKProductDiscount</a> \| null</code> | The <a href="#product">Product</a> introductory Price. |
|
|
112
|
+
| **`discounts`** | <code>{}</code> | The <a href="#product">Product</a> discounts list. |
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
#### SubscriptionPeriod
|
|
116
|
+
|
|
117
|
+
| Prop | Type | Description |
|
|
118
|
+
| ------------------- | ------------------- | --------------------------------------- |
|
|
119
|
+
| **`numberOfUnits`** | <code>number</code> | The Subscription Period number of unit. |
|
|
120
|
+
| **`unit`** | <code>number</code> | The Subscription Period unit. |
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
#### SKProductDiscount
|
|
124
|
+
|
|
125
|
+
| Prop | Type | Description |
|
|
126
|
+
| ------------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
127
|
+
| **`identifier`** | <code>string</code> | The <a href="#product">Product</a> discount identifier. |
|
|
128
|
+
| **`type`** | <code>number</code> | The <a href="#product">Product</a> discount type. |
|
|
129
|
+
| **`price`** | <code>number</code> | The <a href="#product">Product</a> discount price. |
|
|
130
|
+
| **`priceString`** | <code>string</code> | Formatted price of the item, including its currency sign, such as €3.99. |
|
|
131
|
+
| **`currencySymbol`** | <code>string</code> | The <a href="#product">Product</a> discount currency symbol. |
|
|
132
|
+
| **`currencyCode`** | <code>string</code> | The <a href="#product">Product</a> discount currency code. |
|
|
133
|
+
| **`paymentMode`** | <code>number</code> | The <a href="#product">Product</a> discount paymentMode. |
|
|
134
|
+
| **`numberOfPeriods`** | <code>number</code> | The <a href="#product">Product</a> discount number Of Periods. |
|
|
135
|
+
| **`subscriptionPeriod`** | <code><a href="#subscriptionperiod">SubscriptionPeriod</a></code> | The <a href="#product">Product</a> discount subscription period. |
|
|
136
|
+
|
|
137
|
+
</docgen-api>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
ext {
|
|
2
|
+
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
|
|
4
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
|
|
5
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
repositories {
|
|
10
|
+
google()
|
|
11
|
+
mavenCentral()
|
|
12
|
+
}
|
|
13
|
+
dependencies {
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.0.0'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
apply plugin: 'com.android.library'
|
|
19
|
+
|
|
20
|
+
android {
|
|
21
|
+
namespace "ee.forgr.nativepurchases"
|
|
22
|
+
compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 33
|
|
23
|
+
defaultConfig {
|
|
24
|
+
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
|
|
25
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 33
|
|
26
|
+
versionCode 1
|
|
27
|
+
versionName "1.0"
|
|
28
|
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
29
|
+
}
|
|
30
|
+
buildTypes {
|
|
31
|
+
release {
|
|
32
|
+
minifyEnabled false
|
|
33
|
+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
lintOptions {
|
|
37
|
+
abortOnError false
|
|
38
|
+
}
|
|
39
|
+
compileOptions {
|
|
40
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
41
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
repositories {
|
|
46
|
+
google()
|
|
47
|
+
mavenCentral()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
dependencies {
|
|
52
|
+
implementation "com.google.guava:guava:31.1-android"
|
|
53
|
+
def billing_version = "6.0.1"
|
|
54
|
+
implementation "com.android.billingclient:billing:$billing_version"
|
|
55
|
+
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
56
|
+
implementation project(':capacitor-android')
|
|
57
|
+
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
58
|
+
testImplementation "junit:junit:$junitVersion"
|
|
59
|
+
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
60
|
+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
61
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
package ee.forgr.nativepurchases;
|
|
2
|
+
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
import androidx.annotation.NonNull;
|
|
5
|
+
|
|
6
|
+
import com.android.billingclient.api.AcknowledgePurchaseParams;
|
|
7
|
+
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
|
|
8
|
+
import com.android.billingclient.api.BillingClient;
|
|
9
|
+
import com.android.billingclient.api.BillingFlowParams;
|
|
10
|
+
import com.android.billingclient.api.BillingResult;
|
|
11
|
+
import com.android.billingclient.api.Purchase;
|
|
12
|
+
import com.android.billingclient.api.PurchasesUpdatedListener;
|
|
13
|
+
import com.android.billingclient.api.SkuDetails;
|
|
14
|
+
import com.android.billingclient.api.SkuDetailsParams;
|
|
15
|
+
import com.android.billingclient.api.SkuDetailsResponseListener;
|
|
16
|
+
import com.getcapacitor.JSObject;
|
|
17
|
+
import com.getcapacitor.Plugin;
|
|
18
|
+
import com.getcapacitor.PluginCall;
|
|
19
|
+
import com.getcapacitor.PluginMethod;
|
|
20
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
21
|
+
import com.google.common.base.CaseFormat;
|
|
22
|
+
import java.util.ArrayList;
|
|
23
|
+
import java.util.HashMap;
|
|
24
|
+
import java.util.Iterator;
|
|
25
|
+
import java.util.List;
|
|
26
|
+
import java.util.Map;
|
|
27
|
+
import org.json.JSONArray;
|
|
28
|
+
import org.json.JSONException;
|
|
29
|
+
import org.json.JSONObject;
|
|
30
|
+
|
|
31
|
+
@CapacitorPlugin(name = "NativePurchases")
|
|
32
|
+
public class NativePurchasesPlugin extends Plugin {
|
|
33
|
+
|
|
34
|
+
public final String PLUGIN_VERSION = "2.0.13";
|
|
35
|
+
|
|
36
|
+
private BillingClient billingClient;
|
|
37
|
+
private PluginCall purchaseCall;
|
|
38
|
+
|
|
39
|
+
@Override
|
|
40
|
+
public void load() {
|
|
41
|
+
super.load();
|
|
42
|
+
billingClient = BillingClient.newBuilder(getContext())
|
|
43
|
+
.setListener(new PurchasesUpdatedListener() {
|
|
44
|
+
@Override
|
|
45
|
+
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
|
|
46
|
+
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) {
|
|
47
|
+
for (Purchase purchase : purchases) {
|
|
48
|
+
handlePurchase(purchase);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
// Handle any other error codes.
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
.enablePendingPurchases()
|
|
56
|
+
.build();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private void handlePurchase(Purchase purchase) {
|
|
60
|
+
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
|
61
|
+
// Grant entitlement to the user, then acknowledge the purchase
|
|
62
|
+
acknowledgePurchase(purchase.getPurchaseToken());
|
|
63
|
+
|
|
64
|
+
JSObject ret = new JSObject();
|
|
65
|
+
ret.put("transactionId", purchase.getPurchaseToken());
|
|
66
|
+
purchaseCall.resolve(ret);
|
|
67
|
+
} else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {
|
|
68
|
+
// Here you can confirm to the user that they've started the pending
|
|
69
|
+
// purchase, and to complete it, they should follow instructions that are
|
|
70
|
+
// given to them. You can also choose to remind the user to complete the
|
|
71
|
+
// purchase if you detect that it is still pending.
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private void acknowledgePurchase(String purchaseToken) {
|
|
76
|
+
AcknowledgePurchaseParams acknowledgePurchaseParams =
|
|
77
|
+
AcknowledgePurchaseParams.newBuilder()
|
|
78
|
+
.setPurchaseToken(purchaseToken)
|
|
79
|
+
.build();
|
|
80
|
+
billingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
|
|
81
|
+
@Override
|
|
82
|
+
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
|
|
83
|
+
// Handle the result of the acknowledge purchase
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@PluginMethod
|
|
89
|
+
public void purchaseProduct(PluginCall call) {
|
|
90
|
+
String productIdentifier = call.getString("productIdentifier");
|
|
91
|
+
Log.d("CapacitorPurchases", "purchaseProduct: " + productIdentifier);
|
|
92
|
+
purchaseCall = call;
|
|
93
|
+
|
|
94
|
+
if (billingClient.isReady()) {
|
|
95
|
+
List<String> skuList = new ArrayList<>();
|
|
96
|
+
skuList.add(productIdentifier);
|
|
97
|
+
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
|
|
98
|
+
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
|
|
99
|
+
|
|
100
|
+
billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
|
|
101
|
+
@Override
|
|
102
|
+
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
|
|
103
|
+
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
|
|
104
|
+
for (SkuDetails skuDetails : skuDetailsList) {
|
|
105
|
+
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
|
|
106
|
+
.setSkuDetails(skuDetails)
|
|
107
|
+
.build();
|
|
108
|
+
billingClient.launchBillingFlow(getActivity(), flowParams);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@PluginMethod
|
|
117
|
+
public void restorePurchases(PluginCall call) {
|
|
118
|
+
Log.i("NativePurchases", "restorePurchases");
|
|
119
|
+
call.resolve();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@PluginMethod
|
|
123
|
+
public void getProducts(PluginCall call) {
|
|
124
|
+
List<String> productIdentifiers = new ArrayList<String>();
|
|
125
|
+
JSONArray productIdentifiersArray = call.getArray("productIdentifiers");
|
|
126
|
+
Log.i("NativePurchases", "getProducts: " + productIdentifiersArray);
|
|
127
|
+
call.resolve();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
//================================================================================
|
|
131
|
+
// Private methods
|
|
132
|
+
//================================================================================
|
|
133
|
+
|
|
134
|
+
private static JSObject convertMapToJson(Map<String, ?> readableMap) {
|
|
135
|
+
JSObject object = new JSObject();
|
|
136
|
+
|
|
137
|
+
for (Map.Entry<String, ?> entry : readableMap.entrySet()) {
|
|
138
|
+
String camelKey = entry.getKey().contains("_")
|
|
139
|
+
? CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, entry.getKey())
|
|
140
|
+
: entry.getKey();
|
|
141
|
+
if (entry.getValue() == null) {
|
|
142
|
+
object.put(camelKey, JSONObject.NULL);
|
|
143
|
+
} else if (entry.getValue() instanceof Map) {
|
|
144
|
+
object.put(
|
|
145
|
+
camelKey,
|
|
146
|
+
convertMapToJson((Map<String, Object>) entry.getValue())
|
|
147
|
+
);
|
|
148
|
+
} else if (entry.getValue() instanceof Object[]) {
|
|
149
|
+
object.put(
|
|
150
|
+
camelKey,
|
|
151
|
+
convertArrayToJsonArray((Object[]) entry.getValue())
|
|
152
|
+
);
|
|
153
|
+
} else if (entry.getValue() instanceof List) {
|
|
154
|
+
object.put(
|
|
155
|
+
camelKey,
|
|
156
|
+
convertArrayToJsonArray(((List) entry.getValue()).toArray())
|
|
157
|
+
);
|
|
158
|
+
} else if (entry.getValue() != null) {
|
|
159
|
+
Object value = entry.getValue();
|
|
160
|
+
if (camelKey == "priceString") {
|
|
161
|
+
String currency_symbol =
|
|
162
|
+
((String) value).replaceAll("\\d", "")
|
|
163
|
+
.replace(".", "")
|
|
164
|
+
.replace(",", "");
|
|
165
|
+
object.put("currencySymbol", currency_symbol);
|
|
166
|
+
}
|
|
167
|
+
if (camelKey == "title") {
|
|
168
|
+
// value = ((String) value).replace("(" + AppName + ")", "");
|
|
169
|
+
value = ((String) value).replaceAll("\\((.*?)\\)", ""); // TODO find better implementation
|
|
170
|
+
}
|
|
171
|
+
object.put(camelKey, value);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return object;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private static JSONArray convertArrayToJsonArray(Object[] array) {
|
|
179
|
+
JSONArray writableArray = new JSONArray();
|
|
180
|
+
for (Object item : array) {
|
|
181
|
+
if (item == null) {
|
|
182
|
+
writableArray.put(JSONObject.NULL);
|
|
183
|
+
} else if (item instanceof Map) {
|
|
184
|
+
writableArray.put(convertMapToJson((Map<String, Object>) item));
|
|
185
|
+
} else if (item instanceof Object[]) {
|
|
186
|
+
writableArray.put(convertArrayToJsonArray((Object[]) item));
|
|
187
|
+
} else if (item instanceof List) {
|
|
188
|
+
writableArray.put(convertArrayToJsonArray(((List) item).toArray()));
|
|
189
|
+
} else {
|
|
190
|
+
writableArray.put(item);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return writableArray;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
File without changes
|