├── .gitattributes
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── RNInAppPurchase.podspec
├── android
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── net
│ └── class101
│ └── iap
│ ├── NativeInAppPurchaseModule.java
│ ├── RNInAppPurchasePackage.java
│ └── internal
│ └── utils
│ └── ReadableMapUtils.java
├── docs
├── android_1.png
├── ios_1.png
└── ios_2.png
├── ios
├── RNInAppPurchase.h
├── RNInAppPurchase.mm
└── RNInAppPurchase.xcodeproj
│ └── project.pbxproj
├── package.json
├── sample
├── .eslintrc.js
├── .gitignore
├── .prettierrc.js
├── .vscode
│ └── settings.json
├── .watchmanconfig
├── App.tsx
├── Gemfile
├── __tests__
│ └── App.test.tsx
├── android
│ ├── app
│ │ ├── build.gradle
│ │ ├── debug.keystore
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── rninapppurchasesample
│ │ │ │ ├── MainActivity.kt
│ │ │ │ └── MainApplication.kt
│ │ │ └── res
│ │ │ ├── drawable
│ │ │ └── rn_edit_text_material.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── app.json
├── babel.config.js
├── index.js
├── ios
│ ├── .xcode.env
│ ├── Podfile
│ ├── Podfile.lock
│ ├── RNInAppPurchaseSample.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── RNInAppPurchaseSample.xcscheme
│ ├── RNInAppPurchaseSample.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── RNInAppPurchaseSample
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.mm
│ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ ├── LaunchScreen.storyboard
│ │ ├── PrivacyInfo.xcprivacy
│ │ └── main.m
│ └── RNInAppPurchaseSampleTests
│ │ ├── Info.plist
│ │ └── RNInAppPurchaseSampleTests.m
├── jest.config.js
├── metro.config.js
├── package.json
├── tsconfig.json
└── yarn.lock
└── src
├── NativeInAppPurchaseModule.ts
└── index.ts
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # OSX
3 | #
4 | .DS_Store
5 |
6 | # node.js
7 | #
8 | node_modules/
9 | npm-debug.log
10 | yarn-error.log
11 |
12 |
13 | # Xcode
14 | #
15 | build/
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 | xcuserdata
25 | *.xccheckout
26 | *.moved-aside
27 | DerivedData
28 | *.hmap
29 | *.ipa
30 | *.xcuserstate
31 | project.xcworkspace
32 |
33 |
34 | # Android/IntelliJ
35 | #
36 | build/
37 | .idea
38 | .gradle
39 | local.properties
40 | *.iml
41 |
42 | # BUCK
43 | buck-out/
44 | \.buckd/
45 | *.keystore
46 |
47 | .yarn
48 | .bundle
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | sample
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Injung Chung
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-in-app-purchase
2 |
3 | [](https://www.npmjs.com/package/@class101/react-native-in-app-purchase)
4 | [](https://www.npmjs.com/package/@class101/react-native-in-app-purchase)
5 | [](https://www.npmjs.com/package/@class101/react-native-in-app-purchase)
6 |
7 | 👻 A dead simple In-App Purchase library for React Native
8 |
9 | ## Getting started
10 |
11 | ```bash
12 | $ yarn add @class101/react-native-in-app-purchase
13 |
14 | # RN >= 0.60
15 | cd ios && pod install
16 |
17 | # RN < 0.60
18 | react-native link @class101/react-native-in-app-purchase
19 | ```
20 |
21 | ### Android
22 |
23 | Add `BILLING` permission to the `AndroidManifest.xml`.
24 |
25 | ```xml
26 |
29 |
30 |
31 |
32 |
33 | ...
34 |
35 | ```
36 |
37 | Create your app on the Google Play Console, and add product in the In-App Products section. Make sure set the product status to **active** so that you can view or purchase it.
38 |
39 | [](docs/android_1.png?raw=true)
40 |
41 | Note that testing Android In-App Billing is only possible after uploading your APK to Alpha release or above.
42 |
43 | ### iOS
44 |
45 | Add In-App Purchase capability on the Signing & Capabilities section of the project.
46 |
47 | [](docs/ios_1.png?raw=true)
48 |
49 | Create your app on the App Store Connect, and add product in the In-App Purchases section. You may need to fill the audit information field.
50 |
51 | [](docs/ios_2.png?raw=true)
52 |
53 | Testing iOS In-App Purchase is possible on TestFlight.
54 |
55 | ## Usage
56 |
57 | See full example [here](sample/App.js). This sample can also be downloaded from the [Play Store](https://play.google.com/store/apps/details?id=com.rninapppurchasesample).
58 |
59 | #### 1. Prepare product ids
60 |
61 | Choose the product id that you want to sell. It would be nice to have the same product id for Android and iOS.
62 |
63 | ```javascript
64 | import InAppPurchase from "@class101/react-native-in-app-purchase";
65 |
66 | const PRODUCT_IDS = [
67 | "rniap.sample.normal",
68 | "rniap.sample.consumable",
69 | "rniap.sample.subscribe",
70 | ];
71 | ```
72 |
73 | #### 2. Add Listeners
74 |
75 | For some reasons, the `purchase` and `fetchProducts` functions are not `Promise`. So you need to register `onPurchase` and `onFetchProducts` listeners.
76 |
77 | ```javascript
78 | const onFetchProducts = (products) => {
79 | this.setState({ products });
80 | };
81 |
82 | const onPurchase = (purchase) => {
83 | // Validate payment on your backend server with purchase object.
84 | setTimeout(() => {
85 | // Complete the purchase flow by calling finalize function.
86 | InAppPurchase.finalize(
87 | purchase,
88 | purchase.productId === "rniap.sample.consumable"
89 | ).then(() => {
90 | Alert.alert("In App Purchase", "Purchase Succeed!");
91 | });
92 | });
93 | };
94 |
95 | const onError = (e) => {
96 | console.log(e);
97 | };
98 |
99 | InAppPurchase.onFetchProducts(onFetchProducts);
100 | InAppPurchase.onPurchase(onPurchase);
101 | InAppPurchase.onError(onError);
102 | ```
103 |
104 | After each purchase, you need to verify receipt on your server. If purchase is valid, call `finalize` function in the app. Set whether it is consumable or not as the second argument to the `finalize` function.
105 |
106 | #### 3. Configure and Fetch Products
107 |
108 | Once you have registered your listeners, call `configure` and `fetchProducts`. Since the library will initialize billingClient only once, you can call `configure`, `fetchProducts` multiple times.
109 |
110 | ```javascript
111 | InAppPurchase.configure().then(() => {
112 | InAppPurchase.fetchProducts(PRODUCT_IDS);
113 | });
114 | ```
115 |
116 | #### 4. Purchase Product
117 |
118 | Call `InAppPurchase.purchase` with product id.
119 |
120 | ```javascript
121 | InAppPurchase.purchase(item.productId); // 'rniap.sample.consumable'
122 | ```
123 |
124 | #### 5. Retry
125 |
126 | In some cases, your app may not be able to call the `finalize` function even the purchase was successful. (such as poor internet connection) Purchases that are not finalized can be retrieved with the `flush` function. Send these purchases to the server to verify, and then call the `finalize` function.
127 |
128 | ```javascript
129 | InAppPurchase.flush().then((purchases) => {
130 | purchases.forEach(onPurchase);
131 | });
132 | ```
133 |
134 | ## Type Definitions
135 |
136 | Type definitions of Product, Purchase and InAppPurchaseError.
137 |
138 | #### Product
139 |
140 | | Property | Type | Comment |
141 | | ----------- | ------ | --------------------------- |
142 | | productId | string | - |
143 | | price | string | - |
144 | | currency | string | Currency code (USD, KRW...) |
145 | | title | string | - |
146 | | description | string | - |
147 |
148 | #### Purchase
149 |
150 | | Property | Type | Comment |
151 | | --------------- | -------- | ---------------------------------------------- |
152 | | productIds | string[] | - |
153 | | transactionId | string | - |
154 | | transactionDate | string | - |
155 | | receipt | string | Use this property to validate iOS purchase |
156 | | purchaseToken | string | Use this property to validate Android purchase |
157 |
158 | #### InAppPurchaseError
159 |
160 | | Property | Type | Comment |
161 | | -------- | ------------------------------------ | --------------------------------------------- |
162 | | type | FETCH_PRODUCTS, PURCHASE, CONNECTION | `CONNECTION` error is only occurs on Android. |
163 | | code | number | - |
164 | | message | string | - |
165 |
166 | ## Receipt Verification
167 |
168 | Actually this isn't something that should be mentioned in this document. However, since it's critical part of implementing In-App Purchase flow, I'll show you how I implemented it.
169 |
170 | #### Client Side
171 |
172 | ```typescript
173 | const onPurchase = useCallback(
174 | (result: Purchase) => {
175 | return verifyReceipt({
176 | variables: {
177 | input: {
178 | platform: Platform.select({
179 | ios: "apple",
180 | android: "google",
181 | }),
182 | productId: result.productIds[0],
183 | receipt: Platform.select({
184 | ios: result.receipt,
185 | android: result.purchaseToken,
186 | }),
187 | },
188 | },
189 | })
190 | .then(() => InAppPurchase.finalize(result, true))
191 | .then(() =>
192 | Alert.alert(
193 | LocalizedStrings.COIN_PURCHASE_SUCCESS_TITLE,
194 | LocalizedStrings.COIN_PURCHASE_SUCCESS_MESSAGE
195 | )
196 | )
197 | .catch((e) => Alert.alert(LocalizedStrings.COMMON_ERROR, e.message))
198 | .finally(() => setIsLoading(false));
199 | },
200 | [setIsLoading, verifyReceipt]
201 | );
202 | ```
203 |
204 | #### Server Side
205 |
206 | Here I used [node-iap](https://github.com/Wizcorp/node-iap) library.
207 |
208 | ```typescript
209 | class VerifyReceipt extends Interactor {
210 | public async perform() {
211 | const { user, platform, productId, receipt, language } = this.context;
212 |
213 | if (!["apple", "google"].includes(platform)) {
214 | throw new functions.https.HttpsError(
215 | "invalid-argument",
216 | LocalizedStrings(language).ERROR_RECEIPT_VALIDATE_FAILURE
217 | );
218 | }
219 |
220 | return new Promise((resolve, reject) => {
221 | iap.verifyPayment(
222 | platform,
223 | {
224 | receipt,
225 | productId,
226 | packageName: PACKAGE_NAME,
227 | keyObject: require("../../../iapServiceAccountKey.json"),
228 | },
229 | async (error, response) => {
230 | if (error) {
231 | return reject(
232 | new functions.https.HttpsError("aborted", error.message)
233 | );
234 | }
235 |
236 | // If it's already consumed
237 | if (platform === "google" && response.receipt.purchase_state === 1) {
238 | return reject(
239 | new functions.https.HttpsError(
240 | "unavailable",
241 | LocalizedStrings(language).ERROR_RECEIPT_NOT_FOUND
242 | )
243 | );
244 | }
245 |
246 | const coin = COIN_LIST[language].find((c) => c.id === productId);
247 |
248 | // Unavailable product
249 | if (!coin) {
250 | return reject(
251 | new functions.https.HttpsError(
252 | "unavailable",
253 | LocalizedStrings(language).ERROR_RECEIPT_VALIDATE_FAILURE
254 | )
255 | );
256 | }
257 |
258 | const orderId = response.transactionId;
259 |
260 | // If it's already verified
261 | const userRef = firestore().collection("users").doc(user.id);
262 | const transactionSnapshot = await userRef
263 | .collection("transactions")
264 | .where("orderId", "==", orderId)
265 | .get();
266 | if (transactionSnapshot.docs.length > 0) {
267 | return resolve({
268 | transaction: transactionSnapshot.docs[0].data() as Transaction,
269 | profile: user,
270 | });
271 | }
272 |
273 | const now = Date.now();
274 | const batch = firestore().batch();
275 | const receiptRef = userRef.collection("receipts").doc();
276 | const transactionRef = userRef.collection("transactions").doc();
277 |
278 | const transaction = {
279 | id: transactionRef.id,
280 | description: LocalizedStrings(language).DESCRIPTION_PURCHASE_COIN,
281 | orderId,
282 | amount: coin.amount,
283 | createdAt: now,
284 | };
285 |
286 | batch.set(receiptRef, {
287 | id: receiptRef.id,
288 | productId,
289 | orderId,
290 | createdAt: now,
291 | });
292 |
293 | batch.set(
294 | userRef,
295 | {
296 | coin: firestore.FieldValue.increment(coin.amount),
297 | },
298 | {
299 | merge: true,
300 | }
301 | );
302 |
303 | batch.set(transactionRef, transaction);
304 |
305 | await batch.commit();
306 |
307 | resolve({
308 | transaction,
309 | profile: {
310 | ...user,
311 | coin: user.coin + coin.amount,
312 | },
313 | });
314 | }
315 | );
316 | });
317 | }
318 | }
319 | ```
320 |
321 | Note the part _If it's already verified_. Purchases that have already been verified should also return **success**. Otherwise, the item will be provided multiple times when flushing.
322 |
323 | ## Contributing
324 |
325 | Bug reports and pull requests are welcome on [GitHub](https://github.com/pedaling/react-native-in-app-purchase/issues).
326 |
327 | ## License
328 |
329 | The package is available as open source under the terms of the [MIT License](LICENSE).
330 |
--------------------------------------------------------------------------------
/RNInAppPurchase.podspec:
--------------------------------------------------------------------------------
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 = "RNInAppPurchase"
7 | s.version = package['version']
8 | s.summary = package['description']
9 | s.license = package['license']
10 |
11 | s.authors = package['author']
12 | s.homepage = 'https://github.com/pedaling/react-native-in-app-purchase'
13 | s.platform = :ios, "9.0"
14 | s.ios.deployment_target = '9.0'
15 | s.tvos.deployment_target = '10.0'
16 |
17 | s.source = { :git => "https://github.com/pedaling/react-native-in-app-purchase.git", :tag => "v#{s.version}" }
18 | s.source_files = "ios/**/*.{h,m,mm,swift}"
19 |
20 | s.dependency 'React'
21 |
22 | install_modules_dependencies(s)
23 | end
24 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.safeExtGet = { prop ->
3 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : project.properties['ReactNativeIAP_' + prop]
4 | }
5 | repositories {
6 | google()
7 | gradlePluginPortal()
8 | }
9 | dependencies {
10 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion')}")
11 | classpath("com.android.tools.build:gradle:7.0.4")
12 | }
13 | }
14 |
15 | def safeExtGet(prop, fallback) {
16 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
17 | }
18 |
19 | def isNewArchitectureEnabled() {
20 | return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
21 | }
22 |
23 | apply plugin: 'com.android.library'
24 | apply plugin: 'com.facebook.react'
25 |
26 | android {
27 | compileSdkVersion safeExtGet('compileSdkVersion', 34)
28 | buildToolsVersion safeExtGet('buildToolsVersion', '34.0.0')
29 |
30 | defaultConfig {
31 | minSdkVersion safeExtGet('minSdkVersion', 28)
32 | targetSdkVersion safeExtGet('targetSdkVersion', 34)
33 | buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
34 | ndk {
35 | abiFilters "armeabi-v7a", "x86"
36 | }
37 | }
38 | buildFeatures {
39 | buildConfig true
40 | }
41 | sourceSets {
42 | main {
43 | if (isNewArchitectureEnabled()) {
44 | java.srcDirs += [
45 | "generated/java",
46 | "generated/jni"
47 | ]
48 | }
49 | }
50 | }
51 | }
52 |
53 | repositories {
54 | mavenCentral()
55 | google()
56 | }
57 |
58 | dependencies {
59 | implementation 'com.facebook.react:react-native:+'
60 | implementation "com.android.billingclient:billing:${safeExtGet('googleBillingVersion', '7.0.0')}"
61 | }
62 |
63 | if (isNewArchitectureEnabled()) {
64 | react {
65 | jsRootDir = file("../src")
66 | libraryName = "InAppPurchase"
67 | codegenJavaPackageName = "net.class101.iap"
68 | }
69 | }
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC2039,SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC2039,SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command:
206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
207 | # and any embedded shellness will be escaped.
208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
209 | # treated as '${Hostname}' itself on the command line.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/src/main/java/net/class101/iap/NativeInAppPurchaseModule.java:
--------------------------------------------------------------------------------
1 | package net.class101.iap;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.annotation.Nullable;
5 |
6 | import com.android.billingclient.api.AcknowledgePurchaseParams;
7 | import com.android.billingclient.api.BillingClient;
8 | import com.android.billingclient.api.BillingClientStateListener;
9 | import com.android.billingclient.api.BillingFlowParams;
10 | import com.android.billingclient.api.BillingResult;
11 | import com.android.billingclient.api.ConsumeParams;
12 | import com.android.billingclient.api.PendingPurchasesParams;
13 | import com.android.billingclient.api.ProductDetails;
14 | import com.android.billingclient.api.Purchase;
15 | import com.android.billingclient.api.PurchasesUpdatedListener;
16 | import com.android.billingclient.api.QueryProductDetailsParams;
17 | import com.android.billingclient.api.QueryPurchasesParams;
18 | import com.android.billingclient.api.UserChoiceBillingListener;
19 | import com.android.billingclient.api.UserChoiceDetails;
20 | import com.facebook.common.internal.ImmutableList;
21 | import com.facebook.react.bridge.Arguments;
22 | import com.facebook.react.bridge.Callback;
23 | import com.facebook.react.bridge.Promise;
24 | import com.facebook.react.bridge.ReactApplicationContext;
25 | import com.facebook.react.bridge.ReadableArray;
26 | import com.facebook.react.bridge.ReadableMap;
27 | import com.facebook.react.bridge.WritableArray;
28 | import com.facebook.react.bridge.WritableMap;
29 | import com.facebook.react.bridge.WritableNativeArray;
30 |
31 | import net.class101.iap.internal.utils.ReadableMapUtils;
32 |
33 | import java.util.ArrayList;
34 | import java.util.HashMap;
35 | import java.util.List;
36 | import java.util.Map;
37 | import java.util.Optional;
38 |
39 | public class NativeInAppPurchaseModule extends NativeInAppPurchaseModuleSpec implements PurchasesUpdatedListener, UserChoiceBillingListener {
40 | private final ReactApplicationContext reactContext;
41 |
42 | private final Map productDetailsMap;
43 |
44 | private BillingClient client;
45 | private ReadableMap appliedConfig;
46 |
47 | private Callback fetchProductsListener;
48 | private Callback purchaseListener;
49 | private Callback errorListener;
50 | private Callback alternativeBillingFlowListener;
51 |
52 | public NativeInAppPurchaseModule(ReactApplicationContext reactContext) {
53 | super(reactContext);
54 | this.reactContext = reactContext;
55 | this.productDetailsMap = new HashMap<>();
56 | }
57 |
58 | @Override
59 | public void configure(@Nullable ReadableMap config, Promise promise) {
60 | if (client != null) {
61 | if (client.isReady() && !hasChangedOptions(appliedConfig, config)) {
62 | promise.resolve(true);
63 | return;
64 | }
65 |
66 | client.endConnection();
67 | client = null;
68 | }
69 | this.appliedConfig = config;
70 |
71 | BillingClient.Builder builder = BillingClient.newBuilder(reactContext)
72 | .setListener(this)
73 | .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build());
74 |
75 | var isAlternativeBillingEnable = Optional.ofNullable(config).map(it -> it.getBoolean("isAlternativeBillingEnable")).orElse(false);
76 |
77 | if (isAlternativeBillingEnable) {
78 | builder.enableUserChoiceBilling(this);
79 | }
80 |
81 | client = builder.build();
82 |
83 | client.startConnection(new BillingClientStateListener() {
84 | @Override
85 | public void onBillingSetupFinished(@NonNull BillingResult result) {
86 | int code = result.getResponseCode();
87 |
88 | if (code == BillingClient.BillingResponseCode.OK) {
89 | promise.resolve(true);
90 | } else {
91 | promise.reject("configure", "Billing service setup failed with code " + code);
92 | }
93 | }
94 |
95 | @Override
96 | public void onBillingServiceDisconnected() {
97 | promise.reject("configure", "Billing service disconnected");
98 | }
99 | });
100 | }
101 |
102 | @Override
103 | public void fetchProducts(ReadableArray products) {
104 | tryConnect(() -> {
105 | ImmutableList productList = ImmutableList.of();
106 |
107 |
108 | for (int i = 0; i < products.size(); i++) {
109 | ReadableMap product = products.getMap(i);
110 |
111 | String productId = product.getString("id");
112 | String productType = product.getString("type");
113 |
114 | if (productId == null || productType == null) {
115 | continue;
116 | }
117 |
118 | if (!productType.equals(BillingClient.ProductType.SUBS) && !productType.equals(BillingClient.ProductType.INAPP)) {
119 | continue;
120 | }
121 |
122 | productList.add(
123 | QueryProductDetailsParams.Product.newBuilder()
124 | .setProductId(productId)
125 | .setProductType(productType)
126 | .build()
127 | );
128 | }
129 |
130 | QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
131 | .setProductList(productList)
132 | .build();
133 |
134 | final WritableArray items = new WritableNativeArray();
135 |
136 | // Query in-app items
137 | client.queryProductDetailsAsync(params, (billingResult, productDetailsList) -> {
138 | if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
139 | sendBillingError("FETCH_PRODUCTS", billingResult);
140 | return;
141 | }
142 |
143 | for (int i = 0; i < products.size(); i++) {
144 | ReadableMap product = products.getMap(i);
145 |
146 | String productId = product.getString("id");
147 | String productType = product.getString("type");
148 | String planId = product.getString("planId");
149 | String offerId = product.getString("offerId");
150 |
151 | if (productId == null || productType == null) {
152 | continue;
153 | }
154 |
155 | if (!productType.equals(BillingClient.ProductType.SUBS) && !productType.equals(BillingClient.ProductType.INAPP)) {
156 | continue;
157 | }
158 |
159 | Optional productDetails = productDetailsList.stream().filter(details -> details.getProductId().equals(productId)).findFirst();
160 | if (!productDetails.isPresent()) {
161 | continue;
162 | }
163 |
164 | if (productType.equals(BillingClient.ProductType.INAPP)) {
165 | WritableMap item = Arguments.createMap();
166 | item.putString("productId", productDetails.get().getProductId());
167 | item.putString("offerId", offerId);
168 | item.putString("title", productDetails.get().getTitle());
169 | item.putString("description", productDetails.get().getDescription());
170 |
171 | ProductDetails.OneTimePurchaseOfferDetails offerDetails = productDetails.get().getOneTimePurchaseOfferDetails();
172 | if (offerDetails != null) {
173 | item.putString("price", offerDetails.getFormattedPrice());
174 | item.putString("currency", offerDetails.getPriceCurrencyCode());
175 | }
176 |
177 | items.pushMap(item);
178 | continue;
179 | }
180 |
181 | List offerDetailsList = productDetails.get().getSubscriptionOfferDetails();
182 |
183 | if (offerDetailsList == null || offerDetailsList.isEmpty()) {
184 | continue;
185 | }
186 |
187 | Optional offerDetails = offerDetailsList.stream()
188 | .filter(details -> planId == null || details.getBasePlanId().equals(planId))
189 | .filter(details -> offerId == null || (details.getOfferId() != null && details.getOfferId().equals(offerId)))
190 | .findFirst();
191 |
192 | if (offerDetails.isPresent()) {
193 | WritableMap item = Arguments.createMap();
194 | item.putString("productId", productDetails.get().getProductId());
195 | item.putString("planId", planId);
196 | item.putString("offerId", offerId);
197 | item.putString("title", productDetails.get().getTitle());
198 | item.putString("description", productDetails.get().getDescription());
199 | item.putString("price", offerDetails.get().getPricingPhases().getPricingPhaseList().get(0).getFormattedPrice());
200 | item.putString("currency", offerDetails.get().getPricingPhases().getPricingPhaseList().get(0).getPriceCurrencyCode());
201 |
202 | items.pushMap(item);
203 | }
204 | }
205 |
206 | for (ProductDetails productDetails : productDetailsList) {
207 | productDetailsMap.put(productDetails.getProductId(), productDetails);
208 | }
209 |
210 | if (fetchProductsListener != null) {
211 | fetchProductsListener.invoke(items);
212 | }
213 | });
214 | });
215 | }
216 |
217 | @Override
218 | public void flush(Promise promise) {
219 | tryConnect(() -> client.queryPurchasesAsync(
220 | QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build(),
221 | (inAppResult, inAppPurchases) -> {
222 | if (inAppResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
223 | promise.reject("flush", inAppResult.getDebugMessage());
224 | return;
225 | }
226 | List purchaseList = new ArrayList<>(inAppPurchases);
227 |
228 | client.queryPurchasesAsync(
229 | QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build(),
230 | (subscriptionResult, subscriptionPurchases) -> {
231 | if (subscriptionResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
232 | promise.reject("flush", subscriptionResult.getDebugMessage());
233 | return;
234 | }
235 |
236 | purchaseList.addAll(subscriptionPurchases);
237 | WritableArray items = new WritableNativeArray();
238 |
239 | for (Purchase purchase : purchaseList) {
240 | if (purchase.isAcknowledged()) {
241 | continue;
242 | }
243 |
244 | ReadableMap item = this.buildPurchaseJSON(purchase);
245 | items.pushMap(item);
246 | }
247 |
248 | promise.resolve(items);
249 | }
250 | );
251 | }
252 | ));
253 | }
254 |
255 | @Override
256 | public void purchase(String productId, @Nullable ReadableMap args) {
257 | tryConnect(() -> {
258 | if (getCurrentActivity() == null) {
259 | return;
260 | }
261 |
262 | ProductDetails productDetails = productDetailsMap.get(productId);
263 | String obfuscatedAccountId = args != null ? args.getString("obfuscatedAccountId") : null;
264 | String obfuscatedProfileId = args != null ? args.getString("obfuscatedProfileId") : null;
265 | String originalPurchaseToken = args != null ? args.getString("originalPurchaseToken") : null;
266 |
267 | String planId = args != null ? args.getString("planId") : null;
268 | String offerId = args != null ? args.getString("offerId") : null;
269 |
270 | if (productDetails == null) {
271 | return;
272 | }
273 |
274 | BillingFlowParams.Builder builder = BillingFlowParams.newBuilder();
275 |
276 | if (obfuscatedAccountId != null) {
277 | builder.setObfuscatedAccountId(obfuscatedAccountId);
278 | }
279 |
280 | if (obfuscatedProfileId != null) {
281 | builder.setObfuscatedProfileId(obfuscatedProfileId);
282 | }
283 |
284 | if (originalPurchaseToken != null) {
285 | builder.setSubscriptionUpdateParams(
286 | BillingFlowParams.SubscriptionUpdateParams.newBuilder()
287 | .setOldPurchaseToken(originalPurchaseToken)
288 | .build()
289 | );
290 | }
291 |
292 | BillingFlowParams.ProductDetailsParams.Builder productDetailsParamsBuilder = BillingFlowParams.ProductDetailsParams.newBuilder();
293 | List offerDetailsList = productDetails.getSubscriptionOfferDetails();
294 |
295 | productDetailsParamsBuilder.setProductDetails(productDetails);
296 |
297 | if (offerDetailsList != null) {
298 | offerDetailsList.stream()
299 | .filter(details -> planId == null || details.getBasePlanId().equals(planId))
300 | .filter(details -> offerId == null || (details.getOfferId() != null && details.getOfferId().equals(offerId)))
301 | .findFirst()
302 | .ifPresent(details -> productDetailsParamsBuilder.setOfferToken(details.getOfferToken()));
303 | }
304 |
305 | ImmutableList productDetailsParamsList = ImmutableList.of(productDetailsParamsBuilder.build());
306 | BillingFlowParams params = builder.setProductDetailsParamsList(productDetailsParamsList).build();
307 |
308 | client.launchBillingFlow(getCurrentActivity(), params);
309 | });
310 | }
311 |
312 | @Override
313 | public void finalize(ReadableMap purchase, boolean isConsumable, final Promise promise) {
314 | tryConnect(() -> {
315 | String token = purchase.getString("purchaseToken");
316 |
317 | if (token == null) {
318 | return;
319 | }
320 |
321 | if (isConsumable) {
322 | ConsumeParams params = ConsumeParams.newBuilder()
323 | .setPurchaseToken(token)
324 | .build();
325 |
326 | client.consumeAsync(params, (result, purchaseToken) -> {
327 | if (result.getResponseCode() != BillingClient.BillingResponseCode.OK) {
328 | promise.reject("finalize", result.getDebugMessage());
329 | return;
330 | }
331 |
332 | WritableMap event = Arguments.createMap();
333 | event.putString("message", result.getDebugMessage());
334 |
335 | promise.resolve(event);
336 | });
337 | return;
338 | }
339 |
340 | AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
341 | .setPurchaseToken(token)
342 | .build();
343 |
344 | client.acknowledgePurchase(acknowledgePurchaseParams, (result) -> {
345 | if (result.getResponseCode() != BillingClient.BillingResponseCode.OK) {
346 | promise.reject("finalize", result.getDebugMessage());
347 | return;
348 | }
349 |
350 | WritableMap event = Arguments.createMap();
351 | event.putString("message", result.getDebugMessage());
352 |
353 | promise.resolve(event);
354 | });
355 | });
356 | }
357 |
358 | @Override
359 | public void fetchReceipt(Promise promise) {
360 | promise.reject("fetchReceipt", "Not implemented");
361 | }
362 |
363 | @Override
364 | public void onFetchProducts(Callback listener) {
365 | this.fetchProductsListener = listener;
366 | }
367 |
368 | @Override
369 | public void onPurchase(Callback listener) {
370 | this.purchaseListener = listener;
371 | }
372 |
373 | @Override
374 | public void onAlternativeBillingFlow(Callback listener) {
375 | this.alternativeBillingFlowListener = listener;
376 | }
377 |
378 | @Override
379 | public void onError(Callback listener) {
380 | this.errorListener = listener;
381 | }
382 |
383 | @Override
384 | public void clear() {
385 | this.fetchProductsListener = null;
386 | this.purchaseListener = null;
387 | this.errorListener = null;
388 | this.alternativeBillingFlowListener = null;
389 | }
390 |
391 | @Override
392 | public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List purchases) {
393 | if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
394 | sendBillingError("PURCHASE", billingResult);
395 | return;
396 | }
397 |
398 | if (purchases != null) {
399 | for (Purchase purchase : purchases) {
400 | ReadableMap item = this.buildPurchaseJSON(purchase);
401 | this.purchaseListener.invoke(item);
402 | }
403 | }
404 | }
405 |
406 | @Override
407 | public void userSelectedAlternativeBilling(@NonNull UserChoiceDetails userChoiceDetails) {
408 | if (this.alternativeBillingFlowListener == null) {
409 | return;
410 | }
411 |
412 | this.alternativeBillingFlowListener.invoke(userChoiceDetails.getExternalTransactionToken());
413 | }
414 |
415 | private boolean hasChangedOptions(ReadableMap appliedConfig, ReadableMap newConfig) {
416 | return !ReadableMapUtils.deepEquals(appliedConfig, newConfig);
417 | }
418 |
419 |
420 | private void tryConnect(final Runnable runnable) {
421 | if (client.isReady()) {
422 | runnable.run();
423 | return;
424 | }
425 |
426 | client.startConnection(new BillingClientStateListener() {
427 | @Override
428 | public void onBillingSetupFinished(@NonNull BillingResult result) {
429 | if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) {
430 | runnable.run();
431 | } else {
432 | sendBillingError("CONNECTION", result);
433 | }
434 | }
435 |
436 | @Override
437 | public void onBillingServiceDisconnected() {
438 | }
439 | });
440 | }
441 |
442 | private void sendBillingError(String type, BillingResult result) {
443 | WritableMap exception = Arguments.createMap();
444 | exception.putString("type", type);
445 | exception.putInt("code", result.getResponseCode());
446 | exception.putString("message", result.getDebugMessage());
447 |
448 | if (errorListener != null) {
449 | errorListener.invoke(exception);
450 | }
451 | }
452 |
453 | private ReadableMap buildPurchaseJSON(Purchase purchase) {
454 | WritableMap item = Arguments.createMap();
455 | WritableArray productIds = Arguments.createArray();
456 | for (String sku : purchase.getProducts()) {
457 | productIds.pushString(sku);
458 | }
459 | item.putArray("productIds", productIds);
460 | item.putString("transactionId", purchase.getOrderId());
461 | item.putString("transactionDate", String.valueOf(purchase.getPurchaseTime()));
462 | item.putString("receipt", purchase.getOriginalJson());
463 | item.putString("purchaseToken", purchase.getPurchaseToken());
464 |
465 | return item;
466 | }
467 | }
468 |
469 |
--------------------------------------------------------------------------------
/android/src/main/java/net/class101/iap/RNInAppPurchasePackage.java:
--------------------------------------------------------------------------------
1 | package net.class101.iap;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.annotation.Nullable;
5 |
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | import com.facebook.react.TurboReactPackage;
10 | import com.facebook.react.bridge.NativeModule;
11 | import com.facebook.react.bridge.ReactApplicationContext;
12 | import com.facebook.react.module.model.ReactModuleInfo;
13 | import com.facebook.react.module.model.ReactModuleInfoProvider;
14 |
15 | public class RNInAppPurchasePackage extends TurboReactPackage {
16 |
17 | @Nullable
18 | @Override
19 | public NativeModule getModule(@NonNull String name, @NonNull ReactApplicationContext reactApplicationContext) {
20 | if (name.equals(NativeInAppPurchaseModule.NAME)) {
21 | return new NativeInAppPurchaseModule(reactApplicationContext);
22 | } else {
23 | return null;
24 | }
25 | }
26 |
27 | @Override
28 | public ReactModuleInfoProvider getReactModuleInfoProvider() {
29 | return () -> {
30 | final Map moduleInfos = new HashMap<>();
31 | boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
32 |
33 | moduleInfos.put(
34 | NativeInAppPurchaseModule.NAME,
35 | new ReactModuleInfo(
36 | NativeInAppPurchaseModule.NAME,
37 | NativeInAppPurchaseModule.NAME,
38 | false, // canOverrideExistingModule
39 | false, // needsEagerInit
40 | false, // isCxxModule
41 | isTurboModule
42 | ));
43 | return moduleInfos;
44 | };
45 | }
46 | }
--------------------------------------------------------------------------------
/android/src/main/java/net/class101/iap/internal/utils/ReadableMapUtils.java:
--------------------------------------------------------------------------------
1 | package net.class101.iap.internal.utils;
2 |
3 | import com.facebook.react.bridge.Dynamic;
4 | import com.facebook.react.bridge.ReadableArray;
5 | import com.facebook.react.bridge.ReadableMap;
6 | import com.facebook.react.bridge.ReadableMapKeySetIterator;
7 |
8 | public class ReadableMapUtils {
9 | public static boolean deepEquals(ReadableMap map1, ReadableMap map2) {
10 | if (map1 == null && map2 == null) {
11 | return true;
12 | }
13 | if (map1 == null || map2 == null) {
14 | return false;
15 | }
16 |
17 | ReadableMapKeySetIterator iterator = map1.keySetIterator();
18 | while (iterator.hasNextKey()) {
19 | String key = iterator.nextKey();
20 | if (!map2.hasKey(key) || !deepEquals(map1.getDynamic(key), map2.getDynamic(key))) {
21 | return false;
22 | }
23 | }
24 |
25 | iterator = map2.keySetIterator();
26 | while (iterator.hasNextKey()) {
27 | String key = iterator.nextKey();
28 | if (!map1.hasKey(key)) {
29 | return false;
30 | }
31 | }
32 |
33 | return true;
34 | }
35 |
36 | private static boolean deepEquals(Dynamic value1, Dynamic value2) {
37 | if (value1.getType() != value2.getType()) return false;
38 | switch (value1.getType()) {
39 | case Null:
40 | return true;
41 | case Boolean:
42 | return value1.asBoolean() == value2.asBoolean();
43 | case Number:
44 | return value1.asDouble() == value2.asDouble();
45 | case String:
46 | return value1.asString().equals(value2.asString());
47 | case Map:
48 | return deepEquals(value1.asMap(), value2.asMap());
49 | case Array:
50 | return deepEquals(value1.asArray(), value2.asArray());
51 | default:
52 | return false;
53 | }
54 | }
55 |
56 | private static boolean deepEquals(ReadableArray array1, ReadableArray array2) {
57 | if (array1.size() != array2.size()) return false;
58 | for (int i = 0; i < array1.size(); i++) {
59 | if (!deepEquals(array1.getDynamic(i), array2.getDynamic(i))) return false;
60 | }
61 | return true;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/docs/android_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/docs/android_1.png
--------------------------------------------------------------------------------
/docs/ios_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/docs/ios_1.png
--------------------------------------------------------------------------------
/docs/ios_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/docs/ios_2.png
--------------------------------------------------------------------------------
/ios/RNInAppPurchase.h:
--------------------------------------------------------------------------------
1 | #ifndef RNInAppPurchase_h
2 | #define RNInAppPurchase_h
3 |
4 | #import
5 | #import
6 | #import
7 |
8 | #ifdef RCT_NEW_ARCH_ENABLED
9 | #import
10 | #endif /* RCT_NEW_ARCH_ENABLED */
11 |
12 | @interface RNInAppPurchase :
13 | #ifdef RCT_NEW_ARCH_ENABLED
14 | NSObject
15 | #else
16 | RCTEventEmitter
17 | #endif /* RCT_NEW_ARCH_ENABLED */
18 | {
19 | NSMutableDictionary* productsMap;
20 | NSMutableDictionary* transactionsMap;
21 |
22 | RCTResponseSenderBlock fetchProductsListener;
23 | RCTResponseSenderBlock purchaseListener;
24 | RCTResponseSenderBlock errorListener;
25 | RCTResponseSenderBlock alternativeBillingFlowListener;
26 | }
27 | @end
28 |
29 | #endif /* RNInAppPurchase_h */
30 |
31 |
--------------------------------------------------------------------------------
/ios/RNInAppPurchase.mm:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | #import
5 | #import "RNInAppPurchase.h"
6 |
7 | #import
8 |
9 | @implementation RNInAppPurchase
10 |
11 | - (instancetype) init {
12 | if (self = [super init]) {
13 | [[SKPaymentQueue defaultQueue] addTransactionObserver: self];
14 | }
15 | productsMap = [[NSMutableDictionary alloc] init];
16 | transactionsMap = [[NSMutableDictionary alloc] init];
17 |
18 | return self;
19 | }
20 |
21 | - (void) dealloc {
22 | [[SKPaymentQueue defaultQueue] removeTransactionObserver: self];
23 | }
24 |
25 | + (BOOL) requiresMainQueueSetup {
26 | return YES;
27 | }
28 |
29 | RCT_EXPORT_MODULE();
30 |
31 | RCT_EXPORT_METHOD(fetchProducts: (NSArray*) products) {
32 | NSSet* identifiers = [NSSet setWithArray: [products valueForKey: @"id"]];
33 | SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers: identifiers];
34 | productsRequest.delegate = self;
35 | [productsRequest start];
36 | }
37 |
38 | RCT_EXPORT_METHOD(onFetchProducts:(RCTResponseSenderBlock)listener) {
39 | fetchProductsListener = listener;
40 | }
41 |
42 | RCT_EXPORT_METHOD(onPurchase:(RCTResponseSenderBlock)listener) {
43 | purchaseListener = listener;
44 | }
45 |
46 | RCT_EXPORT_METHOD(onAlternativeBillingFlow:(RCTResponseSenderBlock)listener) {
47 | alternativeBillingFlowListener = listener;
48 | }
49 |
50 | RCT_EXPORT_METHOD(onError:(RCTResponseSenderBlock)listener) {
51 | errorListener = listener;
52 | }
53 |
54 | RCT_EXPORT_METHOD(flush: (RCTPromiseResolveBlock) resolve
55 | rejector: (RCTPromiseRejectBlock) reject) {
56 | NSArray* transactions = [[SKPaymentQueue defaultQueue] transactions];
57 | NSMutableArray* items = [NSMutableArray array];
58 |
59 | for (SKPaymentTransaction* transaction in transactions) {
60 | NSURL* receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
61 | NSData* receipt = [[NSData alloc] initWithContentsOfURL: receiptURL];
62 |
63 | if (!receipt) {
64 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
65 | continue;
66 | }
67 |
68 | if (!transaction.transactionIdentifier) {
69 | continue;
70 | }
71 |
72 | NSArray* productIds = @[transaction.payment.productIdentifier];
73 | NSDictionary* item = @{
74 | @"productIds": productIds,
75 | @"transactionId": transaction.transactionIdentifier,
76 | @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000),
77 | @"receipt": [receipt base64EncodedStringWithOptions: 0]
78 | };
79 |
80 | [transactionsMap setObject: transaction forKey: transaction.transactionIdentifier];
81 | [items addObject: item];
82 | }
83 |
84 | resolve(items);
85 | }
86 |
87 |
88 | - (void) paymentQueue: (SKPaymentQueue*) queue updatedTransactions: (NSArray*) transactions {
89 | for (SKPaymentTransaction* transaction in transactions) {
90 | switch (transaction.transactionState) {
91 | case SKPaymentTransactionStatePurchased: {
92 | NSURL* receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
93 | NSData* receipt = [[NSData alloc] initWithContentsOfURL: receiptURL];
94 |
95 | if (!receipt) {
96 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
97 | return;
98 | }
99 |
100 | NSArray* productIds = @[transaction.payment.productIdentifier];
101 | NSDictionary* item = @{
102 | @"productIds": productIds,
103 | @"transactionId": transaction.transactionIdentifier,
104 | @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000),
105 | @"receipt": [receipt base64EncodedStringWithOptions: 0]
106 | };
107 |
108 | [transactionsMap setObject: transaction forKey: transaction.transactionIdentifier];
109 | purchaseListener(@[item]);
110 | break;
111 | }
112 | case SKPaymentTransactionStateFailed: {
113 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
114 | NSDictionary* error = @{
115 | @"code": [@(transaction.error.code) stringValue],
116 | @"message": transaction.error.localizedDescription
117 | };
118 | [self sendError: @"PURCHASE" body: error];
119 | break;
120 | }
121 | case SKPaymentTransactionStateRestored:
122 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
123 | break;
124 | case SKPaymentTransactionStateDeferred:
125 | break;
126 | case SKPaymentTransactionStatePurchasing:
127 | break;
128 | }
129 | }
130 | }
131 |
132 | - (void) productsRequest: (SKProductsRequest*) request didReceiveResponse: (SKProductsResponse*) response {
133 | NSMutableArray* items = [NSMutableArray array];
134 |
135 | for (SKProduct* product in response.products) {
136 | NSString* title = product.localizedTitle ? product.localizedTitle : @"";
137 | NSString* description = product.localizedDescription ? product.localizedDescription : @"";
138 | NSString* currency = @"";
139 |
140 | if (@available(iOS 10.0, *)) {
141 | currency = product.priceLocale.currencyCode;
142 | }
143 |
144 | NSDictionary* item = @{
145 | @"productId": product.productIdentifier,
146 | @"price": [product.price stringValue],
147 | @"currency": currency,
148 | @"title": title,
149 | @"description": description
150 | };
151 | [items addObject: item];
152 | [productsMap setObject: product forKey: product.productIdentifier];
153 | }
154 |
155 | fetchProductsListener(@[items]); // or iap:onFetchProductsFailure
156 | }
157 |
158 | - (void) sendError: (NSString*) errorType body: (NSDictionary*) body {
159 | NSMutableDictionary *mutableDict = [body mutableCopy];
160 | [mutableDict setObject:errorType forKey:@"type"];
161 | errorListener(@[mutableDict]);
162 | }
163 |
164 |
165 | RCT_EXPORT_METHOD(clear) {
166 |
167 | }
168 |
169 |
170 | RCT_EXPORT_METHOD(fetchReceipt: (RCTPromiseResolveBlock) resolve
171 | rejector: (RCTPromiseRejectBlock) reject) {
172 | NSURL* receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
173 | NSData* receipt = [[NSData alloc] initWithContentsOfURL: receiptURL];
174 |
175 | if (receipt == nil) {
176 | resolve(nil);
177 | return;
178 | }
179 |
180 | NSString* encodedReceipt = [receipt base64EncodedStringWithOptions: 0];
181 | resolve(encodedReceipt);
182 | }
183 |
184 | #if RCT_NEW_ARCH_ENABLED
185 | RCT_EXPORT_METHOD(configure:(JS::NativeInAppPurchaseModule::SpecConfigureConfig &)config
186 | resolve:(RCTPromiseResolveBlock)resolve
187 | reject:(RCTPromiseRejectBlock)reject) {
188 | resolve(@([SKPaymentQueue canMakePayments]));
189 | }
190 |
191 | RCT_EXPORT_METHOD(purchase:(NSString *)productId
192 | args:(JS::NativeInAppPurchaseModule::PurchaseArgs &)args) {
193 | SKProduct* product = productsMap[productId];
194 |
195 | if (!product) {
196 | [self sendError:@"PURCHASE" body: @{ @"message": @"Invalid product id" }];
197 | return;
198 | }
199 |
200 | SKMutablePayment* payment = [SKMutablePayment paymentWithProduct: product];
201 | payment.applicationUsername = args.userId();
202 |
203 | if (@available(iOS 12.2, *)) {
204 | NSUUID* nonce = nil;
205 | if (args.nonce() != nil) {
206 | nonce = [[NSUUID new] initWithUUIDString:args.nonce()];
207 | }
208 |
209 | if (args.offerId() != nil && args.keyIdentifier() != nil && nonce != nil && args.signature() != nil && args.timestamp() != std::nullopt) {
210 | SKPaymentDiscount* paymentDiscount = [[SKPaymentDiscount new] initWithIdentifier:args.offerId() keyIdentifier:args.keyIdentifier() nonce:nonce signature:args.signature() timestamp:[NSNumber numberWithDouble: args.timestamp().value()]];
211 | payment.paymentDiscount = paymentDiscount;
212 | }
213 | }
214 |
215 | [[SKPaymentQueue defaultQueue] addPayment: payment];
216 | }
217 |
218 | RCT_EXPORT_METHOD(finalize:(JS::NativeInAppPurchaseModule::Purchase &)purchase
219 | isConsumable:(BOOL)isConsumable
220 | resolve:(RCTPromiseResolveBlock)resolve
221 | reject:(RCTPromiseRejectBlock)reject) {
222 | NSString* transactionId = purchase.transactionId();
223 | SKPaymentTransaction* transaction = transactionsMap[transactionId];
224 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
225 | resolve(@{ @"message": @"Finalize success" });
226 | }
227 |
228 | - (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
229 | return std::make_shared(params);
230 | }
231 |
232 | #else
233 | RCT_EXPORT_METHOD(configure: (NSDictionary*) config
234 | resolver: (RCTPromiseResolveBlock) resolve
235 | rejector: (RCTPromiseRejectBlock) reject) {
236 | resolve(@([SKPaymentQueue canMakePayments]));
237 | }
238 |
239 | RCT_EXPORT_METHOD(purchase: (NSString*) productId
240 | extras: (NSDictionary*) extras) {
241 | SKProduct* product = productsMap[productId];
242 |
243 | if (!product) {
244 | [self sendError:@"PURCHASE" body: @{ @"message": @"Invalid product id" }];
245 | return;
246 | }
247 |
248 | NSString* offerId = extras[@"offerId"];
249 | NSString* userId = extras[@"userId"];
250 | NSString* keyIdentifier = extras[@"keyIdentifier"];
251 | NSString* nonceString = extras[@"nonce"];
252 | NSString* signature = extras[@"signature"];
253 | NSNumber* timestamp = extras[@"timestamp"];
254 |
255 | SKMutablePayment* payment = [SKMutablePayment paymentWithProduct: product];
256 | payment.applicationUsername = userId;
257 |
258 | if (@available(iOS 12.2, *)) {
259 | NSUUID* nonce = nil;
260 | if (nonceString != nil) {
261 | nonce = [[NSUUID new] initWithUUIDString:nonceString];
262 | }
263 |
264 | if (offerId != nil && keyIdentifier != nil && nonce != nil && signature != nil && timestamp != nil) {
265 | SKPaymentDiscount* paymentDiscount = [[SKPaymentDiscount new] initWithIdentifier:offerId keyIdentifier:keyIdentifier nonce:nonce signature:signature timestamp:timestamp];
266 | payment.paymentDiscount = paymentDiscount;
267 | }
268 | }
269 |
270 | [[SKPaymentQueue defaultQueue] addPayment: payment];
271 | }
272 |
273 | RCT_EXPORT_METHOD(finalize: (NSDictionary*) purchase
274 | resolver: (RCTPromiseResolveBlock) resolve
275 | rejector: (RCTPromiseRejectBlock) reject) {
276 | NSString* transactionId = purchase[@"transactionId"];
277 | SKPaymentTransaction* transaction = transactionsMap[transactionId];
278 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
279 | resolve(@{ @"message": @"Finalize success" });
280 | }
281 |
282 | #endif /* RCT_NEW_ARCH_ENABLED */
283 |
284 | @end
285 |
--------------------------------------------------------------------------------
/ios/RNInAppPurchase.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B3E7B58A1CC2AC0600A0062D /* RNInAppPurchase.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNInAppPurchase.m */; };
11 | /* End PBXBuildFile section */
12 |
13 | /* Begin PBXCopyFilesBuildPhase section */
14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = {
15 | isa = PBXCopyFilesBuildPhase;
16 | buildActionMask = 2147483647;
17 | dstPath = "include/$(PRODUCT_NAME)";
18 | dstSubfolderSpec = 16;
19 | files = (
20 | );
21 | runOnlyForDeploymentPostprocessing = 0;
22 | };
23 | /* End PBXCopyFilesBuildPhase section */
24 |
25 | /* Begin PBXFileReference section */
26 | 134814201AA4EA6300B7C361 /* libRNInAppPurchase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNInAppPurchase.a; sourceTree = BUILT_PRODUCTS_DIR; };
27 | B3E7B5881CC2AC0600A0062D /* RNInAppPurchase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNInAppPurchase.h; sourceTree = ""; };
28 | B3E7B5891CC2AC0600A0062D /* RNInAppPurchase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNInAppPurchase.m; sourceTree = ""; };
29 | /* End PBXFileReference section */
30 |
31 | /* Begin PBXFrameworksBuildPhase section */
32 | 58B511D81A9E6C8500147676 /* Frameworks */ = {
33 | isa = PBXFrameworksBuildPhase;
34 | buildActionMask = 2147483647;
35 | files = (
36 | );
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXFrameworksBuildPhase section */
40 |
41 | /* Begin PBXGroup section */
42 | 134814211AA4EA7D00B7C361 /* Products */ = {
43 | isa = PBXGroup;
44 | children = (
45 | 134814201AA4EA6300B7C361 /* libRNInAppPurchase.a */,
46 | );
47 | name = Products;
48 | sourceTree = "";
49 | };
50 | 58B511D21A9E6C8500147676 = {
51 | isa = PBXGroup;
52 | children = (
53 | B3E7B5881CC2AC0600A0062D /* RNInAppPurchase.h */,
54 | B3E7B5891CC2AC0600A0062D /* RNInAppPurchase.m */,
55 | 134814211AA4EA7D00B7C361 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | /* End PBXGroup section */
60 |
61 | /* Begin PBXNativeTarget section */
62 | 58B511DA1A9E6C8500147676 /* RNInAppPurchase */ = {
63 | isa = PBXNativeTarget;
64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNInAppPurchase" */;
65 | buildPhases = (
66 | 58B511D71A9E6C8500147676 /* Sources */,
67 | 58B511D81A9E6C8500147676 /* Frameworks */,
68 | 58B511D91A9E6C8500147676 /* CopyFiles */,
69 | );
70 | buildRules = (
71 | );
72 | dependencies = (
73 | );
74 | name = RNInAppPurchase;
75 | productName = RCTDataManager;
76 | productReference = 134814201AA4EA6300B7C361 /* libRNInAppPurchase.a */;
77 | productType = "com.apple.product-type.library.static";
78 | };
79 | /* End PBXNativeTarget section */
80 |
81 | /* Begin PBXProject section */
82 | 58B511D31A9E6C8500147676 /* Project object */ = {
83 | isa = PBXProject;
84 | attributes = {
85 | LastUpgradeCheck = 0830;
86 | ORGANIZATIONNAME = Facebook;
87 | TargetAttributes = {
88 | 58B511DA1A9E6C8500147676 = {
89 | CreatedOnToolsVersion = 6.1.1;
90 | };
91 | };
92 | };
93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNInAppPurchase" */;
94 | compatibilityVersion = "Xcode 3.2";
95 | developmentRegion = English;
96 | hasScannedForEncodings = 0;
97 | knownRegions = (
98 | en,
99 | );
100 | mainGroup = 58B511D21A9E6C8500147676;
101 | productRefGroup = 58B511D21A9E6C8500147676;
102 | projectDirPath = "";
103 | projectRoot = "";
104 | targets = (
105 | 58B511DA1A9E6C8500147676 /* RNInAppPurchase */,
106 | );
107 | };
108 | /* End PBXProject section */
109 |
110 | /* Begin PBXSourcesBuildPhase section */
111 | 58B511D71A9E6C8500147676 /* Sources */ = {
112 | isa = PBXSourcesBuildPhase;
113 | buildActionMask = 2147483647;
114 | files = (
115 | B3E7B58A1CC2AC0600A0062D /* RNInAppPurchase.m in Sources */,
116 | );
117 | runOnlyForDeploymentPostprocessing = 0;
118 | };
119 | /* End PBXSourcesBuildPhase section */
120 |
121 | /* Begin XCBuildConfiguration section */
122 | 58B511ED1A9E6C8500147676 /* Debug */ = {
123 | isa = XCBuildConfiguration;
124 | buildSettings = {
125 | ALWAYS_SEARCH_USER_PATHS = NO;
126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
127 | CLANG_CXX_LIBRARY = "libc++";
128 | CLANG_ENABLE_MODULES = YES;
129 | CLANG_ENABLE_OBJC_ARC = YES;
130 | CLANG_WARN_BOOL_CONVERSION = YES;
131 | CLANG_WARN_CONSTANT_CONVERSION = YES;
132 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
133 | CLANG_WARN_EMPTY_BODY = YES;
134 | CLANG_WARN_ENUM_CONVERSION = YES;
135 | CLANG_WARN_INFINITE_RECURSION = YES;
136 | CLANG_WARN_INT_CONVERSION = YES;
137 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
138 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
139 | CLANG_WARN_UNREACHABLE_CODE = YES;
140 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
141 | COPY_PHASE_STRIP = NO;
142 | ENABLE_STRICT_OBJC_MSGSEND = YES;
143 | ENABLE_TESTABILITY = YES;
144 | GCC_C_LANGUAGE_STANDARD = gnu99;
145 | GCC_DYNAMIC_NO_PIC = NO;
146 | GCC_NO_COMMON_BLOCKS = YES;
147 | GCC_OPTIMIZATION_LEVEL = 0;
148 | GCC_PREPROCESSOR_DEFINITIONS = (
149 | "DEBUG=1",
150 | "$(inherited)",
151 | );
152 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
153 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
154 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
155 | GCC_WARN_UNDECLARED_SELECTOR = YES;
156 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
157 | GCC_WARN_UNUSED_FUNCTION = YES;
158 | GCC_WARN_UNUSED_VARIABLE = YES;
159 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
160 | MTL_ENABLE_DEBUG_INFO = YES;
161 | ONLY_ACTIVE_ARCH = YES;
162 | SDKROOT = iphoneos;
163 | };
164 | name = Debug;
165 | };
166 | 58B511EE1A9E6C8500147676 /* Release */ = {
167 | isa = XCBuildConfiguration;
168 | buildSettings = {
169 | ALWAYS_SEARCH_USER_PATHS = NO;
170 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
171 | CLANG_CXX_LIBRARY = "libc++";
172 | CLANG_ENABLE_MODULES = YES;
173 | CLANG_ENABLE_OBJC_ARC = YES;
174 | CLANG_WARN_BOOL_CONVERSION = YES;
175 | CLANG_WARN_CONSTANT_CONVERSION = YES;
176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
177 | CLANG_WARN_EMPTY_BODY = YES;
178 | CLANG_WARN_ENUM_CONVERSION = YES;
179 | CLANG_WARN_INFINITE_RECURSION = YES;
180 | CLANG_WARN_INT_CONVERSION = YES;
181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
182 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
183 | CLANG_WARN_UNREACHABLE_CODE = YES;
184 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
185 | COPY_PHASE_STRIP = YES;
186 | ENABLE_NS_ASSERTIONS = NO;
187 | ENABLE_STRICT_OBJC_MSGSEND = YES;
188 | GCC_C_LANGUAGE_STANDARD = gnu99;
189 | GCC_NO_COMMON_BLOCKS = YES;
190 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
191 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
192 | GCC_WARN_UNDECLARED_SELECTOR = YES;
193 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
194 | GCC_WARN_UNUSED_FUNCTION = YES;
195 | GCC_WARN_UNUSED_VARIABLE = YES;
196 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
197 | MTL_ENABLE_DEBUG_INFO = NO;
198 | SDKROOT = iphoneos;
199 | VALIDATE_PRODUCT = YES;
200 | };
201 | name = Release;
202 | };
203 | 58B511F01A9E6C8500147676 /* Debug */ = {
204 | isa = XCBuildConfiguration;
205 | buildSettings = {
206 | HEADER_SEARCH_PATHS = (
207 | "$(inherited)",
208 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
209 | "$(SRCROOT)/../../../React/**",
210 | "$(SRCROOT)/../../react-native/React/**",
211 | );
212 | LIBRARY_SEARCH_PATHS = "$(inherited)";
213 | OTHER_LDFLAGS = "-ObjC";
214 | PRODUCT_NAME = RNInAppPurchase;
215 | SKIP_INSTALL = YES;
216 | };
217 | name = Debug;
218 | };
219 | 58B511F11A9E6C8500147676 /* Release */ = {
220 | isa = XCBuildConfiguration;
221 | buildSettings = {
222 | HEADER_SEARCH_PATHS = (
223 | "$(inherited)",
224 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
225 | "$(SRCROOT)/../../../React/**",
226 | "$(SRCROOT)/../../react-native/React/**",
227 | );
228 | LIBRARY_SEARCH_PATHS = "$(inherited)";
229 | OTHER_LDFLAGS = "-ObjC";
230 | PRODUCT_NAME = RNInAppPurchase;
231 | SKIP_INSTALL = YES;
232 | };
233 | name = Release;
234 | };
235 | /* End XCBuildConfiguration section */
236 |
237 | /* Begin XCConfigurationList section */
238 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNInAppPurchase" */ = {
239 | isa = XCConfigurationList;
240 | buildConfigurations = (
241 | 58B511ED1A9E6C8500147676 /* Debug */,
242 | 58B511EE1A9E6C8500147676 /* Release */,
243 | );
244 | defaultConfigurationIsVisible = 0;
245 | defaultConfigurationName = Release;
246 | };
247 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNInAppPurchase" */ = {
248 | isa = XCConfigurationList;
249 | buildConfigurations = (
250 | 58B511F01A9E6C8500147676 /* Debug */,
251 | 58B511F11A9E6C8500147676 /* Release */,
252 | );
253 | defaultConfigurationIsVisible = 0;
254 | defaultConfigurationName = Release;
255 | };
256 | /* End XCConfigurationList section */
257 | };
258 | rootObject = 58B511D31A9E6C8500147676 /* Project object */;
259 | }
260 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@class101/react-native-in-app-purchase",
3 | "version": "3.0.0-rc1",
4 | "description": "👻 A dead simple in app purchase library for React Native",
5 | "main": "src/index.ts",
6 | "repository": "https://github.com/pedaling/react-native-in-app-purchase",
7 | "keywords": [
8 | "react-native",
9 | "in-app-purchase",
10 | "purchase",
11 | "billing"
12 | ],
13 | "author": "Injung Chung ",
14 | "license": "MIT",
15 | "peerDependencies": {
16 | "react-native": "*"
17 | },
18 | "codegenConfig": {
19 | "name": "InAppPurchase",
20 | "type": "all",
21 | "jsSrcsDir": "src",
22 | "outputDir": {
23 | "ios": "ios/generated",
24 | "android": "android/generated"
25 | },
26 | "includesGeneratedCode": true,
27 | "android": {
28 | "javaPackageName": "net.class101.iap"
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/sample/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native',
4 | };
5 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 |
37 | # node.js
38 | #
39 | node_modules/
40 | npm-debug.log
41 | yarn-error.log
42 |
43 | # fastlane
44 | #
45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
46 | # screenshots whenever they are needed.
47 | # For more information about the recommended setup visit:
48 | # https://docs.fastlane.tools/best-practices/source-control/
49 |
50 | **/fastlane/report.xml
51 | **/fastlane/Preview.html
52 | **/fastlane/screenshots
53 | **/fastlane/test_output
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # Ruby / CocoaPods
59 | /ios/Pods/
60 | /vendor/bundle/
61 |
62 | # Temporary files created by Metro to check the health of the file watcher
63 | .metro-health-check*
64 |
65 | # testing
66 | /coverage
67 |
--------------------------------------------------------------------------------
/sample/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: false,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/sample/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true
3 | }
--------------------------------------------------------------------------------
/sample/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/sample/App.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState, useCallback } from 'react';
2 | import {
3 | Alert,
4 | View,
5 | Text,
6 | TouchableOpacity,
7 | StyleSheet,
8 | } from 'react-native';
9 | import InAppPurchase from '@class101/react-native-in-app-purchase';
10 |
11 | const PRODUCT_IDS = [
12 | {id: 'rniap.sample.normal',},
13 | {
14 | id: 'rniap.sample.consumable'},
15 | { id: 'rniap.sample.subscribe'},
16 | ];
17 |
18 | const App = () => {
19 | const [products, setProducts] = useState([]);
20 |
21 | const handleFetchProducts = (fetchedProducts) => {
22 | console.log(fetchedProducts);
23 | setProducts(fetchedProducts);
24 | };
25 |
26 | const handlePurchase = (purchase) => {
27 | setTimeout(() => {
28 | InAppPurchase.finalize(purchase, purchase.productId === 'rniap.sample.consumable').then(() => {
29 | Alert.alert('In App Purchase', 'Purchase Succeed!');
30 | });
31 | });
32 | };
33 |
34 |
35 | useEffect(() => {
36 | const handleError = (error) => {
37 | console.log(error);
38 | };
39 |
40 | InAppPurchase.onFetchProducts(handleFetchProducts);
41 | InAppPurchase.onPurchase(handlePurchase);
42 | InAppPurchase.onError(handleError);
43 |
44 | InAppPurchase.configure().then(() => {
45 | InAppPurchase.fetchProducts(PRODUCT_IDS);
46 | });
47 |
48 | return () => {
49 | InAppPurchase.clear();
50 | };
51 | }, []);
52 |
53 | const flush = useCallback(() => {
54 | InAppPurchase.flush().then((purchases) => {
55 | console.log(purchases);
56 | purchases.forEach((purchase) => {
57 | handlePurchase(purchase);
58 | });
59 | });
60 | }, []);
61 |
62 | const renderItem = useCallback((item) => (
63 | InAppPurchase.purchase(item.productId)}
67 | style={styles.item}
68 | >
69 |
70 | {item.title}
71 |
72 |
73 |
74 | {item.currency} {item.price}
75 |
76 |
77 |
78 | ), []);
79 |
80 | return (
81 |
82 | {products.map(renderItem)}
83 |
88 |
89 | Flush uncompleted purchases
90 |
91 |
92 |
93 | );
94 | };
95 |
96 | const styles = StyleSheet.create({
97 | container: {
98 | flex: 1,
99 | justifyContent: 'center',
100 | backgroundColor: '#FFF',
101 | },
102 | item: {
103 | flexDirection: 'row',
104 | justifyContent: 'space-between',
105 | alignItems: 'center',
106 | marginBottom: 24,
107 | marginHorizontal: 24,
108 | paddingVertical: 20,
109 | paddingHorizontal: 16,
110 | backgroundColor: '#F2F4F9',
111 | },
112 | title: {
113 | fontSize: 16,
114 | color: '#191919',
115 | },
116 | priceTag: {
117 | paddingHorizontal: 8,
118 | paddingVertical: 4,
119 | borderRadius: 2,
120 | backgroundColor: '#2D2D2D'
121 | },
122 | priceText: {
123 | fontSize: 12,
124 | color: '#FAFAFA',
125 | },
126 | button: {
127 | marginTop: 16,
128 | marginBottom: 0,
129 | justifyContent: 'center',
130 | backgroundColor: '#2D2D2D',
131 | borderRadius: 32,
132 | },
133 | text: {
134 | fontSize: 16,
135 | color: '#FAFAFA',
136 | },
137 | });
138 |
139 | export default App;
--------------------------------------------------------------------------------
/sample/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby ">= 2.6.10"
5 |
6 | # Cocoapods 1.15 introduced a bug which break the build. We will remove the upper
7 | # bound in the template on Cocoapods with next React Native release.
8 | gem 'cocoapods', '>= 1.13', '< 1.15'
9 | gem 'activesupport', '>= 6.1.7.5', '< 7.1.0'
10 |
--------------------------------------------------------------------------------
/sample/__tests__/App.test.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'react-native';
6 | import React from 'react';
7 | import App from '../App';
8 |
9 | // Note: import explicitly to use the types shipped with jest.
10 | import {it} from '@jest/globals';
11 |
12 | // Note: test renderer must be required after react-native.
13 | import renderer from 'react-test-renderer';
14 |
15 | it('renders correctly', () => {
16 | renderer.create();
17 | });
18 |
--------------------------------------------------------------------------------
/sample/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 | apply plugin: "org.jetbrains.kotlin.android"
3 | apply plugin: "com.facebook.react"
4 |
5 | /**
6 | * This is the configuration block to customize your React Native Android app.
7 | * By default you don't need to apply any configuration, just uncomment the lines you need.
8 | */
9 | react {
10 | /* Folders */
11 | // The root of your project, i.e. where "package.json" lives. Default is '..'
12 | // root = file("../")
13 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native
14 | // reactNativeDir = file("../node_modules/react-native")
15 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
16 | // codegenDir = file("../node_modules/@react-native/codegen")
17 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
18 | // cliFile = file("../node_modules/react-native/cli.js")
19 |
20 | /* Variants */
21 | // The list of variants to that are debuggable. For those we're going to
22 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
23 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
24 | // debuggableVariants = ["liteDebug", "prodDebug"]
25 |
26 | /* Bundling */
27 | // A list containing the node command and its flags. Default is just 'node'.
28 | // nodeExecutableAndArgs = ["node"]
29 | //
30 | // The command to run when bundling. By default is 'bundle'
31 | // bundleCommand = "ram-bundle"
32 | //
33 | // The path to the CLI configuration file. Default is empty.
34 | // bundleConfig = file(../rn-cli.config.js)
35 | //
36 | // The name of the generated asset file containing your JS bundle
37 | // bundleAssetName = "MyApplication.android.bundle"
38 | //
39 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
40 | // entryFile = file("../js/MyApplication.android.js")
41 | //
42 | // A list of extra flags to pass to the 'bundle' commands.
43 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
44 | // extraPackagerArgs = []
45 |
46 | /* Hermes Commands */
47 | // The hermes compiler command to run. By default it is 'hermesc'
48 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
49 | //
50 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
51 | // hermesFlags = ["-O", "-output-source-map"]
52 | }
53 |
54 | /**
55 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
56 | */
57 | def enableProguardInReleaseBuilds = false
58 |
59 | /**
60 | * The preferred build flavor of JavaScriptCore (JSC)
61 | *
62 | * For example, to use the international variant, you can use:
63 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
64 | *
65 | * The international variant includes ICU i18n library and necessary data
66 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
67 | * give correct results when using with locales other than en-US. Note that
68 | * this variant is about 6MiB larger per architecture than default.
69 | */
70 | def jscFlavor = 'org.webkit:android-jsc:+'
71 |
72 | android {
73 | ndkVersion rootProject.ext.ndkVersion
74 | buildToolsVersion rootProject.ext.buildToolsVersion
75 | compileSdk rootProject.ext.compileSdkVersion
76 |
77 | namespace "com.rninapppurchasesample"
78 | defaultConfig {
79 | applicationId "com.rninapppurchasesample"
80 | minSdkVersion rootProject.ext.minSdkVersion
81 | targetSdkVersion rootProject.ext.targetSdkVersion
82 | versionCode 1
83 | versionName "1.0"
84 | }
85 | signingConfigs {
86 | debug {
87 | storeFile file('debug.keystore')
88 | storePassword 'android'
89 | keyAlias 'androiddebugkey'
90 | keyPassword 'android'
91 | }
92 | }
93 | buildTypes {
94 | debug {
95 | signingConfig signingConfigs.debug
96 | }
97 | release {
98 | // Caution! In production, you need to generate your own keystore file.
99 | // see https://reactnative.dev/docs/signed-apk-android.
100 | signingConfig signingConfigs.debug
101 | minifyEnabled enableProguardInReleaseBuilds
102 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
103 | }
104 | }
105 | }
106 |
107 | dependencies {
108 | // The version of react-native is set by the React Native Gradle Plugin
109 | implementation("com.facebook.react:react-android")
110 | implementation("com.facebook.react:flipper-integration")
111 |
112 | if (hermesEnabled.toBoolean()) {
113 | implementation("com.facebook.react:hermes-android")
114 | } else {
115 | implementation jscFlavor
116 | }
117 | }
118 |
119 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
120 |
--------------------------------------------------------------------------------
/sample/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/debug.keystore
--------------------------------------------------------------------------------
/sample/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/sample/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/sample/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/sample/android/app/src/main/java/com/rninapppurchasesample/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.rninapppurchasesample
2 |
3 | import com.facebook.react.ReactActivity
4 | import com.facebook.react.ReactActivityDelegate
5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
6 | import com.facebook.react.defaults.DefaultReactActivityDelegate
7 |
8 | class MainActivity : ReactActivity() {
9 |
10 | /**
11 | * Returns the name of the main component registered from JavaScript. This is used to schedule
12 | * rendering of the component.
13 | */
14 | override fun getMainComponentName(): String = "RNInAppPurchaseSample"
15 |
16 | /**
17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
19 | */
20 | override fun createReactActivityDelegate(): ReactActivityDelegate =
21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
22 | }
23 |
--------------------------------------------------------------------------------
/sample/android/app/src/main/java/com/rninapppurchasesample/MainApplication.kt:
--------------------------------------------------------------------------------
1 | package com.rninapppurchasesample
2 |
3 | import android.app.Application
4 | import com.facebook.react.PackageList
5 | import com.facebook.react.ReactApplication
6 | import com.facebook.react.ReactHost
7 | import com.facebook.react.ReactNativeHost
8 | import com.facebook.react.ReactPackage
9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
11 | import com.facebook.react.defaults.DefaultReactNativeHost
12 | import com.facebook.react.flipper.ReactNativeFlipper
13 | import com.facebook.soloader.SoLoader
14 |
15 | class MainApplication : Application(), ReactApplication {
16 |
17 | override val reactNativeHost: ReactNativeHost =
18 | object : DefaultReactNativeHost(this) {
19 | override fun getPackages(): List =
20 | PackageList(this).packages.apply {
21 | // Packages that cannot be autolinked yet can be added manually here, for example:
22 | // add(MyReactNativePackage())
23 | }
24 |
25 | override fun getJSMainModuleName(): String = "index"
26 |
27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
28 |
29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
31 | }
32 |
33 | override val reactHost: ReactHost
34 | get() = getDefaultReactHost(this.applicationContext, reactNativeHost)
35 |
36 | override fun onCreate() {
37 | super.onCreate()
38 | SoLoader.init(this, false)
39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
40 | // If you opted-in for the New Architecture, we load the native entry point for this app.
41 | load()
42 | }
43 | ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | RNInAppPurchaseSample
3 |
4 |
--------------------------------------------------------------------------------
/sample/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/sample/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext {
3 | buildToolsVersion = "34.0.0"
4 | minSdkVersion = 24
5 | compileSdkVersion = 34
6 | targetSdkVersion = 34
7 | ndkVersion = "25.1.8937393"
8 | kotlinVersion = "1.8.0"
9 | }
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | dependencies {
15 | classpath("com.android.tools.build:gradle")
16 | classpath("com.facebook.react:react-native-gradle-plugin")
17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
18 | }
19 | }
20 |
21 | apply plugin: "com.facebook.react.rootproject"
22 |
--------------------------------------------------------------------------------
/sample/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 | # Automatically convert third-party libraries to use AndroidX
25 | android.enableJetifier=true
26 |
27 | # Use this property to specify which architecture you want to build.
28 | # You can also override it from the CLI using
29 | # ./gradlew -PreactNativeArchitectures=x86_64
30 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
31 |
32 | # Use this property to enable support to the new architecture.
33 | # This will allow you to use TurboModules and the Fabric render in
34 | # your application. You should enable this flag either if you want
35 | # to write custom TurboModules/Fabric components OR use libraries that
36 | # are providing them.
37 | newArchEnabled=false
38 |
39 | # Use this property to enable or disable the Hermes JS engine.
40 | # If set to false, you will be using JSC instead.
41 | hermesEnabled=true
42 |
--------------------------------------------------------------------------------
/sample/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/sample/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/sample/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command;
206 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
207 | # shell script including quotes and variable substitutions, so put them in
208 | # double quotes to make sure that they get re-expanded; and
209 | # * put everything else in single quotes, so that it's not re-expanded.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/sample/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/sample/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'RNInAppPurchaseSample'
2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
3 | applyNativeModulesSettingsGradle(settings)
4 |
5 | include ':app'
6 | includeBuild('../node_modules/@react-native/gradle-plugin')
7 |
--------------------------------------------------------------------------------
/sample/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "RNInAppPurchaseSample",
3 | "displayName": "RNInAppPurchaseSample"
4 | }
5 |
--------------------------------------------------------------------------------
/sample/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | };
4 |
--------------------------------------------------------------------------------
/sample/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import {AppRegistry} from 'react-native';
6 | import App from './App';
7 | import {name as appName} from './app.json';
8 |
9 | AppRegistry.registerComponent(appName, () => App);
10 |
--------------------------------------------------------------------------------
/sample/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/sample/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Resolve react_native_pods.rb with node to allow for hoisting
2 | require Pod::Executable.execute_command('node', ['-p',
3 | 'require.resolve(
4 | "react-native/scripts/react_native_pods.rb",
5 | {paths: [process.argv[1]]},
6 | )', __dir__]).strip
7 |
8 | platform :ios, min_ios_version_supported
9 | prepare_react_native_project!
10 |
11 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
12 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
13 | #
14 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
15 | # ```js
16 | # module.exports = {
17 | # dependencies: {
18 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
19 | # ```
20 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
21 |
22 | linkage = ENV['USE_FRAMEWORKS']
23 | if linkage != nil
24 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
25 | use_frameworks! :linkage => linkage.to_sym
26 | end
27 |
28 | target 'RNInAppPurchaseSample' do
29 | config = use_native_modules!
30 |
31 | use_react_native!(
32 | :path => config[:reactNativePath],
33 | # Enables Flipper.
34 | #
35 | # Note that if you have use_frameworks! enabled, Flipper will not work and
36 | # you should disable the next line.
37 | :flipper_configuration => flipper_config,
38 | # An absolute path to your application root.
39 | :app_path => "#{Pod::Config.instance.installation_root}/.."
40 | )
41 |
42 | target 'RNInAppPurchaseSampleTests' do
43 | inherit! :complete
44 | # Pods for testing
45 | end
46 |
47 | post_install do |installer|
48 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
49 | react_native_post_install(
50 | installer,
51 | config[:reactNativePath],
52 | :mac_catalyst_enabled => false
53 | )
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/sample/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - boost (1.83.0)
3 | - CocoaAsyncSocket (7.6.5)
4 | - DoubleConversion (1.1.6)
5 | - FBLazyVector (0.73.9)
6 | - FBReactNativeSpec (0.73.9):
7 | - RCT-Folly (= 2022.05.16.00)
8 | - RCTRequired (= 0.73.9)
9 | - RCTTypeSafety (= 0.73.9)
10 | - React-Core (= 0.73.9)
11 | - React-jsi (= 0.73.9)
12 | - ReactCommon/turbomodule/core (= 0.73.9)
13 | - Flipper (0.201.0):
14 | - Flipper-Folly (~> 2.6)
15 | - Flipper-Boost-iOSX (1.76.0.1.11)
16 | - Flipper-DoubleConversion (3.2.0.1)
17 | - Flipper-Fmt (7.1.7)
18 | - Flipper-Folly (2.6.10):
19 | - Flipper-Boost-iOSX
20 | - Flipper-DoubleConversion
21 | - Flipper-Fmt (= 7.1.7)
22 | - Flipper-Glog
23 | - libevent (~> 2.1.12)
24 | - OpenSSL-Universal (= 1.1.1100)
25 | - Flipper-Glog (0.5.0.5)
26 | - Flipper-PeerTalk (0.0.4)
27 | - FlipperKit (0.201.0):
28 | - FlipperKit/Core (= 0.201.0)
29 | - FlipperKit/Core (0.201.0):
30 | - Flipper (~> 0.201.0)
31 | - FlipperKit/CppBridge
32 | - FlipperKit/FBCxxFollyDynamicConvert
33 | - FlipperKit/FBDefines
34 | - FlipperKit/FKPortForwarding
35 | - SocketRocket (~> 0.6.0)
36 | - FlipperKit/CppBridge (0.201.0):
37 | - Flipper (~> 0.201.0)
38 | - FlipperKit/FBCxxFollyDynamicConvert (0.201.0):
39 | - Flipper-Folly (~> 2.6)
40 | - FlipperKit/FBDefines (0.201.0)
41 | - FlipperKit/FKPortForwarding (0.201.0):
42 | - CocoaAsyncSocket (~> 7.6)
43 | - Flipper-PeerTalk (~> 0.0.4)
44 | - FlipperKit/FlipperKitHighlightOverlay (0.201.0)
45 | - FlipperKit/FlipperKitLayoutHelpers (0.201.0):
46 | - FlipperKit/Core
47 | - FlipperKit/FlipperKitHighlightOverlay
48 | - FlipperKit/FlipperKitLayoutTextSearchable
49 | - FlipperKit/FlipperKitLayoutIOSDescriptors (0.201.0):
50 | - FlipperKit/Core
51 | - FlipperKit/FlipperKitHighlightOverlay
52 | - FlipperKit/FlipperKitLayoutHelpers
53 | - FlipperKit/FlipperKitLayoutPlugin (0.201.0):
54 | - FlipperKit/Core
55 | - FlipperKit/FlipperKitHighlightOverlay
56 | - FlipperKit/FlipperKitLayoutHelpers
57 | - FlipperKit/FlipperKitLayoutIOSDescriptors
58 | - FlipperKit/FlipperKitLayoutTextSearchable
59 | - FlipperKit/FlipperKitLayoutTextSearchable (0.201.0)
60 | - FlipperKit/FlipperKitNetworkPlugin (0.201.0):
61 | - FlipperKit/Core
62 | - FlipperKit/FlipperKitReactPlugin (0.201.0):
63 | - FlipperKit/Core
64 | - FlipperKit/FlipperKitUserDefaultsPlugin (0.201.0):
65 | - FlipperKit/Core
66 | - FlipperKit/SKIOSNetworkPlugin (0.201.0):
67 | - FlipperKit/Core
68 | - FlipperKit/FlipperKitNetworkPlugin
69 | - fmt (6.2.1)
70 | - glog (0.3.5)
71 | - hermes-engine (0.73.9):
72 | - hermes-engine/Pre-built (= 0.73.9)
73 | - hermes-engine/Pre-built (0.73.9)
74 | - libevent (2.1.12)
75 | - OpenSSL-Universal (1.1.1100)
76 | - RCT-Folly (2022.05.16.00):
77 | - boost
78 | - DoubleConversion
79 | - fmt (~> 6.2.1)
80 | - glog
81 | - RCT-Folly/Default (= 2022.05.16.00)
82 | - RCT-Folly/Default (2022.05.16.00):
83 | - boost
84 | - DoubleConversion
85 | - fmt (~> 6.2.1)
86 | - glog
87 | - RCT-Folly/Fabric (2022.05.16.00):
88 | - boost
89 | - DoubleConversion
90 | - fmt (~> 6.2.1)
91 | - glog
92 | - RCT-Folly/Futures (2022.05.16.00):
93 | - boost
94 | - DoubleConversion
95 | - fmt (~> 6.2.1)
96 | - glog
97 | - libevent
98 | - RCTRequired (0.73.9)
99 | - RCTTypeSafety (0.73.9):
100 | - FBLazyVector (= 0.73.9)
101 | - RCTRequired (= 0.73.9)
102 | - React-Core (= 0.73.9)
103 | - React (0.73.9):
104 | - React-Core (= 0.73.9)
105 | - React-Core/DevSupport (= 0.73.9)
106 | - React-Core/RCTWebSocket (= 0.73.9)
107 | - React-RCTActionSheet (= 0.73.9)
108 | - React-RCTAnimation (= 0.73.9)
109 | - React-RCTBlob (= 0.73.9)
110 | - React-RCTImage (= 0.73.9)
111 | - React-RCTLinking (= 0.73.9)
112 | - React-RCTNetwork (= 0.73.9)
113 | - React-RCTSettings (= 0.73.9)
114 | - React-RCTText (= 0.73.9)
115 | - React-RCTVibration (= 0.73.9)
116 | - React-callinvoker (0.73.9)
117 | - React-Codegen (0.73.9):
118 | - DoubleConversion
119 | - FBReactNativeSpec
120 | - glog
121 | - hermes-engine
122 | - RCT-Folly
123 | - RCTRequired
124 | - RCTTypeSafety
125 | - React-Core
126 | - React-jsi
127 | - React-jsiexecutor
128 | - React-NativeModulesApple
129 | - React-rncore
130 | - ReactCommon/turbomodule/bridging
131 | - ReactCommon/turbomodule/core
132 | - React-Core (0.73.9):
133 | - glog
134 | - hermes-engine
135 | - RCT-Folly (= 2022.05.16.00)
136 | - React-Core/Default (= 0.73.9)
137 | - React-cxxreact
138 | - React-hermes
139 | - React-jsi
140 | - React-jsiexecutor
141 | - React-perflogger
142 | - React-runtimescheduler
143 | - React-utils
144 | - SocketRocket (= 0.6.1)
145 | - Yoga
146 | - React-Core/CoreModulesHeaders (0.73.9):
147 | - glog
148 | - hermes-engine
149 | - RCT-Folly (= 2022.05.16.00)
150 | - React-Core/Default
151 | - React-cxxreact
152 | - React-hermes
153 | - React-jsi
154 | - React-jsiexecutor
155 | - React-perflogger
156 | - React-runtimescheduler
157 | - React-utils
158 | - SocketRocket (= 0.6.1)
159 | - Yoga
160 | - React-Core/Default (0.73.9):
161 | - glog
162 | - hermes-engine
163 | - RCT-Folly (= 2022.05.16.00)
164 | - React-cxxreact
165 | - React-hermes
166 | - React-jsi
167 | - React-jsiexecutor
168 | - React-perflogger
169 | - React-runtimescheduler
170 | - React-utils
171 | - SocketRocket (= 0.6.1)
172 | - Yoga
173 | - React-Core/DevSupport (0.73.9):
174 | - glog
175 | - hermes-engine
176 | - RCT-Folly (= 2022.05.16.00)
177 | - React-Core/Default (= 0.73.9)
178 | - React-Core/RCTWebSocket (= 0.73.9)
179 | - React-cxxreact
180 | - React-hermes
181 | - React-jsi
182 | - React-jsiexecutor
183 | - React-jsinspector (= 0.73.9)
184 | - React-perflogger
185 | - React-runtimescheduler
186 | - React-utils
187 | - SocketRocket (= 0.6.1)
188 | - Yoga
189 | - React-Core/RCTActionSheetHeaders (0.73.9):
190 | - glog
191 | - hermes-engine
192 | - RCT-Folly (= 2022.05.16.00)
193 | - React-Core/Default
194 | - React-cxxreact
195 | - React-hermes
196 | - React-jsi
197 | - React-jsiexecutor
198 | - React-perflogger
199 | - React-runtimescheduler
200 | - React-utils
201 | - SocketRocket (= 0.6.1)
202 | - Yoga
203 | - React-Core/RCTAnimationHeaders (0.73.9):
204 | - glog
205 | - hermes-engine
206 | - RCT-Folly (= 2022.05.16.00)
207 | - React-Core/Default
208 | - React-cxxreact
209 | - React-hermes
210 | - React-jsi
211 | - React-jsiexecutor
212 | - React-perflogger
213 | - React-runtimescheduler
214 | - React-utils
215 | - SocketRocket (= 0.6.1)
216 | - Yoga
217 | - React-Core/RCTBlobHeaders (0.73.9):
218 | - glog
219 | - hermes-engine
220 | - RCT-Folly (= 2022.05.16.00)
221 | - React-Core/Default
222 | - React-cxxreact
223 | - React-hermes
224 | - React-jsi
225 | - React-jsiexecutor
226 | - React-perflogger
227 | - React-runtimescheduler
228 | - React-utils
229 | - SocketRocket (= 0.6.1)
230 | - Yoga
231 | - React-Core/RCTImageHeaders (0.73.9):
232 | - glog
233 | - hermes-engine
234 | - RCT-Folly (= 2022.05.16.00)
235 | - React-Core/Default
236 | - React-cxxreact
237 | - React-hermes
238 | - React-jsi
239 | - React-jsiexecutor
240 | - React-perflogger
241 | - React-runtimescheduler
242 | - React-utils
243 | - SocketRocket (= 0.6.1)
244 | - Yoga
245 | - React-Core/RCTLinkingHeaders (0.73.9):
246 | - glog
247 | - hermes-engine
248 | - RCT-Folly (= 2022.05.16.00)
249 | - React-Core/Default
250 | - React-cxxreact
251 | - React-hermes
252 | - React-jsi
253 | - React-jsiexecutor
254 | - React-perflogger
255 | - React-runtimescheduler
256 | - React-utils
257 | - SocketRocket (= 0.6.1)
258 | - Yoga
259 | - React-Core/RCTNetworkHeaders (0.73.9):
260 | - glog
261 | - hermes-engine
262 | - RCT-Folly (= 2022.05.16.00)
263 | - React-Core/Default
264 | - React-cxxreact
265 | - React-hermes
266 | - React-jsi
267 | - React-jsiexecutor
268 | - React-perflogger
269 | - React-runtimescheduler
270 | - React-utils
271 | - SocketRocket (= 0.6.1)
272 | - Yoga
273 | - React-Core/RCTSettingsHeaders (0.73.9):
274 | - glog
275 | - hermes-engine
276 | - RCT-Folly (= 2022.05.16.00)
277 | - React-Core/Default
278 | - React-cxxreact
279 | - React-hermes
280 | - React-jsi
281 | - React-jsiexecutor
282 | - React-perflogger
283 | - React-runtimescheduler
284 | - React-utils
285 | - SocketRocket (= 0.6.1)
286 | - Yoga
287 | - React-Core/RCTTextHeaders (0.73.9):
288 | - glog
289 | - hermes-engine
290 | - RCT-Folly (= 2022.05.16.00)
291 | - React-Core/Default
292 | - React-cxxreact
293 | - React-hermes
294 | - React-jsi
295 | - React-jsiexecutor
296 | - React-perflogger
297 | - React-runtimescheduler
298 | - React-utils
299 | - SocketRocket (= 0.6.1)
300 | - Yoga
301 | - React-Core/RCTVibrationHeaders (0.73.9):
302 | - glog
303 | - hermes-engine
304 | - RCT-Folly (= 2022.05.16.00)
305 | - React-Core/Default
306 | - React-cxxreact
307 | - React-hermes
308 | - React-jsi
309 | - React-jsiexecutor
310 | - React-perflogger
311 | - React-runtimescheduler
312 | - React-utils
313 | - SocketRocket (= 0.6.1)
314 | - Yoga
315 | - React-Core/RCTWebSocket (0.73.9):
316 | - glog
317 | - hermes-engine
318 | - RCT-Folly (= 2022.05.16.00)
319 | - React-Core/Default (= 0.73.9)
320 | - React-cxxreact
321 | - React-hermes
322 | - React-jsi
323 | - React-jsiexecutor
324 | - React-perflogger
325 | - React-runtimescheduler
326 | - React-utils
327 | - SocketRocket (= 0.6.1)
328 | - Yoga
329 | - React-CoreModules (0.73.9):
330 | - RCT-Folly (= 2022.05.16.00)
331 | - RCTTypeSafety (= 0.73.9)
332 | - React-Codegen
333 | - React-Core/CoreModulesHeaders (= 0.73.9)
334 | - React-jsi (= 0.73.9)
335 | - React-NativeModulesApple
336 | - React-RCTBlob
337 | - React-RCTImage (= 0.73.9)
338 | - ReactCommon
339 | - SocketRocket (= 0.6.1)
340 | - React-cxxreact (0.73.9):
341 | - boost (= 1.83.0)
342 | - DoubleConversion
343 | - fmt (~> 6.2.1)
344 | - glog
345 | - hermes-engine
346 | - RCT-Folly (= 2022.05.16.00)
347 | - React-callinvoker (= 0.73.9)
348 | - React-debug (= 0.73.9)
349 | - React-jsi (= 0.73.9)
350 | - React-jsinspector (= 0.73.9)
351 | - React-logger (= 0.73.9)
352 | - React-perflogger (= 0.73.9)
353 | - React-runtimeexecutor (= 0.73.9)
354 | - React-debug (0.73.9)
355 | - React-Fabric (0.73.9):
356 | - DoubleConversion
357 | - fmt (~> 6.2.1)
358 | - glog
359 | - hermes-engine
360 | - RCT-Folly/Fabric (= 2022.05.16.00)
361 | - RCTRequired
362 | - RCTTypeSafety
363 | - React-Core
364 | - React-cxxreact
365 | - React-debug
366 | - React-Fabric/animations (= 0.73.9)
367 | - React-Fabric/attributedstring (= 0.73.9)
368 | - React-Fabric/componentregistry (= 0.73.9)
369 | - React-Fabric/componentregistrynative (= 0.73.9)
370 | - React-Fabric/components (= 0.73.9)
371 | - React-Fabric/core (= 0.73.9)
372 | - React-Fabric/imagemanager (= 0.73.9)
373 | - React-Fabric/leakchecker (= 0.73.9)
374 | - React-Fabric/mounting (= 0.73.9)
375 | - React-Fabric/scheduler (= 0.73.9)
376 | - React-Fabric/telemetry (= 0.73.9)
377 | - React-Fabric/templateprocessor (= 0.73.9)
378 | - React-Fabric/textlayoutmanager (= 0.73.9)
379 | - React-Fabric/uimanager (= 0.73.9)
380 | - React-graphics
381 | - React-jsi
382 | - React-jsiexecutor
383 | - React-logger
384 | - React-rendererdebug
385 | - React-runtimescheduler
386 | - React-utils
387 | - ReactCommon/turbomodule/core
388 | - React-Fabric/animations (0.73.9):
389 | - DoubleConversion
390 | - fmt (~> 6.2.1)
391 | - glog
392 | - hermes-engine
393 | - RCT-Folly/Fabric (= 2022.05.16.00)
394 | - RCTRequired
395 | - RCTTypeSafety
396 | - React-Core
397 | - React-cxxreact
398 | - React-debug
399 | - React-graphics
400 | - React-jsi
401 | - React-jsiexecutor
402 | - React-logger
403 | - React-rendererdebug
404 | - React-runtimescheduler
405 | - React-utils
406 | - ReactCommon/turbomodule/core
407 | - React-Fabric/attributedstring (0.73.9):
408 | - DoubleConversion
409 | - fmt (~> 6.2.1)
410 | - glog
411 | - hermes-engine
412 | - RCT-Folly/Fabric (= 2022.05.16.00)
413 | - RCTRequired
414 | - RCTTypeSafety
415 | - React-Core
416 | - React-cxxreact
417 | - React-debug
418 | - React-graphics
419 | - React-jsi
420 | - React-jsiexecutor
421 | - React-logger
422 | - React-rendererdebug
423 | - React-runtimescheduler
424 | - React-utils
425 | - ReactCommon/turbomodule/core
426 | - React-Fabric/componentregistry (0.73.9):
427 | - DoubleConversion
428 | - fmt (~> 6.2.1)
429 | - glog
430 | - hermes-engine
431 | - RCT-Folly/Fabric (= 2022.05.16.00)
432 | - RCTRequired
433 | - RCTTypeSafety
434 | - React-Core
435 | - React-cxxreact
436 | - React-debug
437 | - React-graphics
438 | - React-jsi
439 | - React-jsiexecutor
440 | - React-logger
441 | - React-rendererdebug
442 | - React-runtimescheduler
443 | - React-utils
444 | - ReactCommon/turbomodule/core
445 | - React-Fabric/componentregistrynative (0.73.9):
446 | - DoubleConversion
447 | - fmt (~> 6.2.1)
448 | - glog
449 | - hermes-engine
450 | - RCT-Folly/Fabric (= 2022.05.16.00)
451 | - RCTRequired
452 | - RCTTypeSafety
453 | - React-Core
454 | - React-cxxreact
455 | - React-debug
456 | - React-graphics
457 | - React-jsi
458 | - React-jsiexecutor
459 | - React-logger
460 | - React-rendererdebug
461 | - React-runtimescheduler
462 | - React-utils
463 | - ReactCommon/turbomodule/core
464 | - React-Fabric/components (0.73.9):
465 | - DoubleConversion
466 | - fmt (~> 6.2.1)
467 | - glog
468 | - hermes-engine
469 | - RCT-Folly/Fabric (= 2022.05.16.00)
470 | - RCTRequired
471 | - RCTTypeSafety
472 | - React-Core
473 | - React-cxxreact
474 | - React-debug
475 | - React-Fabric/components/inputaccessory (= 0.73.9)
476 | - React-Fabric/components/legacyviewmanagerinterop (= 0.73.9)
477 | - React-Fabric/components/modal (= 0.73.9)
478 | - React-Fabric/components/rncore (= 0.73.9)
479 | - React-Fabric/components/root (= 0.73.9)
480 | - React-Fabric/components/safeareaview (= 0.73.9)
481 | - React-Fabric/components/scrollview (= 0.73.9)
482 | - React-Fabric/components/text (= 0.73.9)
483 | - React-Fabric/components/textinput (= 0.73.9)
484 | - React-Fabric/components/unimplementedview (= 0.73.9)
485 | - React-Fabric/components/view (= 0.73.9)
486 | - React-graphics
487 | - React-jsi
488 | - React-jsiexecutor
489 | - React-logger
490 | - React-rendererdebug
491 | - React-runtimescheduler
492 | - React-utils
493 | - ReactCommon/turbomodule/core
494 | - React-Fabric/components/inputaccessory (0.73.9):
495 | - DoubleConversion
496 | - fmt (~> 6.2.1)
497 | - glog
498 | - hermes-engine
499 | - RCT-Folly/Fabric (= 2022.05.16.00)
500 | - RCTRequired
501 | - RCTTypeSafety
502 | - React-Core
503 | - React-cxxreact
504 | - React-debug
505 | - React-graphics
506 | - React-jsi
507 | - React-jsiexecutor
508 | - React-logger
509 | - React-rendererdebug
510 | - React-runtimescheduler
511 | - React-utils
512 | - ReactCommon/turbomodule/core
513 | - React-Fabric/components/legacyviewmanagerinterop (0.73.9):
514 | - DoubleConversion
515 | - fmt (~> 6.2.1)
516 | - glog
517 | - hermes-engine
518 | - RCT-Folly/Fabric (= 2022.05.16.00)
519 | - RCTRequired
520 | - RCTTypeSafety
521 | - React-Core
522 | - React-cxxreact
523 | - React-debug
524 | - React-graphics
525 | - React-jsi
526 | - React-jsiexecutor
527 | - React-logger
528 | - React-rendererdebug
529 | - React-runtimescheduler
530 | - React-utils
531 | - ReactCommon/turbomodule/core
532 | - React-Fabric/components/modal (0.73.9):
533 | - DoubleConversion
534 | - fmt (~> 6.2.1)
535 | - glog
536 | - hermes-engine
537 | - RCT-Folly/Fabric (= 2022.05.16.00)
538 | - RCTRequired
539 | - RCTTypeSafety
540 | - React-Core
541 | - React-cxxreact
542 | - React-debug
543 | - React-graphics
544 | - React-jsi
545 | - React-jsiexecutor
546 | - React-logger
547 | - React-rendererdebug
548 | - React-runtimescheduler
549 | - React-utils
550 | - ReactCommon/turbomodule/core
551 | - React-Fabric/components/rncore (0.73.9):
552 | - DoubleConversion
553 | - fmt (~> 6.2.1)
554 | - glog
555 | - hermes-engine
556 | - RCT-Folly/Fabric (= 2022.05.16.00)
557 | - RCTRequired
558 | - RCTTypeSafety
559 | - React-Core
560 | - React-cxxreact
561 | - React-debug
562 | - React-graphics
563 | - React-jsi
564 | - React-jsiexecutor
565 | - React-logger
566 | - React-rendererdebug
567 | - React-runtimescheduler
568 | - React-utils
569 | - ReactCommon/turbomodule/core
570 | - React-Fabric/components/root (0.73.9):
571 | - DoubleConversion
572 | - fmt (~> 6.2.1)
573 | - glog
574 | - hermes-engine
575 | - RCT-Folly/Fabric (= 2022.05.16.00)
576 | - RCTRequired
577 | - RCTTypeSafety
578 | - React-Core
579 | - React-cxxreact
580 | - React-debug
581 | - React-graphics
582 | - React-jsi
583 | - React-jsiexecutor
584 | - React-logger
585 | - React-rendererdebug
586 | - React-runtimescheduler
587 | - React-utils
588 | - ReactCommon/turbomodule/core
589 | - React-Fabric/components/safeareaview (0.73.9):
590 | - DoubleConversion
591 | - fmt (~> 6.2.1)
592 | - glog
593 | - hermes-engine
594 | - RCT-Folly/Fabric (= 2022.05.16.00)
595 | - RCTRequired
596 | - RCTTypeSafety
597 | - React-Core
598 | - React-cxxreact
599 | - React-debug
600 | - React-graphics
601 | - React-jsi
602 | - React-jsiexecutor
603 | - React-logger
604 | - React-rendererdebug
605 | - React-runtimescheduler
606 | - React-utils
607 | - ReactCommon/turbomodule/core
608 | - React-Fabric/components/scrollview (0.73.9):
609 | - DoubleConversion
610 | - fmt (~> 6.2.1)
611 | - glog
612 | - hermes-engine
613 | - RCT-Folly/Fabric (= 2022.05.16.00)
614 | - RCTRequired
615 | - RCTTypeSafety
616 | - React-Core
617 | - React-cxxreact
618 | - React-debug
619 | - React-graphics
620 | - React-jsi
621 | - React-jsiexecutor
622 | - React-logger
623 | - React-rendererdebug
624 | - React-runtimescheduler
625 | - React-utils
626 | - ReactCommon/turbomodule/core
627 | - React-Fabric/components/text (0.73.9):
628 | - DoubleConversion
629 | - fmt (~> 6.2.1)
630 | - glog
631 | - hermes-engine
632 | - RCT-Folly/Fabric (= 2022.05.16.00)
633 | - RCTRequired
634 | - RCTTypeSafety
635 | - React-Core
636 | - React-cxxreact
637 | - React-debug
638 | - React-graphics
639 | - React-jsi
640 | - React-jsiexecutor
641 | - React-logger
642 | - React-rendererdebug
643 | - React-runtimescheduler
644 | - React-utils
645 | - ReactCommon/turbomodule/core
646 | - React-Fabric/components/textinput (0.73.9):
647 | - DoubleConversion
648 | - fmt (~> 6.2.1)
649 | - glog
650 | - hermes-engine
651 | - RCT-Folly/Fabric (= 2022.05.16.00)
652 | - RCTRequired
653 | - RCTTypeSafety
654 | - React-Core
655 | - React-cxxreact
656 | - React-debug
657 | - React-graphics
658 | - React-jsi
659 | - React-jsiexecutor
660 | - React-logger
661 | - React-rendererdebug
662 | - React-runtimescheduler
663 | - React-utils
664 | - ReactCommon/turbomodule/core
665 | - React-Fabric/components/unimplementedview (0.73.9):
666 | - DoubleConversion
667 | - fmt (~> 6.2.1)
668 | - glog
669 | - hermes-engine
670 | - RCT-Folly/Fabric (= 2022.05.16.00)
671 | - RCTRequired
672 | - RCTTypeSafety
673 | - React-Core
674 | - React-cxxreact
675 | - React-debug
676 | - React-graphics
677 | - React-jsi
678 | - React-jsiexecutor
679 | - React-logger
680 | - React-rendererdebug
681 | - React-runtimescheduler
682 | - React-utils
683 | - ReactCommon/turbomodule/core
684 | - React-Fabric/components/view (0.73.9):
685 | - DoubleConversion
686 | - fmt (~> 6.2.1)
687 | - glog
688 | - hermes-engine
689 | - RCT-Folly/Fabric (= 2022.05.16.00)
690 | - RCTRequired
691 | - RCTTypeSafety
692 | - React-Core
693 | - React-cxxreact
694 | - React-debug
695 | - React-graphics
696 | - React-jsi
697 | - React-jsiexecutor
698 | - React-logger
699 | - React-rendererdebug
700 | - React-runtimescheduler
701 | - React-utils
702 | - ReactCommon/turbomodule/core
703 | - Yoga
704 | - React-Fabric/core (0.73.9):
705 | - DoubleConversion
706 | - fmt (~> 6.2.1)
707 | - glog
708 | - hermes-engine
709 | - RCT-Folly/Fabric (= 2022.05.16.00)
710 | - RCTRequired
711 | - RCTTypeSafety
712 | - React-Core
713 | - React-cxxreact
714 | - React-debug
715 | - React-graphics
716 | - React-jsi
717 | - React-jsiexecutor
718 | - React-logger
719 | - React-rendererdebug
720 | - React-runtimescheduler
721 | - React-utils
722 | - ReactCommon/turbomodule/core
723 | - React-Fabric/imagemanager (0.73.9):
724 | - DoubleConversion
725 | - fmt (~> 6.2.1)
726 | - glog
727 | - hermes-engine
728 | - RCT-Folly/Fabric (= 2022.05.16.00)
729 | - RCTRequired
730 | - RCTTypeSafety
731 | - React-Core
732 | - React-cxxreact
733 | - React-debug
734 | - React-graphics
735 | - React-jsi
736 | - React-jsiexecutor
737 | - React-logger
738 | - React-rendererdebug
739 | - React-runtimescheduler
740 | - React-utils
741 | - ReactCommon/turbomodule/core
742 | - React-Fabric/leakchecker (0.73.9):
743 | - DoubleConversion
744 | - fmt (~> 6.2.1)
745 | - glog
746 | - hermes-engine
747 | - RCT-Folly/Fabric (= 2022.05.16.00)
748 | - RCTRequired
749 | - RCTTypeSafety
750 | - React-Core
751 | - React-cxxreact
752 | - React-debug
753 | - React-graphics
754 | - React-jsi
755 | - React-jsiexecutor
756 | - React-logger
757 | - React-rendererdebug
758 | - React-runtimescheduler
759 | - React-utils
760 | - ReactCommon/turbomodule/core
761 | - React-Fabric/mounting (0.73.9):
762 | - DoubleConversion
763 | - fmt (~> 6.2.1)
764 | - glog
765 | - hermes-engine
766 | - RCT-Folly/Fabric (= 2022.05.16.00)
767 | - RCTRequired
768 | - RCTTypeSafety
769 | - React-Core
770 | - React-cxxreact
771 | - React-debug
772 | - React-graphics
773 | - React-jsi
774 | - React-jsiexecutor
775 | - React-logger
776 | - React-rendererdebug
777 | - React-runtimescheduler
778 | - React-utils
779 | - ReactCommon/turbomodule/core
780 | - React-Fabric/scheduler (0.73.9):
781 | - DoubleConversion
782 | - fmt (~> 6.2.1)
783 | - glog
784 | - hermes-engine
785 | - RCT-Folly/Fabric (= 2022.05.16.00)
786 | - RCTRequired
787 | - RCTTypeSafety
788 | - React-Core
789 | - React-cxxreact
790 | - React-debug
791 | - React-graphics
792 | - React-jsi
793 | - React-jsiexecutor
794 | - React-logger
795 | - React-rendererdebug
796 | - React-runtimescheduler
797 | - React-utils
798 | - ReactCommon/turbomodule/core
799 | - React-Fabric/telemetry (0.73.9):
800 | - DoubleConversion
801 | - fmt (~> 6.2.1)
802 | - glog
803 | - hermes-engine
804 | - RCT-Folly/Fabric (= 2022.05.16.00)
805 | - RCTRequired
806 | - RCTTypeSafety
807 | - React-Core
808 | - React-cxxreact
809 | - React-debug
810 | - React-graphics
811 | - React-jsi
812 | - React-jsiexecutor
813 | - React-logger
814 | - React-rendererdebug
815 | - React-runtimescheduler
816 | - React-utils
817 | - ReactCommon/turbomodule/core
818 | - React-Fabric/templateprocessor (0.73.9):
819 | - DoubleConversion
820 | - fmt (~> 6.2.1)
821 | - glog
822 | - hermes-engine
823 | - RCT-Folly/Fabric (= 2022.05.16.00)
824 | - RCTRequired
825 | - RCTTypeSafety
826 | - React-Core
827 | - React-cxxreact
828 | - React-debug
829 | - React-graphics
830 | - React-jsi
831 | - React-jsiexecutor
832 | - React-logger
833 | - React-rendererdebug
834 | - React-runtimescheduler
835 | - React-utils
836 | - ReactCommon/turbomodule/core
837 | - React-Fabric/textlayoutmanager (0.73.9):
838 | - DoubleConversion
839 | - fmt (~> 6.2.1)
840 | - glog
841 | - hermes-engine
842 | - RCT-Folly/Fabric (= 2022.05.16.00)
843 | - RCTRequired
844 | - RCTTypeSafety
845 | - React-Core
846 | - React-cxxreact
847 | - React-debug
848 | - React-Fabric/uimanager
849 | - React-graphics
850 | - React-jsi
851 | - React-jsiexecutor
852 | - React-logger
853 | - React-rendererdebug
854 | - React-runtimescheduler
855 | - React-utils
856 | - ReactCommon/turbomodule/core
857 | - React-Fabric/uimanager (0.73.9):
858 | - DoubleConversion
859 | - fmt (~> 6.2.1)
860 | - glog
861 | - hermes-engine
862 | - RCT-Folly/Fabric (= 2022.05.16.00)
863 | - RCTRequired
864 | - RCTTypeSafety
865 | - React-Core
866 | - React-cxxreact
867 | - React-debug
868 | - React-graphics
869 | - React-jsi
870 | - React-jsiexecutor
871 | - React-logger
872 | - React-rendererdebug
873 | - React-runtimescheduler
874 | - React-utils
875 | - ReactCommon/turbomodule/core
876 | - React-FabricImage (0.73.9):
877 | - DoubleConversion
878 | - fmt (~> 6.2.1)
879 | - glog
880 | - hermes-engine
881 | - RCT-Folly/Fabric (= 2022.05.16.00)
882 | - RCTRequired (= 0.73.9)
883 | - RCTTypeSafety (= 0.73.9)
884 | - React-Fabric
885 | - React-graphics
886 | - React-ImageManager
887 | - React-jsi
888 | - React-jsiexecutor (= 0.73.9)
889 | - React-logger
890 | - React-rendererdebug
891 | - React-utils
892 | - ReactCommon
893 | - Yoga
894 | - React-graphics (0.73.9):
895 | - glog
896 | - RCT-Folly/Fabric (= 2022.05.16.00)
897 | - React-Core/Default (= 0.73.9)
898 | - React-utils
899 | - React-hermes (0.73.9):
900 | - DoubleConversion
901 | - fmt (~> 6.2.1)
902 | - glog
903 | - hermes-engine
904 | - RCT-Folly (= 2022.05.16.00)
905 | - RCT-Folly/Futures (= 2022.05.16.00)
906 | - React-cxxreact (= 0.73.9)
907 | - React-jsi
908 | - React-jsiexecutor (= 0.73.9)
909 | - React-jsinspector (= 0.73.9)
910 | - React-perflogger (= 0.73.9)
911 | - React-ImageManager (0.73.9):
912 | - glog
913 | - RCT-Folly/Fabric
914 | - React-Core/Default
915 | - React-debug
916 | - React-Fabric
917 | - React-graphics
918 | - React-rendererdebug
919 | - React-utils
920 | - React-jserrorhandler (0.73.9):
921 | - RCT-Folly/Fabric (= 2022.05.16.00)
922 | - React-debug
923 | - React-jsi
924 | - React-Mapbuffer
925 | - React-jsi (0.73.9):
926 | - boost (= 1.83.0)
927 | - DoubleConversion
928 | - fmt (~> 6.2.1)
929 | - glog
930 | - hermes-engine
931 | - RCT-Folly (= 2022.05.16.00)
932 | - React-jsiexecutor (0.73.9):
933 | - DoubleConversion
934 | - fmt (~> 6.2.1)
935 | - glog
936 | - hermes-engine
937 | - RCT-Folly (= 2022.05.16.00)
938 | - React-cxxreact (= 0.73.9)
939 | - React-jsi (= 0.73.9)
940 | - React-perflogger (= 0.73.9)
941 | - React-jsinspector (0.73.9)
942 | - React-logger (0.73.9):
943 | - glog
944 | - React-Mapbuffer (0.73.9):
945 | - glog
946 | - React-debug
947 | - React-nativeconfig (0.73.9)
948 | - React-NativeModulesApple (0.73.9):
949 | - glog
950 | - hermes-engine
951 | - React-callinvoker
952 | - React-Core
953 | - React-cxxreact
954 | - React-jsi
955 | - React-runtimeexecutor
956 | - ReactCommon/turbomodule/bridging
957 | - ReactCommon/turbomodule/core
958 | - React-perflogger (0.73.9)
959 | - React-RCTActionSheet (0.73.9):
960 | - React-Core/RCTActionSheetHeaders (= 0.73.9)
961 | - React-RCTAnimation (0.73.9):
962 | - RCT-Folly (= 2022.05.16.00)
963 | - RCTTypeSafety
964 | - React-Codegen
965 | - React-Core/RCTAnimationHeaders
966 | - React-jsi
967 | - React-NativeModulesApple
968 | - ReactCommon
969 | - React-RCTAppDelegate (0.73.9):
970 | - RCT-Folly
971 | - RCTRequired
972 | - RCTTypeSafety
973 | - React-Core
974 | - React-CoreModules
975 | - React-hermes
976 | - React-nativeconfig
977 | - React-NativeModulesApple
978 | - React-RCTFabric
979 | - React-RCTImage
980 | - React-RCTNetwork
981 | - React-runtimescheduler
982 | - ReactCommon
983 | - React-RCTBlob (0.73.9):
984 | - hermes-engine
985 | - RCT-Folly (= 2022.05.16.00)
986 | - React-Codegen
987 | - React-Core/RCTBlobHeaders
988 | - React-Core/RCTWebSocket
989 | - React-jsi
990 | - React-NativeModulesApple
991 | - React-RCTNetwork
992 | - ReactCommon
993 | - React-RCTFabric (0.73.9):
994 | - glog
995 | - hermes-engine
996 | - RCT-Folly/Fabric (= 2022.05.16.00)
997 | - React-Core
998 | - React-debug
999 | - React-Fabric
1000 | - React-FabricImage
1001 | - React-graphics
1002 | - React-ImageManager
1003 | - React-jsi
1004 | - React-nativeconfig
1005 | - React-RCTImage
1006 | - React-RCTText
1007 | - React-rendererdebug
1008 | - React-runtimescheduler
1009 | - React-utils
1010 | - Yoga
1011 | - React-RCTImage (0.73.9):
1012 | - RCT-Folly (= 2022.05.16.00)
1013 | - RCTTypeSafety
1014 | - React-Codegen
1015 | - React-Core/RCTImageHeaders
1016 | - React-jsi
1017 | - React-NativeModulesApple
1018 | - React-RCTNetwork
1019 | - ReactCommon
1020 | - React-RCTLinking (0.73.9):
1021 | - React-Codegen
1022 | - React-Core/RCTLinkingHeaders (= 0.73.9)
1023 | - React-jsi (= 0.73.9)
1024 | - React-NativeModulesApple
1025 | - ReactCommon
1026 | - ReactCommon/turbomodule/core (= 0.73.9)
1027 | - React-RCTNetwork (0.73.9):
1028 | - RCT-Folly (= 2022.05.16.00)
1029 | - RCTTypeSafety
1030 | - React-Codegen
1031 | - React-Core/RCTNetworkHeaders
1032 | - React-jsi
1033 | - React-NativeModulesApple
1034 | - ReactCommon
1035 | - React-RCTSettings (0.73.9):
1036 | - RCT-Folly (= 2022.05.16.00)
1037 | - RCTTypeSafety
1038 | - React-Codegen
1039 | - React-Core/RCTSettingsHeaders
1040 | - React-jsi
1041 | - React-NativeModulesApple
1042 | - ReactCommon
1043 | - React-RCTText (0.73.9):
1044 | - React-Core/RCTTextHeaders (= 0.73.9)
1045 | - Yoga
1046 | - React-RCTVibration (0.73.9):
1047 | - RCT-Folly (= 2022.05.16.00)
1048 | - React-Codegen
1049 | - React-Core/RCTVibrationHeaders
1050 | - React-jsi
1051 | - React-NativeModulesApple
1052 | - ReactCommon
1053 | - React-rendererdebug (0.73.9):
1054 | - DoubleConversion
1055 | - fmt (~> 6.2.1)
1056 | - RCT-Folly (= 2022.05.16.00)
1057 | - React-debug
1058 | - React-rncore (0.73.9)
1059 | - React-runtimeexecutor (0.73.9):
1060 | - React-jsi (= 0.73.9)
1061 | - React-runtimescheduler (0.73.9):
1062 | - glog
1063 | - hermes-engine
1064 | - RCT-Folly (= 2022.05.16.00)
1065 | - React-callinvoker
1066 | - React-cxxreact
1067 | - React-debug
1068 | - React-jsi
1069 | - React-rendererdebug
1070 | - React-runtimeexecutor
1071 | - React-utils
1072 | - React-utils (0.73.9):
1073 | - glog
1074 | - RCT-Folly (= 2022.05.16.00)
1075 | - React-debug
1076 | - ReactCommon (0.73.9):
1077 | - React-logger (= 0.73.9)
1078 | - ReactCommon/turbomodule (= 0.73.9)
1079 | - ReactCommon/turbomodule (0.73.9):
1080 | - DoubleConversion
1081 | - fmt (~> 6.2.1)
1082 | - glog
1083 | - hermes-engine
1084 | - RCT-Folly (= 2022.05.16.00)
1085 | - React-callinvoker (= 0.73.9)
1086 | - React-cxxreact (= 0.73.9)
1087 | - React-jsi (= 0.73.9)
1088 | - React-logger (= 0.73.9)
1089 | - React-perflogger (= 0.73.9)
1090 | - ReactCommon/turbomodule/bridging (= 0.73.9)
1091 | - ReactCommon/turbomodule/core (= 0.73.9)
1092 | - ReactCommon/turbomodule/bridging (0.73.9):
1093 | - DoubleConversion
1094 | - fmt (~> 6.2.1)
1095 | - glog
1096 | - hermes-engine
1097 | - RCT-Folly (= 2022.05.16.00)
1098 | - React-callinvoker (= 0.73.9)
1099 | - React-cxxreact (= 0.73.9)
1100 | - React-jsi (= 0.73.9)
1101 | - React-logger (= 0.73.9)
1102 | - React-perflogger (= 0.73.9)
1103 | - ReactCommon/turbomodule/core (0.73.9):
1104 | - DoubleConversion
1105 | - fmt (~> 6.2.1)
1106 | - glog
1107 | - hermes-engine
1108 | - RCT-Folly (= 2022.05.16.00)
1109 | - React-callinvoker (= 0.73.9)
1110 | - React-cxxreact (= 0.73.9)
1111 | - React-jsi (= 0.73.9)
1112 | - React-logger (= 0.73.9)
1113 | - React-perflogger (= 0.73.9)
1114 | - RNInAppPurchase (2.0.10):
1115 | - glog
1116 | - RCT-Folly (= 2022.05.16.00)
1117 | - React
1118 | - React-Core
1119 | - SocketRocket (0.6.1)
1120 | - Yoga (1.14.0)
1121 |
1122 | DEPENDENCIES:
1123 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
1124 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
1125 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
1126 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
1127 | - Flipper (= 0.201.0)
1128 | - Flipper-Boost-iOSX (= 1.76.0.1.11)
1129 | - Flipper-DoubleConversion (= 3.2.0.1)
1130 | - Flipper-Fmt (= 7.1.7)
1131 | - Flipper-Folly (= 2.6.10)
1132 | - Flipper-Glog (= 0.5.0.5)
1133 | - Flipper-PeerTalk (= 0.0.4)
1134 | - FlipperKit (= 0.201.0)
1135 | - FlipperKit/Core (= 0.201.0)
1136 | - FlipperKit/CppBridge (= 0.201.0)
1137 | - FlipperKit/FBCxxFollyDynamicConvert (= 0.201.0)
1138 | - FlipperKit/FBDefines (= 0.201.0)
1139 | - FlipperKit/FKPortForwarding (= 0.201.0)
1140 | - FlipperKit/FlipperKitHighlightOverlay (= 0.201.0)
1141 | - FlipperKit/FlipperKitLayoutPlugin (= 0.201.0)
1142 | - FlipperKit/FlipperKitLayoutTextSearchable (= 0.201.0)
1143 | - FlipperKit/FlipperKitNetworkPlugin (= 0.201.0)
1144 | - FlipperKit/FlipperKitReactPlugin (= 0.201.0)
1145 | - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.201.0)
1146 | - FlipperKit/SKIOSNetworkPlugin (= 0.201.0)
1147 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
1148 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
1149 | - libevent (~> 2.1.12)
1150 | - OpenSSL-Universal (= 1.1.1100)
1151 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
1152 | - RCT-Folly/Fabric (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
1153 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
1154 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
1155 | - React (from `../node_modules/react-native/`)
1156 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
1157 | - React-Codegen (from `build/generated/ios`)
1158 | - React-Core (from `../node_modules/react-native/`)
1159 | - React-Core/DevSupport (from `../node_modules/react-native/`)
1160 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`)
1161 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
1162 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
1163 | - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`)
1164 | - React-Fabric (from `../node_modules/react-native/ReactCommon`)
1165 | - React-FabricImage (from `../node_modules/react-native/ReactCommon`)
1166 | - React-graphics (from `../node_modules/react-native/ReactCommon/react/renderer/graphics`)
1167 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
1168 | - React-ImageManager (from `../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios`)
1169 | - React-jserrorhandler (from `../node_modules/react-native/ReactCommon/jserrorhandler`)
1170 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
1171 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
1172 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector-modern`)
1173 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`)
1174 | - React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
1175 | - React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
1176 | - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
1177 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
1178 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
1179 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
1180 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`)
1181 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
1182 | - React-RCTFabric (from `../node_modules/react-native/React`)
1183 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
1184 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
1185 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
1186 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
1187 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
1188 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
1189 | - React-rendererdebug (from `../node_modules/react-native/ReactCommon/react/renderer/debug`)
1190 | - React-rncore (from `../node_modules/react-native/ReactCommon`)
1191 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
1192 | - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
1193 | - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
1194 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
1195 | - "RNInAppPurchase (from `../node_modules/@class101/react-native-in-app-purchase`)"
1196 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
1197 |
1198 | SPEC REPOS:
1199 | trunk:
1200 | - CocoaAsyncSocket
1201 | - Flipper
1202 | - Flipper-Boost-iOSX
1203 | - Flipper-DoubleConversion
1204 | - Flipper-Fmt
1205 | - Flipper-Folly
1206 | - Flipper-Glog
1207 | - Flipper-PeerTalk
1208 | - FlipperKit
1209 | - fmt
1210 | - libevent
1211 | - OpenSSL-Universal
1212 | - SocketRocket
1213 |
1214 | EXTERNAL SOURCES:
1215 | boost:
1216 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
1217 | DoubleConversion:
1218 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
1219 | FBLazyVector:
1220 | :path: "../node_modules/react-native/Libraries/FBLazyVector"
1221 | FBReactNativeSpec:
1222 | :path: "../node_modules/react-native/React/FBReactNativeSpec"
1223 | glog:
1224 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
1225 | hermes-engine:
1226 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
1227 | :tag: hermes-2024-04-29-RNv0.73.8-644c8be78af1eae7c138fa4093fb87f0f4f8db85
1228 | RCT-Folly:
1229 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
1230 | RCTRequired:
1231 | :path: "../node_modules/react-native/Libraries/RCTRequired"
1232 | RCTTypeSafety:
1233 | :path: "../node_modules/react-native/Libraries/TypeSafety"
1234 | React:
1235 | :path: "../node_modules/react-native/"
1236 | React-callinvoker:
1237 | :path: "../node_modules/react-native/ReactCommon/callinvoker"
1238 | React-Codegen:
1239 | :path: build/generated/ios
1240 | React-Core:
1241 | :path: "../node_modules/react-native/"
1242 | React-CoreModules:
1243 | :path: "../node_modules/react-native/React/CoreModules"
1244 | React-cxxreact:
1245 | :path: "../node_modules/react-native/ReactCommon/cxxreact"
1246 | React-debug:
1247 | :path: "../node_modules/react-native/ReactCommon/react/debug"
1248 | React-Fabric:
1249 | :path: "../node_modules/react-native/ReactCommon"
1250 | React-FabricImage:
1251 | :path: "../node_modules/react-native/ReactCommon"
1252 | React-graphics:
1253 | :path: "../node_modules/react-native/ReactCommon/react/renderer/graphics"
1254 | React-hermes:
1255 | :path: "../node_modules/react-native/ReactCommon/hermes"
1256 | React-ImageManager:
1257 | :path: "../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios"
1258 | React-jserrorhandler:
1259 | :path: "../node_modules/react-native/ReactCommon/jserrorhandler"
1260 | React-jsi:
1261 | :path: "../node_modules/react-native/ReactCommon/jsi"
1262 | React-jsiexecutor:
1263 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
1264 | React-jsinspector:
1265 | :path: "../node_modules/react-native/ReactCommon/jsinspector-modern"
1266 | React-logger:
1267 | :path: "../node_modules/react-native/ReactCommon/logger"
1268 | React-Mapbuffer:
1269 | :path: "../node_modules/react-native/ReactCommon"
1270 | React-nativeconfig:
1271 | :path: "../node_modules/react-native/ReactCommon"
1272 | React-NativeModulesApple:
1273 | :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios"
1274 | React-perflogger:
1275 | :path: "../node_modules/react-native/ReactCommon/reactperflogger"
1276 | React-RCTActionSheet:
1277 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS"
1278 | React-RCTAnimation:
1279 | :path: "../node_modules/react-native/Libraries/NativeAnimation"
1280 | React-RCTAppDelegate:
1281 | :path: "../node_modules/react-native/Libraries/AppDelegate"
1282 | React-RCTBlob:
1283 | :path: "../node_modules/react-native/Libraries/Blob"
1284 | React-RCTFabric:
1285 | :path: "../node_modules/react-native/React"
1286 | React-RCTImage:
1287 | :path: "../node_modules/react-native/Libraries/Image"
1288 | React-RCTLinking:
1289 | :path: "../node_modules/react-native/Libraries/LinkingIOS"
1290 | React-RCTNetwork:
1291 | :path: "../node_modules/react-native/Libraries/Network"
1292 | React-RCTSettings:
1293 | :path: "../node_modules/react-native/Libraries/Settings"
1294 | React-RCTText:
1295 | :path: "../node_modules/react-native/Libraries/Text"
1296 | React-RCTVibration:
1297 | :path: "../node_modules/react-native/Libraries/Vibration"
1298 | React-rendererdebug:
1299 | :path: "../node_modules/react-native/ReactCommon/react/renderer/debug"
1300 | React-rncore:
1301 | :path: "../node_modules/react-native/ReactCommon"
1302 | React-runtimeexecutor:
1303 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
1304 | React-runtimescheduler:
1305 | :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler"
1306 | React-utils:
1307 | :path: "../node_modules/react-native/ReactCommon/react/utils"
1308 | ReactCommon:
1309 | :path: "../node_modules/react-native/ReactCommon"
1310 | RNInAppPurchase:
1311 | :path: "../node_modules/@class101/react-native-in-app-purchase"
1312 | Yoga:
1313 | :path: "../node_modules/react-native/ReactCommon/yoga"
1314 |
1315 | SPEC CHECKSUMS:
1316 | boost: d3f49c53809116a5d38da093a8aa78bf551aed09
1317 | CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
1318 | DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
1319 | FBLazyVector: 98c189b92292d4bfeac13ffa8df3ce3d84e2fc5b
1320 | FBReactNativeSpec: 4fe1d8c2fadc7949344b197d933f76b40401aac5
1321 | Flipper: c7a0093234c4bdd456e363f2f19b2e4b27652d44
1322 | Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
1323 | Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
1324 | Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
1325 | Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3
1326 | Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446
1327 | Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
1328 | FlipperKit: 37525a5d056ef9b93d1578e04bc3ea1de940094f
1329 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
1330 | glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
1331 | hermes-engine: ed62e0dcd013bf4a3b487f164feec1c4e705b5b5
1332 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
1333 | OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
1334 | RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
1335 | RCTRequired: d362a61864a64315aee00faea8dee6cf5b3f4aad
1336 | RCTTypeSafety: 09baf60faeab02492dc8bf04ce5af1dda645b86d
1337 | React: b87c7c7c12f8232bd7cfdc4a00bf687144c17e30
1338 | React-callinvoker: 67de0bc05ecb7e690345a53a1661cea9b24670b0
1339 | React-Codegen: d4acea6cf2a7889c042653eaff9233b1d6c4d3c3
1340 | React-Core: 4c87a1873c6d11c6d3843582fbc266ba9ea304ce
1341 | React-CoreModules: 29ad1cbe757a70575913457bb7c646b7f4d4edf0
1342 | React-cxxreact: 08ffaf2def6fe1ec8ef7f16e208587c96a87978e
1343 | React-debug: 937e24adc0479b9bbed3f1b7e0db68688d93c31c
1344 | React-Fabric: 1e2eb26de25f2629350beaab7abc3623becce2b7
1345 | React-FabricImage: 5791bf14ff0550f26b81be575e9a10f1f3c69688
1346 | React-graphics: 3ba4dba54c4d1426118089f1943708ef0bba8a84
1347 | React-hermes: fdaab14cc289d8d9cd45ffd9a3f8aa11157d4c7e
1348 | React-ImageManager: 13b4aebbffd9addbcd79d1687355db2f6d8a37e2
1349 | React-jserrorhandler: f30af3ec30fdc04a4b080c5b1f3defb801c0c861
1350 | React-jsi: 2253621cb2fb5d43a78fec4db8989cf9711039df
1351 | React-jsiexecutor: 5e4620a87fbc4ab174d75220f06ba8b53ae8317b
1352 | React-jsinspector: aee04d04ef553d5e30e52a4de2af958cb060069f
1353 | React-logger: 87a4232dd55485435edfa6803ff0de0b5c9eea1a
1354 | React-Mapbuffer: 6c229dc8f1640457d1f665f0b7d79ab8f604dc8b
1355 | React-nativeconfig: c1729ab95240ec80d47a2bb8354d8f31138e35a7
1356 | React-NativeModulesApple: 115c934a87f3b45fecb0fada08fa70bab3dff65c
1357 | React-perflogger: c93b6a895eca3f9196656bb20ce0e15ad597a4e9
1358 | React-RCTActionSheet: 258842f426709dccbc2af31ca42b0a1807d76ad7
1359 | React-RCTAnimation: 78c40269e35864f541b7486d17bd82a353c99fbc
1360 | React-RCTAppDelegate: d98ec2cdfb161d7a8496990e9649f94018025922
1361 | React-RCTBlob: 593a5dbc58c45e3cccc37ad4498b10766ace26e6
1362 | React-RCTFabric: e6060e78040264f8a542bb8631ae1bbfd5a882ed
1363 | React-RCTImage: a0cdbb81db012ebc42c7dbaabdcb15f488c7c391
1364 | React-RCTLinking: 82b6b0a5b2d5c8d3a28997e70bda46bac4be4c6e
1365 | React-RCTNetwork: 45e30079bcb987724028c9a93c0110b6d82e4a1f
1366 | React-RCTSettings: e67cbe694fe45b080b96b1394d4e45dff1b3ae04
1367 | React-RCTText: 14a54686a1fa0b51b76660c7700980fdec6c3093
1368 | React-RCTVibration: 00561f3d12dca44ed55af9060752bf8cf3fb0bfc
1369 | React-rendererdebug: 975f3e6e430ba1a9b92dc44bc99757cb1c6cae60
1370 | React-rncore: e7dc772ade687746b8a8a38985b4512b8d232637
1371 | React-runtimeexecutor: bf98e8973ed4c45139fbbaf2c34af44053acc9a9
1372 | React-runtimescheduler: efb26ad81d94a9b047504bd716b48869bd311649
1373 | React-utils: dab84549e65d6d711937b9c34d9f6d8fb8bd711c
1374 | ReactCommon: 3dc453f427d2f3d7f2c71499d191b456f83c59bd
1375 | RNInAppPurchase: 4388b2b30b6dae90d63592c079ff98998e849293
1376 | SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
1377 | Yoga: 6aaa3c45f0fda0c6929f855121622669dabe1aaf
1378 |
1379 | PODFILE CHECKSUM: 633ce1a49803ed7ea8d9eae24b715dcf52a433d3
1380 |
1381 | COCOAPODS: 1.15.2
1382 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 00E356F31AD99517003FC87E /* RNInAppPurchaseSampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RNInAppPurchaseSampleTests.m */; };
11 | 0C80B921A6F3F58F76C31292 /* libPods-RNInAppPurchaseSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-RNInAppPurchaseSample.a */; };
12 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
14 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
15 | 6132EF182BDFF13200BBE14D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */; };
16 | 7699B88040F8A987B510C191 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a */; };
17 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXContainerItemProxy section */
21 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
22 | isa = PBXContainerItemProxy;
23 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
24 | proxyType = 1;
25 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
26 | remoteInfo = RNInAppPurchaseSample;
27 | };
28 | /* End PBXContainerItemProxy section */
29 |
30 | /* Begin PBXFileReference section */
31 | 00E356EE1AD99517003FC87E /* RNInAppPurchaseSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNInAppPurchaseSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
32 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
33 | 00E356F21AD99517003FC87E /* RNInAppPurchaseSampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNInAppPurchaseSampleTests.m; sourceTree = ""; };
34 | 13B07F961A680F5B00A75B9A /* RNInAppPurchaseSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RNInAppPurchaseSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
35 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNInAppPurchaseSample/AppDelegate.h; sourceTree = ""; };
36 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNInAppPurchaseSample/AppDelegate.mm; sourceTree = ""; };
37 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNInAppPurchaseSample/Images.xcassets; sourceTree = ""; };
38 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNInAppPurchaseSample/Info.plist; sourceTree = ""; };
39 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNInAppPurchaseSample/main.m; sourceTree = ""; };
40 | 19F6CBCC0A4E27FBF8BF4A61 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
41 | 3B4392A12AC88292D35C810B /* Pods-RNInAppPurchaseSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNInAppPurchaseSample.debug.xcconfig"; path = "Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample.debug.xcconfig"; sourceTree = ""; };
42 | 5709B34CF0A7D63546082F79 /* Pods-RNInAppPurchaseSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNInAppPurchaseSample.release.xcconfig"; path = "Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample.release.xcconfig"; sourceTree = ""; };
43 | 5B7EB9410499542E8C5724F5 /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig"; path = "Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig"; sourceTree = ""; };
44 | 5DCACB8F33CDC322A6C60F78 /* libPods-RNInAppPurchaseSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNInAppPurchaseSample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
45 | 6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = RNInAppPurchaseSample/PrivacyInfo.xcprivacy; sourceTree = ""; };
46 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNInAppPurchaseSample/LaunchScreen.storyboard; sourceTree = ""; };
47 | 89C6BE57DB24E9ADA2F236DE /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig"; path = "Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig"; sourceTree = ""; };
48 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
49 | /* End PBXFileReference section */
50 |
51 | /* Begin PBXFrameworksBuildPhase section */
52 | 00E356EB1AD99517003FC87E /* Frameworks */ = {
53 | isa = PBXFrameworksBuildPhase;
54 | buildActionMask = 2147483647;
55 | files = (
56 | 7699B88040F8A987B510C191 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a in Frameworks */,
57 | );
58 | runOnlyForDeploymentPostprocessing = 0;
59 | };
60 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
61 | isa = PBXFrameworksBuildPhase;
62 | buildActionMask = 2147483647;
63 | files = (
64 | 0C80B921A6F3F58F76C31292 /* libPods-RNInAppPurchaseSample.a in Frameworks */,
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | /* End PBXFrameworksBuildPhase section */
69 |
70 | /* Begin PBXGroup section */
71 | 00E356EF1AD99517003FC87E /* RNInAppPurchaseSampleTests */ = {
72 | isa = PBXGroup;
73 | children = (
74 | 00E356F21AD99517003FC87E /* RNInAppPurchaseSampleTests.m */,
75 | 00E356F01AD99517003FC87E /* Supporting Files */,
76 | );
77 | path = RNInAppPurchaseSampleTests;
78 | sourceTree = "";
79 | };
80 | 00E356F01AD99517003FC87E /* Supporting Files */ = {
81 | isa = PBXGroup;
82 | children = (
83 | 00E356F11AD99517003FC87E /* Info.plist */,
84 | );
85 | name = "Supporting Files";
86 | sourceTree = "";
87 | };
88 | 13B07FAE1A68108700A75B9A /* RNInAppPurchaseSample */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */,
92 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */,
93 | 13B07FB51A68108700A75B9A /* Images.xcassets */,
94 | 13B07FB61A68108700A75B9A /* Info.plist */,
95 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
96 | 13B07FB71A68108700A75B9A /* main.m */,
97 | );
98 | name = RNInAppPurchaseSample;
99 | sourceTree = "";
100 | };
101 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
102 | isa = PBXGroup;
103 | children = (
104 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
105 | 5DCACB8F33CDC322A6C60F78 /* libPods-RNInAppPurchaseSample.a */,
106 | 19F6CBCC0A4E27FBF8BF4A61 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a */,
107 | );
108 | name = Frameworks;
109 | sourceTree = "";
110 | };
111 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
112 | isa = PBXGroup;
113 | children = (
114 | );
115 | name = Libraries;
116 | sourceTree = "";
117 | };
118 | 83CBB9F61A601CBA00E9B192 = {
119 | isa = PBXGroup;
120 | children = (
121 | 6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */,
122 | 13B07FAE1A68108700A75B9A /* RNInAppPurchaseSample */,
123 | 832341AE1AAA6A7D00B99B32 /* Libraries */,
124 | 00E356EF1AD99517003FC87E /* RNInAppPurchaseSampleTests */,
125 | 83CBBA001A601CBA00E9B192 /* Products */,
126 | 2D16E6871FA4F8E400B85C8A /* Frameworks */,
127 | BBD78D7AC51CEA395F1C20DB /* Pods */,
128 | );
129 | indentWidth = 2;
130 | sourceTree = "";
131 | tabWidth = 2;
132 | usesTabs = 0;
133 | };
134 | 83CBBA001A601CBA00E9B192 /* Products */ = {
135 | isa = PBXGroup;
136 | children = (
137 | 13B07F961A680F5B00A75B9A /* RNInAppPurchaseSample.app */,
138 | 00E356EE1AD99517003FC87E /* RNInAppPurchaseSampleTests.xctest */,
139 | );
140 | name = Products;
141 | sourceTree = "";
142 | };
143 | BBD78D7AC51CEA395F1C20DB /* Pods */ = {
144 | isa = PBXGroup;
145 | children = (
146 | 3B4392A12AC88292D35C810B /* Pods-RNInAppPurchaseSample.debug.xcconfig */,
147 | 5709B34CF0A7D63546082F79 /* Pods-RNInAppPurchaseSample.release.xcconfig */,
148 | 5B7EB9410499542E8C5724F5 /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig */,
149 | 89C6BE57DB24E9ADA2F236DE /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig */,
150 | );
151 | path = Pods;
152 | sourceTree = "";
153 | };
154 | /* End PBXGroup section */
155 |
156 | /* Begin PBXNativeTarget section */
157 | 00E356ED1AD99517003FC87E /* RNInAppPurchaseSampleTests */ = {
158 | isa = PBXNativeTarget;
159 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RNInAppPurchaseSampleTests" */;
160 | buildPhases = (
161 | A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */,
162 | 00E356EA1AD99517003FC87E /* Sources */,
163 | 00E356EB1AD99517003FC87E /* Frameworks */,
164 | 00E356EC1AD99517003FC87E /* Resources */,
165 | C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */,
166 | F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */,
167 | );
168 | buildRules = (
169 | );
170 | dependencies = (
171 | 00E356F51AD99517003FC87E /* PBXTargetDependency */,
172 | );
173 | name = RNInAppPurchaseSampleTests;
174 | productName = RNInAppPurchaseSampleTests;
175 | productReference = 00E356EE1AD99517003FC87E /* RNInAppPurchaseSampleTests.xctest */;
176 | productType = "com.apple.product-type.bundle.unit-test";
177 | };
178 | 13B07F861A680F5B00A75B9A /* RNInAppPurchaseSample */ = {
179 | isa = PBXNativeTarget;
180 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNInAppPurchaseSample" */;
181 | buildPhases = (
182 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
183 | 13B07F871A680F5B00A75B9A /* Sources */,
184 | 13B07F8C1A680F5B00A75B9A /* Frameworks */,
185 | 13B07F8E1A680F5B00A75B9A /* Resources */,
186 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
187 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
188 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
189 | );
190 | buildRules = (
191 | );
192 | dependencies = (
193 | );
194 | name = RNInAppPurchaseSample;
195 | productName = RNInAppPurchaseSample;
196 | productReference = 13B07F961A680F5B00A75B9A /* RNInAppPurchaseSample.app */;
197 | productType = "com.apple.product-type.application";
198 | };
199 | /* End PBXNativeTarget section */
200 |
201 | /* Begin PBXProject section */
202 | 83CBB9F71A601CBA00E9B192 /* Project object */ = {
203 | isa = PBXProject;
204 | attributes = {
205 | LastUpgradeCheck = 1210;
206 | TargetAttributes = {
207 | 00E356ED1AD99517003FC87E = {
208 | CreatedOnToolsVersion = 6.2;
209 | TestTargetID = 13B07F861A680F5B00A75B9A;
210 | };
211 | 13B07F861A680F5B00A75B9A = {
212 | LastSwiftMigration = 1120;
213 | };
214 | };
215 | };
216 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RNInAppPurchaseSample" */;
217 | compatibilityVersion = "Xcode 12.0";
218 | developmentRegion = en;
219 | hasScannedForEncodings = 0;
220 | knownRegions = (
221 | en,
222 | Base,
223 | );
224 | mainGroup = 83CBB9F61A601CBA00E9B192;
225 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
226 | projectDirPath = "";
227 | projectRoot = "";
228 | targets = (
229 | 13B07F861A680F5B00A75B9A /* RNInAppPurchaseSample */,
230 | 00E356ED1AD99517003FC87E /* RNInAppPurchaseSampleTests */,
231 | );
232 | };
233 | /* End PBXProject section */
234 |
235 | /* Begin PBXResourcesBuildPhase section */
236 | 00E356EC1AD99517003FC87E /* Resources */ = {
237 | isa = PBXResourcesBuildPhase;
238 | buildActionMask = 2147483647;
239 | files = (
240 | );
241 | runOnlyForDeploymentPostprocessing = 0;
242 | };
243 | 13B07F8E1A680F5B00A75B9A /* Resources */ = {
244 | isa = PBXResourcesBuildPhase;
245 | buildActionMask = 2147483647;
246 | files = (
247 | 6132EF182BDFF13200BBE14D /* PrivacyInfo.xcprivacy in Resources */,
248 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
249 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
250 | );
251 | runOnlyForDeploymentPostprocessing = 0;
252 | };
253 | /* End PBXResourcesBuildPhase section */
254 |
255 | /* Begin PBXShellScriptBuildPhase section */
256 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
257 | isa = PBXShellScriptBuildPhase;
258 | buildActionMask = 2147483647;
259 | files = (
260 | );
261 | inputPaths = (
262 | "$(SRCROOT)/.xcode.env.local",
263 | "$(SRCROOT)/.xcode.env",
264 | );
265 | name = "Bundle React Native code and images";
266 | outputPaths = (
267 | );
268 | runOnlyForDeploymentPostprocessing = 0;
269 | shellPath = /bin/sh;
270 | shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
271 | };
272 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
273 | isa = PBXShellScriptBuildPhase;
274 | buildActionMask = 2147483647;
275 | files = (
276 | );
277 | inputFileListPaths = (
278 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
279 | );
280 | name = "[CP] Embed Pods Frameworks";
281 | outputFileListPaths = (
282 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
283 | );
284 | runOnlyForDeploymentPostprocessing = 0;
285 | shellPath = /bin/sh;
286 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-frameworks.sh\"\n";
287 | showEnvVarsInLog = 0;
288 | };
289 | A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = {
290 | isa = PBXShellScriptBuildPhase;
291 | buildActionMask = 2147483647;
292 | files = (
293 | );
294 | inputFileListPaths = (
295 | );
296 | inputPaths = (
297 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
298 | "${PODS_ROOT}/Manifest.lock",
299 | );
300 | name = "[CP] Check Pods Manifest.lock";
301 | outputFileListPaths = (
302 | );
303 | outputPaths = (
304 | "$(DERIVED_FILE_DIR)/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-checkManifestLockResult.txt",
305 | );
306 | runOnlyForDeploymentPostprocessing = 0;
307 | shellPath = /bin/sh;
308 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
309 | showEnvVarsInLog = 0;
310 | };
311 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
312 | isa = PBXShellScriptBuildPhase;
313 | buildActionMask = 2147483647;
314 | files = (
315 | );
316 | inputFileListPaths = (
317 | );
318 | inputPaths = (
319 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
320 | "${PODS_ROOT}/Manifest.lock",
321 | );
322 | name = "[CP] Check Pods Manifest.lock";
323 | outputFileListPaths = (
324 | );
325 | outputPaths = (
326 | "$(DERIVED_FILE_DIR)/Pods-RNInAppPurchaseSample-checkManifestLockResult.txt",
327 | );
328 | runOnlyForDeploymentPostprocessing = 0;
329 | shellPath = /bin/sh;
330 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
331 | showEnvVarsInLog = 0;
332 | };
333 | C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = {
334 | isa = PBXShellScriptBuildPhase;
335 | buildActionMask = 2147483647;
336 | files = (
337 | );
338 | inputFileListPaths = (
339 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
340 | );
341 | name = "[CP] Embed Pods Frameworks";
342 | outputFileListPaths = (
343 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
344 | );
345 | runOnlyForDeploymentPostprocessing = 0;
346 | shellPath = /bin/sh;
347 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-frameworks.sh\"\n";
348 | showEnvVarsInLog = 0;
349 | };
350 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
351 | isa = PBXShellScriptBuildPhase;
352 | buildActionMask = 2147483647;
353 | files = (
354 | );
355 | inputFileListPaths = (
356 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-resources-${CONFIGURATION}-input-files.xcfilelist",
357 | );
358 | name = "[CP] Copy Pods Resources";
359 | outputFileListPaths = (
360 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-resources-${CONFIGURATION}-output-files.xcfilelist",
361 | );
362 | runOnlyForDeploymentPostprocessing = 0;
363 | shellPath = /bin/sh;
364 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-resources.sh\"\n";
365 | showEnvVarsInLog = 0;
366 | };
367 | F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = {
368 | isa = PBXShellScriptBuildPhase;
369 | buildActionMask = 2147483647;
370 | files = (
371 | );
372 | inputFileListPaths = (
373 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-resources-${CONFIGURATION}-input-files.xcfilelist",
374 | );
375 | name = "[CP] Copy Pods Resources";
376 | outputFileListPaths = (
377 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-resources-${CONFIGURATION}-output-files.xcfilelist",
378 | );
379 | runOnlyForDeploymentPostprocessing = 0;
380 | shellPath = /bin/sh;
381 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-resources.sh\"\n";
382 | showEnvVarsInLog = 0;
383 | };
384 | /* End PBXShellScriptBuildPhase section */
385 |
386 | /* Begin PBXSourcesBuildPhase section */
387 | 00E356EA1AD99517003FC87E /* Sources */ = {
388 | isa = PBXSourcesBuildPhase;
389 | buildActionMask = 2147483647;
390 | files = (
391 | 00E356F31AD99517003FC87E /* RNInAppPurchaseSampleTests.m in Sources */,
392 | );
393 | runOnlyForDeploymentPostprocessing = 0;
394 | };
395 | 13B07F871A680F5B00A75B9A /* Sources */ = {
396 | isa = PBXSourcesBuildPhase;
397 | buildActionMask = 2147483647;
398 | files = (
399 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
400 | 13B07FC11A68108700A75B9A /* main.m in Sources */,
401 | );
402 | runOnlyForDeploymentPostprocessing = 0;
403 | };
404 | /* End PBXSourcesBuildPhase section */
405 |
406 | /* Begin PBXTargetDependency section */
407 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
408 | isa = PBXTargetDependency;
409 | target = 13B07F861A680F5B00A75B9A /* RNInAppPurchaseSample */;
410 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
411 | };
412 | /* End PBXTargetDependency section */
413 |
414 | /* Begin XCBuildConfiguration section */
415 | 00E356F61AD99517003FC87E /* Debug */ = {
416 | isa = XCBuildConfiguration;
417 | baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig */;
418 | buildSettings = {
419 | BUNDLE_LOADER = "$(TEST_HOST)";
420 | GCC_PREPROCESSOR_DEFINITIONS = (
421 | "DEBUG=1",
422 | "$(inherited)",
423 | );
424 | INFOPLIST_FILE = RNInAppPurchaseSampleTests/Info.plist;
425 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
426 | LD_RUNPATH_SEARCH_PATHS = (
427 | "$(inherited)",
428 | "@executable_path/Frameworks",
429 | "@loader_path/Frameworks",
430 | );
431 | OTHER_LDFLAGS = (
432 | "-ObjC",
433 | "-lc++",
434 | "$(inherited)",
435 | );
436 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
437 | PRODUCT_NAME = "$(TARGET_NAME)";
438 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RNInAppPurchaseSample.app/RNInAppPurchaseSample";
439 | };
440 | name = Debug;
441 | };
442 | 00E356F71AD99517003FC87E /* Release */ = {
443 | isa = XCBuildConfiguration;
444 | baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig */;
445 | buildSettings = {
446 | BUNDLE_LOADER = "$(TEST_HOST)";
447 | COPY_PHASE_STRIP = NO;
448 | INFOPLIST_FILE = RNInAppPurchaseSampleTests/Info.plist;
449 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
450 | LD_RUNPATH_SEARCH_PATHS = (
451 | "$(inherited)",
452 | "@executable_path/Frameworks",
453 | "@loader_path/Frameworks",
454 | );
455 | OTHER_LDFLAGS = (
456 | "-ObjC",
457 | "-lc++",
458 | "$(inherited)",
459 | );
460 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
461 | PRODUCT_NAME = "$(TARGET_NAME)";
462 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RNInAppPurchaseSample.app/RNInAppPurchaseSample";
463 | };
464 | name = Release;
465 | };
466 | 13B07F941A680F5B00A75B9A /* Debug */ = {
467 | isa = XCBuildConfiguration;
468 | baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-RNInAppPurchaseSample.debug.xcconfig */;
469 | buildSettings = {
470 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
471 | CLANG_ENABLE_MODULES = YES;
472 | CURRENT_PROJECT_VERSION = 1;
473 | ENABLE_BITCODE = NO;
474 | INFOPLIST_FILE = RNInAppPurchaseSample/Info.plist;
475 | LD_RUNPATH_SEARCH_PATHS = (
476 | "$(inherited)",
477 | "@executable_path/Frameworks",
478 | );
479 | MARKETING_VERSION = 1.0;
480 | OTHER_LDFLAGS = (
481 | "$(inherited)",
482 | "-ObjC",
483 | "-lc++",
484 | );
485 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
486 | PRODUCT_NAME = RNInAppPurchaseSample;
487 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
488 | SWIFT_VERSION = 5.0;
489 | VERSIONING_SYSTEM = "apple-generic";
490 | };
491 | name = Debug;
492 | };
493 | 13B07F951A680F5B00A75B9A /* Release */ = {
494 | isa = XCBuildConfiguration;
495 | baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-RNInAppPurchaseSample.release.xcconfig */;
496 | buildSettings = {
497 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
498 | CLANG_ENABLE_MODULES = YES;
499 | CURRENT_PROJECT_VERSION = 1;
500 | INFOPLIST_FILE = RNInAppPurchaseSample/Info.plist;
501 | LD_RUNPATH_SEARCH_PATHS = (
502 | "$(inherited)",
503 | "@executable_path/Frameworks",
504 | );
505 | MARKETING_VERSION = 1.0;
506 | OTHER_LDFLAGS = (
507 | "$(inherited)",
508 | "-ObjC",
509 | "-lc++",
510 | );
511 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
512 | PRODUCT_NAME = RNInAppPurchaseSample;
513 | SWIFT_VERSION = 5.0;
514 | VERSIONING_SYSTEM = "apple-generic";
515 | };
516 | name = Release;
517 | };
518 | 83CBBA201A601CBA00E9B192 /* Debug */ = {
519 | isa = XCBuildConfiguration;
520 | buildSettings = {
521 | ALWAYS_SEARCH_USER_PATHS = NO;
522 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
523 | CLANG_CXX_LANGUAGE_STANDARD = "c++20";
524 | CLANG_CXX_LIBRARY = "libc++";
525 | CLANG_ENABLE_MODULES = YES;
526 | CLANG_ENABLE_OBJC_ARC = YES;
527 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
528 | CLANG_WARN_BOOL_CONVERSION = YES;
529 | CLANG_WARN_COMMA = YES;
530 | CLANG_WARN_CONSTANT_CONVERSION = YES;
531 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
532 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
533 | CLANG_WARN_EMPTY_BODY = YES;
534 | CLANG_WARN_ENUM_CONVERSION = YES;
535 | CLANG_WARN_INFINITE_RECURSION = YES;
536 | CLANG_WARN_INT_CONVERSION = YES;
537 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
538 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
539 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
540 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
541 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
542 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
543 | CLANG_WARN_STRICT_PROTOTYPES = YES;
544 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
545 | CLANG_WARN_UNREACHABLE_CODE = YES;
546 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
547 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
548 | COPY_PHASE_STRIP = NO;
549 | ENABLE_STRICT_OBJC_MSGSEND = YES;
550 | ENABLE_TESTABILITY = YES;
551 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
552 | GCC_C_LANGUAGE_STANDARD = gnu99;
553 | GCC_DYNAMIC_NO_PIC = NO;
554 | GCC_NO_COMMON_BLOCKS = YES;
555 | GCC_OPTIMIZATION_LEVEL = 0;
556 | GCC_PREPROCESSOR_DEFINITIONS = (
557 | "DEBUG=1",
558 | "$(inherited)",
559 | );
560 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
561 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
562 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
563 | GCC_WARN_UNDECLARED_SELECTOR = YES;
564 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
565 | GCC_WARN_UNUSED_FUNCTION = YES;
566 | GCC_WARN_UNUSED_VARIABLE = YES;
567 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
568 | LD_RUNPATH_SEARCH_PATHS = (
569 | /usr/lib/swift,
570 | "$(inherited)",
571 | );
572 | LIBRARY_SEARCH_PATHS = (
573 | "\"$(SDKROOT)/usr/lib/swift\"",
574 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
575 | "\"$(inherited)\"",
576 | );
577 | MTL_ENABLE_DEBUG_INFO = YES;
578 | ONLY_ACTIVE_ARCH = YES;
579 | OTHER_CFLAGS = (
580 | "$(inherited)",
581 | " ",
582 | );
583 | OTHER_CPLUSPLUSFLAGS = (
584 | "$(OTHER_CFLAGS)",
585 | "-DFOLLY_NO_CONFIG",
586 | "-DFOLLY_MOBILE=1",
587 | "-DFOLLY_USE_LIBCPP=1",
588 | "-DFOLLY_CFG_NO_COROUTINES=1",
589 | " ",
590 | );
591 | OTHER_LDFLAGS = (
592 | "$(inherited)",
593 | " ",
594 | );
595 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
596 | SDKROOT = iphoneos;
597 | USE_HERMES = true;
598 | };
599 | name = Debug;
600 | };
601 | 83CBBA211A601CBA00E9B192 /* Release */ = {
602 | isa = XCBuildConfiguration;
603 | buildSettings = {
604 | ALWAYS_SEARCH_USER_PATHS = NO;
605 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
606 | CLANG_CXX_LANGUAGE_STANDARD = "c++20";
607 | CLANG_CXX_LIBRARY = "libc++";
608 | CLANG_ENABLE_MODULES = YES;
609 | CLANG_ENABLE_OBJC_ARC = YES;
610 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
611 | CLANG_WARN_BOOL_CONVERSION = YES;
612 | CLANG_WARN_COMMA = YES;
613 | CLANG_WARN_CONSTANT_CONVERSION = YES;
614 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
615 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
616 | CLANG_WARN_EMPTY_BODY = YES;
617 | CLANG_WARN_ENUM_CONVERSION = YES;
618 | CLANG_WARN_INFINITE_RECURSION = YES;
619 | CLANG_WARN_INT_CONVERSION = YES;
620 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
621 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
622 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
623 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
624 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
625 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
626 | CLANG_WARN_STRICT_PROTOTYPES = YES;
627 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
628 | CLANG_WARN_UNREACHABLE_CODE = YES;
629 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
630 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
631 | COPY_PHASE_STRIP = YES;
632 | ENABLE_NS_ASSERTIONS = NO;
633 | ENABLE_STRICT_OBJC_MSGSEND = YES;
634 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
635 | GCC_C_LANGUAGE_STANDARD = gnu99;
636 | GCC_NO_COMMON_BLOCKS = YES;
637 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
638 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
639 | GCC_WARN_UNDECLARED_SELECTOR = YES;
640 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
641 | GCC_WARN_UNUSED_FUNCTION = YES;
642 | GCC_WARN_UNUSED_VARIABLE = YES;
643 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
644 | LD_RUNPATH_SEARCH_PATHS = (
645 | /usr/lib/swift,
646 | "$(inherited)",
647 | );
648 | LIBRARY_SEARCH_PATHS = (
649 | "\"$(SDKROOT)/usr/lib/swift\"",
650 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
651 | "\"$(inherited)\"",
652 | );
653 | MTL_ENABLE_DEBUG_INFO = NO;
654 | OTHER_CFLAGS = (
655 | "$(inherited)",
656 | " ",
657 | );
658 | OTHER_CPLUSPLUSFLAGS = (
659 | "$(OTHER_CFLAGS)",
660 | "-DFOLLY_NO_CONFIG",
661 | "-DFOLLY_MOBILE=1",
662 | "-DFOLLY_USE_LIBCPP=1",
663 | "-DFOLLY_CFG_NO_COROUTINES=1",
664 | " ",
665 | );
666 | OTHER_LDFLAGS = (
667 | "$(inherited)",
668 | " ",
669 | );
670 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
671 | SDKROOT = iphoneos;
672 | USE_HERMES = true;
673 | VALIDATE_PRODUCT = YES;
674 | };
675 | name = Release;
676 | };
677 | /* End XCBuildConfiguration section */
678 |
679 | /* Begin XCConfigurationList section */
680 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RNInAppPurchaseSampleTests" */ = {
681 | isa = XCConfigurationList;
682 | buildConfigurations = (
683 | 00E356F61AD99517003FC87E /* Debug */,
684 | 00E356F71AD99517003FC87E /* Release */,
685 | );
686 | defaultConfigurationIsVisible = 0;
687 | defaultConfigurationName = Release;
688 | };
689 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNInAppPurchaseSample" */ = {
690 | isa = XCConfigurationList;
691 | buildConfigurations = (
692 | 13B07F941A680F5B00A75B9A /* Debug */,
693 | 13B07F951A680F5B00A75B9A /* Release */,
694 | );
695 | defaultConfigurationIsVisible = 0;
696 | defaultConfigurationName = Release;
697 | };
698 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RNInAppPurchaseSample" */ = {
699 | isa = XCConfigurationList;
700 | buildConfigurations = (
701 | 83CBBA201A601CBA00E9B192 /* Debug */,
702 | 83CBBA211A601CBA00E9B192 /* Release */,
703 | );
704 | defaultConfigurationIsVisible = 0;
705 | defaultConfigurationName = Release;
706 | };
707 | /* End XCConfigurationList section */
708 | };
709 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
710 | }
711 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample.xcodeproj/xcshareddata/xcschemes/RNInAppPurchaseSample.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : RCTAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample/AppDelegate.mm:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 |
3 | #import
4 |
5 | @implementation AppDelegate
6 |
7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
8 | {
9 | self.moduleName = @"RNInAppPurchaseSample";
10 | // You can add your custom initial props in the dictionary below.
11 | // They will be passed down to the ViewController used by React Native.
12 | self.initialProps = @{};
13 |
14 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
15 | }
16 |
17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
18 | {
19 | return [self getBundleURL];
20 | }
21 |
22 | - (NSURL *)getBundleURL
23 | {
24 | #if DEBUG
25 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
26 | #else
27 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
28 | #endif
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | RNInAppPurchaseSample
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(CURRENT_PROJECT_VERSION)
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 |
30 | NSAllowsArbitraryLoads
31 |
32 | NSAllowsLocalNetworking
33 |
34 |
35 | NSLocationWhenInUseUsageDescription
36 |
37 | UILaunchStoryboardName
38 | LaunchScreen
39 | UIRequiredDeviceCapabilities
40 |
41 | armv7
42 |
43 | UISupportedInterfaceOrientations
44 |
45 | UIInterfaceOrientationPortrait
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 | UIViewControllerBasedStatusBarAppearance
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategoryFileTimestamp
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | C617.1
13 |
14 |
15 |
16 | NSPrivacyAccessedAPIType
17 | NSPrivacyAccessedAPICategoryUserDefaults
18 | NSPrivacyAccessedAPITypeReasons
19 |
20 | CA92.1
21 |
22 |
23 |
24 | NSPrivacyAccessedAPIType
25 | NSPrivacyAccessedAPICategorySystemBootTime
26 | NSPrivacyAccessedAPITypeReasons
27 |
28 | 35F9.1
29 |
30 |
31 |
32 | NSPrivacyCollectedDataTypes
33 |
34 | NSPrivacyTracking
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSample/main.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | @autoreleasepool {
8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSampleTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/sample/ios/RNInAppPurchaseSampleTests/RNInAppPurchaseSampleTests.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | #import
5 | #import
6 |
7 | #define TIMEOUT_SECONDS 600
8 | #define TEXT_TO_LOOK_FOR @"Welcome to React"
9 |
10 | @interface RNInAppPurchaseSampleTests : XCTestCase
11 |
12 | @end
13 |
14 | @implementation RNInAppPurchaseSampleTests
15 |
16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
17 | {
18 | if (test(view)) {
19 | return YES;
20 | }
21 | for (UIView *subview in [view subviews]) {
22 | if ([self findSubviewInView:subview matching:test]) {
23 | return YES;
24 | }
25 | }
26 | return NO;
27 | }
28 |
29 | - (void)testRendersWelcomeScreen
30 | {
31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
33 | BOOL foundElement = NO;
34 |
35 | __block NSString *redboxError = nil;
36 | #ifdef DEBUG
37 | RCTSetLogFunction(
38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
39 | if (level >= RCTLogLevelError) {
40 | redboxError = message;
41 | }
42 | });
43 | #endif
44 |
45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
48 |
49 | foundElement = [self findSubviewInView:vc.view
50 | matching:^BOOL(UIView *view) {
51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
52 | return YES;
53 | }
54 | return NO;
55 | }];
56 | }
57 |
58 | #ifdef DEBUG
59 | RCTSetLogFunction(RCTDefaultLogFunction);
60 | #endif
61 |
62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/sample/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'react-native',
3 | };
4 |
--------------------------------------------------------------------------------
/sample/metro.config.js:
--------------------------------------------------------------------------------
1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
2 |
3 | /**
4 | * Metro configuration
5 | * https://facebook.github.io/metro/docs/configuration
6 | *
7 | * @type {import('metro-config').MetroConfig}
8 | */
9 | const config = {};
10 |
11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config);
12 |
--------------------------------------------------------------------------------
/sample/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "RNInAppPurchaseSample",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "android": "react-native run-android",
7 | "ios": "react-native run-ios",
8 | "lint": "eslint .",
9 | "start": "react-native start",
10 | "test": "jest"
11 | },
12 | "dependencies": {
13 | "@class101/react-native-in-app-purchase": "link:../",
14 | "react": "18.2.0",
15 | "react-native": "0.73.9"
16 | },
17 | "devDependencies": {
18 | "@babel/core": "^7.20.0",
19 | "@babel/preset-env": "^7.20.0",
20 | "@babel/runtime": "^7.20.0",
21 | "@react-native/babel-preset": "0.73.21",
22 | "@react-native/eslint-config": "0.73.2",
23 | "@react-native/metro-config": "0.73.5",
24 | "@react-native/typescript-config": "0.73.1",
25 | "@types/react": "^18.2.6",
26 | "@types/react-test-renderer": "^18.0.0",
27 | "babel-jest": "^29.6.3",
28 | "eslint": "^8.19.0",
29 | "jest": "^29.6.3",
30 | "prettier": "2.8.8",
31 | "react-test-renderer": "18.2.0",
32 | "typescript": "5.0.4"
33 | },
34 | "engines": {
35 | "node": ">=18"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/sample/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@react-native/typescript-config/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/src/NativeInAppPurchaseModule.ts:
--------------------------------------------------------------------------------
1 | import { TurboModule, TurboModuleRegistry } from "react-native";
2 | import type {
3 | Int32,
4 | } from 'react-native/Libraries/Types/CodegenTypes';
5 |
6 | type FetchProductInput = {
7 | id: string;
8 |
9 | // Android only
10 | type?: 'inapp' | 'subs';
11 | planId?: string;
12 | offerId?: string;
13 | }
14 |
15 | type Product = {
16 | productId: string;
17 | type: string;
18 | planId?: string;
19 | offerId?: string;
20 | title: string;
21 | description: string;
22 | price: string;
23 | currency: string;
24 | }
25 |
26 | type Purchase = {
27 | productIds: string[];
28 | transactionId: string;
29 | transactionDate: string;
30 | receipt: string;
31 | purchaseToken: string;
32 | }
33 |
34 | type PurchaseArgs = {
35 | // Android
36 | planId?: string,
37 | offerId?: string,
38 | originalPurchaseToken?: string,
39 | obfuscatedAccountId?: string,
40 | obfuscatedProfileId?: string,
41 |
42 | // iOS
43 | userId?: string,
44 | keyIdentifier?: string,
45 | nonce?: string,
46 | signature?: string,
47 | timestamp?: Int32,
48 | }
49 |
50 | export interface Spec extends TurboModule {
51 | readonly getConstants: () => {};
52 | configure:(config?: {
53 | isAlternativeBillingEnable?: boolean,
54 | }) => Promise;
55 | fetchProducts: (products: FetchProductInput[]) => void;
56 | flush: () => Promise;
57 | purchase: (productId: string, extras?: PurchaseArgs) => void;
58 | finalize: (purchase: Purchase, isConsumable: boolean) => Promise;
59 | fetchReceipt: () => Promise;
60 | onFetchProducts: (listener: (products: Product[]) => void) => void;
61 | onPurchase: (listener: (purchase: {
62 | productIds: string[],
63 | transactionId: string,
64 | transactionDate: string,
65 | receipt: string,
66 | purchaseToken: string,
67 | }) => void) => void,
68 | onAlternativeBillingFlow: (listener: (token: string) => void) => void;
69 | onError: (listener: (exception: {
70 | type: string,
71 | // Android only
72 | code?: Int32,
73 | message: string }) => void) => void;
74 | clear: () => void;
75 | }
76 |
77 | export default TurboModuleRegistry.get("NativeInAppPurchase") as Spec;
78 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './NativeInAppPurchaseModule';
--------------------------------------------------------------------------------