Skip to content

Commit bb7baa0

Browse files
authored
Merge pull request #70 from apphud/feature/attribute-from-web
update with latest dependencies; attribute from web method
2 parents 955c81b + 4eb8ac7 commit bb7baa0

18 files changed

+519
-319
lines changed

.yarnrc.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@ enableGlobalCache: false
44

55
nmHoistingLimits: workspaces
66

7-
nodeLinker: node-modules
8-
9-
yarnPath: .yarn/releases/yarn-3.6.1.cjs
7+
nodeLinker: node-modules

android/build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ android {
4040
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
4141
buildToolsVersion getExtOrDefault('buildToolsVersion')
4242
defaultConfig {
43-
minSdkVersion 16
43+
minSdkVersion getExtOrIntegerDefault('minSdkVersion')
4444
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
4545
versionCode 1
4646
versionName "1.0"
@@ -137,7 +137,7 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
137137
dependencies {
138138
// noinspection GradleDynamicVersion
139139
api 'com.facebook.react:react-native:+'
140-
implementation 'com.apphud:ApphudSDK-Android:2.1.0'
140+
implementation 'com.apphud:ApphudSDK-Android:2.8.4'
141141
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
142-
implementation 'com.android.billingclient:billing:5.2.0'
142+
implementation 'com.android.billingclient:billing:7.1.1'
143143
}

android/gradle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ ApphudSdk_kotlinVersion=1.5.20
22
ApphudSdk_compileSdkVersion=29
33
ApphudSdk_buildToolsVersion=30.0.3
44
ApphudSdk_targetSdkVersion=29
5+
ApphudSdk_minSdkVersion=24

android/src/main/java/com/reactnativeapphudsdk/ApphudDataTransformer.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ class ApphudDataTransformer {
3838
}
3939

4040
fun getApphudProductMap(apphudProduct: ApphudProduct): WritableNativeMap {
41-
val payload: WritableNativeMap = WritableNativeMap()
41+
val payload = WritableNativeMap()
4242
payload.putString("name", apphudProduct.name)
4343
payload.putString("store", apphudProduct.store)
44-
payload.putString("paywallIdentifier", apphudProduct.paywall_identifier)
45-
payload.putString("id", apphudProduct.product_id)
44+
payload.putString("paywallIdentifier", apphudProduct.paywallIdentifier)
45+
payload.putString("id", apphudProduct.productId)
4646
apphudProduct.productDetails?.let {
4747
payload.merge(getProductMap(it) )
4848
}

android/src/main/java/com/reactnativeapphudsdk/ApphudListenerHandler.kt

+12-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package com.reactnativeapphudsdk
22

33
import android.util.Log
44
import com.android.billingclient.api.ProductDetails
5+
import com.android.billingclient.api.Purchase
56
import com.android.billingclient.api.SkuDetails
67
import com.apphud.sdk.ApphudListener
78
import com.apphud.sdk.domain.ApphudPaywall
9+
import com.apphud.sdk.domain.ApphudPlacement
10+
import com.apphud.sdk.domain.ApphudUser
811
import com.facebook.react.bridge.ReactApplicationContext
912
import com.facebook.react.bridge.ReactContextBaseJavaModule
1013
import com.facebook.react.bridge.WritableMap
@@ -55,7 +58,15 @@ class ApphudListenerHandler(private val reactContext: ReactApplicationContext) :
5558
.emit(ApphudSdkDelegateEvents.PAYWALLS_DID_FULLY_LOAD.value, nativeArray);
5659
}
5760

58-
override fun userDidLoad() {
61+
override fun placementsDidFullyLoad(placements: List<ApphudPlacement>) {
62+
// do nothing
63+
}
64+
65+
override fun userDidLoad(user: ApphudUser) {
66+
// do nothing
67+
}
68+
69+
override fun apphudDidReceivePurchase(purchase: Purchase) {
5970
// do nothing
6071
}
6172

android/src/main/java/com/reactnativeapphudsdk/ApphudSdkModule.kt

+80-35
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package com.reactnativeapphudsdk
22
import android.util.Log
3-
import androidx.annotation.RequiresPermission.Read
43
import com.apphud.sdk.Apphud
54
import com.apphud.sdk.ApphudAttributionProvider
65
import com.apphud.sdk.ApphudUserPropertyKey
6+
import com.apphud.sdk.ApphudUtils
77
import com.apphud.sdk.domain.ApphudProduct
88
import com.apphud.sdk.managers.HeadersInterceptor
99
import com.facebook.react.bridge.*
1010
import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
11-
import java.lang.Exception
1211

1312
class ApphudSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
1413

@@ -22,28 +21,31 @@ class ApphudSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
2221

2322
init {
2423
HeadersInterceptor.X_SDK = "reactnative"
25-
HeadersInterceptor.X_SDK_VERSION = "2.1.0"
24+
HeadersInterceptor.X_SDK_VERSION = "2.2.0"
2625
listener = ApphudListenerHandler(reactContext)
2726
listener?.let { Apphud.setListener(it) }
2827
}
2928

3029
@ReactMethod
31-
fun start(options: ReadableMap) {
32-
startManually(options)
30+
fun start(options: ReadableMap, promise: Promise) {
31+
startManually(options, promise)
3332
}
3433

3534
@ReactMethod
36-
fun startManually(options: ReadableMap) {
35+
fun startManually(options: ReadableMap, promise: Promise) {
3736
val apiKey = options.getString("apiKey")
3837
val userId = options.getString("userId")
3938
val deviceId = options.getString("deviceId")
4039

4140
if (apiKey.isNullOrEmpty()) {
41+
promise.reject("Error", "apiKey not set")
4242
return
4343
}
4444

4545
runOnUiThread {
46-
Apphud.start(this.reactApplicationContext, apiKey!!, userId, deviceId)
46+
Apphud.start(this.reactApplicationContext, apiKey, userId, deviceId) { _ ->
47+
promise.resolve(null)
48+
}
4749
}
4850
}
4951

@@ -64,9 +66,14 @@ class ApphudSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
6466

6567
@ReactMethod
6668
fun paywalls(promise: Promise) {
67-
Apphud.paywallsDidLoadCallback {
69+
Apphud.paywallsDidLoadCallback { list, error ->
70+
if (error != null) {
71+
promise.reject(error)
72+
return@paywallsDidLoadCallback
73+
}
74+
6875
val result = WritableNativeArray()
69-
for (paywall in it) {
76+
for (paywall in list) {
7077
result.pushMap(ApphudDataTransformer.getApphudPaywallMap(paywall))
7178
}
7279
promise.resolve(result)
@@ -75,18 +82,24 @@ class ApphudSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
7582

7683
@ReactMethod
7784
fun paywallShown(identifier: String) {
78-
val paywall = Apphud.paywalls().firstOrNull { it.identifier == identifier }
85+
Apphud.paywallsDidLoadCallback { apphudPaywalls, _ ->
86+
val paywall = apphudPaywalls.firstOrNull { it.identifier == identifier }
87+
7988
paywall?.let {
80-
Apphud.paywallShown(it)
89+
Apphud.paywallShown(it)
8190
}
91+
}
8292
}
8393

8494
@ReactMethod
8595
fun paywallClosed(identifier: String) {
86-
val paywall = Apphud.paywalls().firstOrNull { it.identifier == identifier }
96+
Apphud.paywallsDidLoadCallback { apphudPaywalls, _ ->
97+
val paywall = apphudPaywalls.firstOrNull { it.identifier == identifier }
98+
8799
paywall?.let {
88-
Apphud.paywallClosed(it)
100+
Apphud.paywallClosed(it)
89101
}
102+
}
90103
}
91104

92105
@ReactMethod
@@ -100,35 +113,40 @@ class ApphudSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
100113
val paywallId = args.getString("paywallId")
101114

102115
var product: ApphudProduct? = null
103-
val paywalls = Apphud.paywalls()
104116

105-
for (paywall in paywalls) {
106-
if (product == null) {
107-
product = paywall.products?.firstOrNull { p ->
108-
p.product_id == productId && (paywallId.isNullOrEmpty() || p.paywall_identifier == paywallId)
117+
Apphud.paywallsDidLoadCallback { paywalls, apphudError ->
118+
if (apphudError != null) {
119+
promise.reject(apphudError)
120+
121+
return@paywallsDidLoadCallback
122+
}
123+
124+
for (paywall in paywalls) {
125+
if (product == null) {
126+
product = paywall.products?.firstOrNull { p ->
127+
p.productId == productId && (paywallId.isNullOrEmpty() || p.paywallIdentifier == paywallId)
128+
}
109129
}
110130
}
111-
}
112131

113-
val isSub = product?.productDetails?.productType?.lowercase() == "subs"
114-
val offerToken = args.getString("offerToken")
115-
val isConsumable = if (args.hasKey("isConsumable")) args.getBoolean("isConsumable") else false
132+
val isSub = product?.productDetails?.productType?.lowercase() == "subs"
133+
val offerToken = args.getString("offerToken")
134+
val isConsumable = if (args.hasKey("isConsumable")) args.getBoolean("isConsumable") else false
116135

117-
if (product == null) {
118-
promise.reject("Error", "Product not found")
119-
return
120-
}
136+
if (product == null) {
137+
promise.reject("Error", "Product not found")
138+
return@paywallsDidLoadCallback
139+
}
121140

122-
if (isSub && offerToken.isNullOrEmpty()) {
123-
promise.reject("Error", "Offer Token not found")
124-
} else if (!offerToken.isNullOrEmpty()) {
125-
purchaseSubscription(product, offerToken, promise)
126-
} else {
127-
purchaseOneTimeProduct(product, isConsumable, promise)
141+
if (isSub || product?.productDetails == null) {
142+
purchaseSubscription(product!!, offerToken, promise)
143+
} else {
144+
purchaseOneTimeProduct(product!!, isConsumable, promise)
145+
}
128146
}
129147
}
130148

131-
private fun purchaseSubscription(product: ApphudProduct, offerToken: String, promise: Promise) {
149+
private fun purchaseSubscription(product: ApphudProduct, offerToken: String?, promise: Promise) {
132150
this.currentActivity?.let {
133151
Apphud.purchase(it, product, offerToken) { res ->
134152
promise.resolve(ApphudDataTransformer.getPurchaseMap(res))
@@ -173,6 +191,32 @@ class ApphudSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
173191
}
174192
}
175193

194+
@ReactMethod
195+
fun attributeFromWeb(options: ReadableMap, promise: Promise) {
196+
val data = options.toHashMap().let {
197+
val result = mutableMapOf<String, Any>()
198+
199+
for ((key, value) in it) {
200+
value?.let { x ->
201+
result[key] = x
202+
}
203+
}
204+
205+
return@let result
206+
}
207+
208+
Apphud.attributeFromWeb(data) { success, user ->
209+
val result = WritableNativeMap()
210+
211+
user?.userId?.let {
212+
result.putString("user_id", it)
213+
}
214+
result.putBoolean("is_premium", Apphud.hasPremiumAccess())
215+
result.putBoolean("result", success)
216+
promise.resolve(result)
217+
}
218+
}
219+
176220
private fun stringToApphudAttributionProvider(value: String): ApphudAttributionProvider? {
177221
return enumValues<ApphudAttributionProvider>().find {
178222
it.name == value
@@ -300,7 +344,7 @@ class ApphudSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
300344

301345
@ReactMethod
302346
fun enableDebugLogs() {
303-
Apphud.enableDebugLogs()
347+
ApphudUtils.enableAllLogs()
304348
}
305349

306350
@ReactMethod
@@ -314,8 +358,9 @@ class ApphudSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJ
314358
}
315359

316360
@ReactMethod
317-
fun logout() {
361+
fun logout(promise: Promise) {
318362
Apphud.logout()
363+
promise.resolve(null)
319364
}
320365

321366
private fun getUserPropertyKey(key: String): ApphudUserPropertyKey {

example/ios/.xcode.env.local

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export NODE_BINARY=/opt/homebrew/Cellar/node@20/20.18.1/bin/node

example/ios/ApphudBridgeClass.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class ApphudBridgeClass: NSObject {
1313
Apphud.submitPushNotificationsToken(token: data, callback: nil)
1414
}
1515

16-
@objc
16+
@MainActor @objc
1717
static func handleUserInfo(dict: [AnyHashable: Any]) {
1818
Apphud.handlePushNotification(apsInfo: dict)
1919
}

example/ios/ExampleApp.xcodeproj/project.pbxproj

+8-2
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,10 @@
384384
"-DFOLLY_CFG_NO_COROUTINES=1",
385385
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
386386
);
387-
OTHER_LDFLAGS = "$(inherited) ";
387+
OTHER_LDFLAGS = (
388+
"$(inherited)",
389+
" ",
390+
);
388391
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
389392
SDKROOT = iphoneos;
390393
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
@@ -453,7 +456,10 @@
453456
"-DFOLLY_CFG_NO_COROUTINES=1",
454457
"-DFOLLY_HAVE_CLOCK_GETTIME=1",
455458
);
456-
OTHER_LDFLAGS = "$(inherited) ";
459+
OTHER_LDFLAGS = (
460+
"$(inherited)",
461+
" ",
462+
);
457463
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
458464
SDKROOT = iphoneos;
459465
USE_HERMES = true;

example/ios/Podfile.lock

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
PODS:
2-
- ApphudSDK (3.1.4)
2+
- ApphudSDK (3.5.9)
33
- boost (1.84.0)
44
- DoubleConversion (1.1.6)
55
- fast_float (6.1.4)
@@ -1211,8 +1211,8 @@ PODS:
12111211
- React-jsiexecutor
12121212
- React-RCTFBReactNativeSpec
12131213
- ReactCommon/turbomodule/core
1214-
- react-native-apphud-sdk (2.1.0):
1215-
- ApphudSDK (= 3.1.4)
1214+
- react-native-apphud-sdk (2.2.0):
1215+
- ApphudSDK (= 3.5.9)
12161216
- React-Core
12171217
- react-native-safe-area-context (5.2.0):
12181218
- DoubleConversion
@@ -1932,7 +1932,7 @@ EXTERNAL SOURCES:
19321932
:path: "../node_modules/react-native/ReactCommon/yoga"
19331933

19341934
SPEC CHECKSUMS:
1935-
ApphudSDK: 5e5a30f21b8b44b864e5f16f2b2a122d2b906781
1935+
ApphudSDK: 4aad14717e9029d9e9defc205d75b4836cbed559
19361936
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
19371937
DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
19381938
fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6
@@ -1969,7 +1969,7 @@ SPEC CHECKSUMS:
19691969
React-logger: 1935d6e6461e9c8be4c87af56c56a4876021171e
19701970
React-Mapbuffer: 212171f037e3b22e6c2df839aa826806da480b85
19711971
React-microtasksnativemodule: 72564d5469003687d39bfc4efad281df8efc0684
1972-
react-native-apphud-sdk: c1ea12dd222d96375beed503e64cbf7451f0bcc8
1972+
react-native-apphud-sdk: 101e802e81c69f1ca8998ce2ec8c5fd961a52729
19731973
react-native-safe-area-context: 9c33120e9eac7741a5364cc2d9f74665049b76b3
19741974
React-nativeconfig: cb207ebba7cafce30657c7ad9f1587a8f32e4564
19751975
React-NativeModulesApple: 82a8bee52df9f5b378195a500f22be3a6ef0f890
@@ -2005,8 +2005,8 @@ SPEC CHECKSUMS:
20052005
RNReanimated: ef80cf675203a39bb5e5464234cb08a0f0040ac2
20062006
RNVectorIcons: 14a0c42f16a26bcc3e79a19bc1c5718284b1d469
20072007
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
2008-
Yoga: 2957d0e744897870b5a377f26522e3f08cadd7ac
2008+
Yoga: 1fd059161b449018342943b095a6d4e69bcaa719
20092009

20102010
PODFILE CHECKSUM: a12992b818b7dbdfe9a7e215f41593babfb4de2e
20112011

2012-
COCOAPODS: 1.15.2
2012+
COCOAPODS: 1.16.2

example/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"android": "react-native run-android",
77
"ios": "react-native run-ios",
88
"lint": "eslint .",
9-
"start": "react-native start",
9+
"start": "react-native start --client-logs",
1010
"test": "jest",
1111
"export": "export NODE_OPTIONS=--openssl-legacy-provider"
1212
},

0 commit comments

Comments
 (0)