com-tapp-so-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ComTappSoSdk.podspec +50 -0
- package/LICENSE +20 -0
- package/README.md +263 -0
- package/android/build.gradle +114 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/comtappsosdk/ComTappSoSdkModule.kt +354 -0
- package/android/src/main/java/com/comtappsosdk/ComTappSoSdkPackage.kt +45 -0
- package/ios/ComTappSoSdk.h +62 -0
- package/ios/ComTappSoSdk.mm +343 -0
- package/ios/generated/ComTappSoSdkSpec/ComTappSoSdkSpec-generated.mm +81 -0
- package/ios/generated/ComTappSoSdkSpec/ComTappSoSdkSpec.h +84 -0
- package/ios/generated/ComTappSoSdkSpecJSI-generated.cpp +76 -0
- package/ios/generated/ComTappSoSdkSpecJSI.h +125 -0
- package/lib/module/NativeComTappSoSdk.js +5 -0
- package/lib/module/NativeComTappSoSdk.js.map +1 -0
- package/lib/module/Types.js +47 -0
- package/lib/module/Types.js.map +1 -0
- package/lib/module/events.js +17 -0
- package/lib/module/events.js.map +1 -0
- package/lib/module/index.js +58 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/src/NativeComTappSoSdk.d.ts +37 -0
- package/lib/typescript/src/NativeComTappSoSdk.d.ts.map +1 -0
- package/lib/typescript/src/Types.d.ts +145 -0
- package/lib/typescript/src/Types.d.ts.map +1 -0
- package/lib/typescript/src/events.d.ts +10 -0
- package/lib/typescript/src/events.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +13 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +169 -0
- package/src/NativeComTappSoSdk.ts +46 -0
- package/src/Types.ts +149 -0
- package/src/events.ts +21 -0
- package/src/index.tsx +81 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
package com.comtappsosdk
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import com.example.tapp.Tapp
|
|
5
|
+
import com.example.tapp.models.Affiliate
|
|
6
|
+
import com.example.tapp.models.Environment
|
|
7
|
+
import com.example.tapp.services.affiliate.tapp.DeferredLinkDelegate
|
|
8
|
+
import com.example.tapp.services.network.RequestModels
|
|
9
|
+
import com.example.tapp.utils.Logger
|
|
10
|
+
import com.example.tapp.utils.TappConfiguration
|
|
11
|
+
import com.facebook.react.bridge.Arguments
|
|
12
|
+
import com.facebook.react.bridge.Promise
|
|
13
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
14
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
15
|
+
import com.facebook.react.bridge.ReactMethod
|
|
16
|
+
import com.facebook.react.bridge.ReadableMap
|
|
17
|
+
import com.facebook.react.bridge.ReadableType
|
|
18
|
+
import com.facebook.react.bridge.WritableMap
|
|
19
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
20
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
21
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule
|
|
22
|
+
import kotlinx.coroutines.CoroutineScope
|
|
23
|
+
import kotlinx.coroutines.Dispatchers
|
|
24
|
+
import kotlinx.coroutines.launch
|
|
25
|
+
import kotlinx.coroutines.withContext
|
|
26
|
+
|
|
27
|
+
@ReactModule(name = ComTappSoSdkModule.NAME)
|
|
28
|
+
class ComTappSoSdkModule(reactContext: ReactApplicationContext) :
|
|
29
|
+
ReactContextBaseJavaModule(reactContext), TurboModule{
|
|
30
|
+
|
|
31
|
+
companion object {
|
|
32
|
+
const val NAME = "ComTappSoSdk"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private lateinit var tapp: Tapp
|
|
36
|
+
|
|
37
|
+
init {
|
|
38
|
+
Log.i(NAME, "IS_NEW_ARCHITECTURE_ENABLED: ${BuildConfig.IS_NEW_ARCHITECTURE_ENABLED}")
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
override fun getName(): String = NAME
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@ReactMethod
|
|
45
|
+
fun start(authToken: String, env: String, tappToken: String) {
|
|
46
|
+
if (!::tapp.isInitialized) {
|
|
47
|
+
tapp = Tapp(reactApplicationContext)
|
|
48
|
+
// Set the deferred link delegate to emit events to JS.
|
|
49
|
+
tapp.deferredLinkDelegate = object : DeferredLinkDelegate {
|
|
50
|
+
override fun didFailResolvingUrl(response: RequestModels.FailResolvingUrlResponse) {
|
|
51
|
+
didFailResolvingURL(response)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
override fun didReceiveDeferredLink(linkDataResponse: RequestModels.TappLinkDataResponse) {
|
|
55
|
+
sendDeferredLinkEvent(linkDataResponse)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override fun testListener(test: String) {
|
|
59
|
+
sendTestEvent(test)
|
|
60
|
+
//Logger.logInfo("Test listener triggered with test: $test");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Map environment string to Environment enum
|
|
65
|
+
val environment = when (env.uppercase()) {
|
|
66
|
+
"SANDBOX" -> Environment.SANDBOX
|
|
67
|
+
"PRODUCTION" -> Environment.PRODUCTION
|
|
68
|
+
else -> throw IllegalArgumentException("Invalid environment: $env")
|
|
69
|
+
}
|
|
70
|
+
// Map affiliate string to Affiliate enum
|
|
71
|
+
val affiliateEnum = when ("TAPP_NATIVE") {
|
|
72
|
+
"TAPP_NATIVE" -> Affiliate.TAPP_NATIVE
|
|
73
|
+
else -> throw IllegalArgumentException("Invalid affiliate")
|
|
74
|
+
}
|
|
75
|
+
val config = TappConfiguration(authToken, environment, tappToken, affiliateEnum)
|
|
76
|
+
tapp.start(config)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@ReactMethod
|
|
80
|
+
fun url(influencer: String, adGroup: String?, creative: String?, data: ReadableMap?, promise: Promise?) {
|
|
81
|
+
if (!::tapp.isInitialized) {
|
|
82
|
+
tapp = Tapp(reactApplicationContext)
|
|
83
|
+
}
|
|
84
|
+
val dataMap = data?.toHashMap()?.mapValues { it.value.toString() } ?: emptyMap()
|
|
85
|
+
CoroutineScope(Dispatchers.IO).launch {
|
|
86
|
+
try {
|
|
87
|
+
val result = tapp.url(influencer, adGroup, creative, dataMap)
|
|
88
|
+
if (result.error) {
|
|
89
|
+
promise?.resolve(result.message)
|
|
90
|
+
} else {
|
|
91
|
+
promise?.resolve(result.influencer_url)
|
|
92
|
+
}
|
|
93
|
+
} catch (e: Exception) {
|
|
94
|
+
promise?.reject("URL_ERROR", e.message ?: "An unexpected error occurred")
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@ReactMethod
|
|
100
|
+
fun handleTappEvent(
|
|
101
|
+
eventAction: Double,
|
|
102
|
+
customValue: String?,
|
|
103
|
+
metadata: ReadableMap?,
|
|
104
|
+
promise: Promise
|
|
105
|
+
) {
|
|
106
|
+
if (!::tapp.isInitialized) {
|
|
107
|
+
tapp = Tapp(reactApplicationContext)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
val action = when (eventAction.toInt()) {
|
|
112
|
+
0 -> RequestModels.EventAction.custom(customValue ?: "custom_event_autogenerated")
|
|
113
|
+
1 -> RequestModels.EventAction.tapp_add_payment_info
|
|
114
|
+
2 -> RequestModels.EventAction.tapp_add_to_cart
|
|
115
|
+
3 -> RequestModels.EventAction.tapp_add_to_wishlist
|
|
116
|
+
4 -> RequestModels.EventAction.tapp_complete_registration
|
|
117
|
+
5 -> RequestModels.EventAction.tapp_contact
|
|
118
|
+
6 -> RequestModels.EventAction.tapp_customize_product
|
|
119
|
+
7 -> RequestModels.EventAction.tapp_donate
|
|
120
|
+
8 -> RequestModels.EventAction.tapp_find_location
|
|
121
|
+
9 -> RequestModels.EventAction.tapp_initiate_checkout
|
|
122
|
+
10 -> RequestModels.EventAction.tapp_generate_lead
|
|
123
|
+
11 -> RequestModels.EventAction.tapp_purchase
|
|
124
|
+
12 -> RequestModels.EventAction.tapp_schedule
|
|
125
|
+
13 -> RequestModels.EventAction.tapp_search
|
|
126
|
+
14 -> RequestModels.EventAction.tapp_start_trial
|
|
127
|
+
15 -> RequestModels.EventAction.tapp_submit_application
|
|
128
|
+
16 -> RequestModels.EventAction.tapp_subscribe
|
|
129
|
+
17 -> RequestModels.EventAction.tapp_view_content
|
|
130
|
+
18 -> RequestModels.EventAction.tapp_click_button
|
|
131
|
+
19 -> RequestModels.EventAction.tapp_download_file
|
|
132
|
+
20 -> RequestModels.EventAction.tapp_join_group
|
|
133
|
+
21 -> RequestModels.EventAction.tapp_achieve_level
|
|
134
|
+
22 -> RequestModels.EventAction.tapp_create_group
|
|
135
|
+
23 -> RequestModels.EventAction.tapp_create_role
|
|
136
|
+
24 -> RequestModels.EventAction.tapp_link_click
|
|
137
|
+
25 -> RequestModels.EventAction.tapp_link_impression
|
|
138
|
+
26 -> RequestModels.EventAction.tapp_apply_for_loan
|
|
139
|
+
27 -> RequestModels.EventAction.tapp_loan_approval
|
|
140
|
+
28 -> RequestModels.EventAction.tapp_loan_disbursal
|
|
141
|
+
29 -> RequestModels.EventAction.tapp_login
|
|
142
|
+
30 -> RequestModels.EventAction.tapp_rate
|
|
143
|
+
31 -> RequestModels.EventAction.tapp_spend_credits
|
|
144
|
+
32 -> RequestModels.EventAction.tapp_unlock_achievement
|
|
145
|
+
33 -> RequestModels.EventAction.tapp_add_shipping_info
|
|
146
|
+
34 -> RequestModels.EventAction.tapp_earn_virtual_currency
|
|
147
|
+
35 -> RequestModels.EventAction.tapp_start_level
|
|
148
|
+
36 -> RequestModels.EventAction.tapp_complete_level
|
|
149
|
+
37 -> RequestModels.EventAction.tapp_post_score
|
|
150
|
+
38 -> RequestModels.EventAction.tapp_select_content
|
|
151
|
+
39 -> RequestModels.EventAction.tapp_begin_tutorial
|
|
152
|
+
40 -> RequestModels.EventAction.tapp_complete_tutorial
|
|
153
|
+
else -> null
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (action == null) {
|
|
157
|
+
promise.reject("INVALID_ACTION", "Invalid or unsupported event action: $eventAction")
|
|
158
|
+
return
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
val metaMap: Map<String, Any>? = metadata?.toSafeMetadataMap { msg ->
|
|
162
|
+
Log.w("TappRN", msg)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
val tappEvent = RequestModels.TappEvent(
|
|
166
|
+
eventName = action,
|
|
167
|
+
metadata = metaMap
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
tapp.handleTappEvent(tappEvent)
|
|
171
|
+
promise.resolve("Tapp event handled successfully: $eventAction")
|
|
172
|
+
|
|
173
|
+
} catch (e: Exception) {
|
|
174
|
+
promise.reject("HANDLE_EVENT_ERROR", e.message ?: "An unexpected error occurred", e)
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private fun ReadableMap.toSafeMetadataMap(
|
|
179
|
+
onDrop: (String) -> Unit
|
|
180
|
+
): Map<String, Any> {
|
|
181
|
+
val out = LinkedHashMap<String, Any>()
|
|
182
|
+
val iterator = keySetIterator()
|
|
183
|
+
|
|
184
|
+
while (iterator.hasNextKey()) {
|
|
185
|
+
val key = iterator.nextKey()
|
|
186
|
+
when (getType(key)) {
|
|
187
|
+
ReadableType.String -> out[key] = getString(key).orEmpty()
|
|
188
|
+
ReadableType.Boolean -> out[key] = getBoolean(key)
|
|
189
|
+
ReadableType.Number -> {
|
|
190
|
+
// RN exposes numbers as Double; keep as Double (still a Number)
|
|
191
|
+
val n = getDouble(key)
|
|
192
|
+
// JSON safety: reject NaN/Infinity
|
|
193
|
+
if (n.isFinite()) out[key] = n
|
|
194
|
+
else onDrop("Dropping metadata '$key' because value is not finite: $n")
|
|
195
|
+
}
|
|
196
|
+
ReadableType.Null -> {
|
|
197
|
+
// Skip nulls (or decide to keep nulls if your serializer supports it)
|
|
198
|
+
onDrop("Dropping metadata '$key' because value is null")
|
|
199
|
+
}
|
|
200
|
+
ReadableType.Map, ReadableType.Array -> {
|
|
201
|
+
// Not allowed by your native contract
|
|
202
|
+
onDrop("Dropping metadata '$key' because nested ${getType(key)} is not supported")
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return out
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@ReactMethod
|
|
212
|
+
fun fetchLinkData(deepLink: String?, promise: Promise?) {
|
|
213
|
+
if (!::tapp.isInitialized) {
|
|
214
|
+
tapp = Tapp(reactApplicationContext)
|
|
215
|
+
}
|
|
216
|
+
CoroutineScope(Dispatchers.IO).launch {
|
|
217
|
+
try {
|
|
218
|
+
val response = tapp.fetchLinkData(deepLink ?: "")
|
|
219
|
+
if (response != null) {
|
|
220
|
+
val map: WritableMap = Arguments.createMap().apply {
|
|
221
|
+
putBoolean("error", response.error)
|
|
222
|
+
putString("message", response.message)
|
|
223
|
+
putString("tappUrl", response.tappUrl)
|
|
224
|
+
putString("attrTappUrl", response.attrTappUrl)
|
|
225
|
+
putString("influencer", response.influencer)
|
|
226
|
+
putBoolean("isFirstSession", response.isFirstSession ?: false)
|
|
227
|
+
putString("deepLink", response.deepLink)
|
|
228
|
+
val dataMap: WritableMap = Arguments.createMap()
|
|
229
|
+
response.data?.forEach { (key, value) ->
|
|
230
|
+
dataMap.putString(key, value)
|
|
231
|
+
}
|
|
232
|
+
putMap("data", dataMap)
|
|
233
|
+
}
|
|
234
|
+
withContext(Dispatchers.Main) {
|
|
235
|
+
promise?.resolve(map)
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
238
|
+
withContext(Dispatchers.Main) {
|
|
239
|
+
promise?.reject("NO_RESPONSE", "No link data response")
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
} catch (e: Exception) {
|
|
243
|
+
withContext(Dispatchers.Main) {
|
|
244
|
+
promise?.reject("FETCH_LINK_DATA_ERROR", e.message ?: "An unexpected error occurred")
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
@ReactMethod
|
|
251
|
+
fun shouldProcess(deepLink: String?, promise: Promise?) {
|
|
252
|
+
if (!::tapp.isInitialized) {
|
|
253
|
+
tapp = Tapp(reactApplicationContext)
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
val process = tapp.shouldProcess(deepLink)
|
|
257
|
+
Logger.logInfo("shouldProcess run for deepLink: $deepLink with process $process")
|
|
258
|
+
promise?.resolve(process)
|
|
259
|
+
} catch (e: Exception) {
|
|
260
|
+
Logger.logError("SHOULD_PROCESS_ERROR ${e.message ?: "An unexpected error occurred"}")
|
|
261
|
+
promise?.resolve(false)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
@ReactMethod
|
|
266
|
+
fun fetchOriginLinkData(promise: Promise?) {
|
|
267
|
+
if (!::tapp.isInitialized) {
|
|
268
|
+
tapp = Tapp(reactApplicationContext)
|
|
269
|
+
}
|
|
270
|
+
CoroutineScope(Dispatchers.IO).launch {
|
|
271
|
+
try {
|
|
272
|
+
val response = tapp.fetchOriginalLinkData()
|
|
273
|
+
if (response != null) {
|
|
274
|
+
val resultMap = convertResponseToMap(response)
|
|
275
|
+
withContext(Dispatchers.Main) {
|
|
276
|
+
promise?.resolve(resultMap)
|
|
277
|
+
}
|
|
278
|
+
} else {
|
|
279
|
+
withContext(Dispatchers.Main) {
|
|
280
|
+
promise?.reject("NO_DATA", "No link data returned")
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
} catch (e: Exception) {
|
|
284
|
+
withContext(Dispatchers.Main) {
|
|
285
|
+
promise?.reject("FETCH_ORIGINAL_LINK_DATA_ERROR", e.message ?: "An unexpected error occurred", e)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@ReactMethod
|
|
292
|
+
fun simulateTestEvent() {
|
|
293
|
+
tapp.simulateTestEvent()
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
private fun didFailResolvingURL(response: RequestModels.FailResolvingUrlResponse) {
|
|
297
|
+
val map: WritableMap = Arguments.createMap().apply {
|
|
298
|
+
putString("url", response.url)
|
|
299
|
+
putString("error", response.error.ifEmpty { "" })
|
|
300
|
+
}
|
|
301
|
+
reactApplicationContext
|
|
302
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
303
|
+
.emit("onDidFailResolvingURL", map)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
// --- helper methods for emitting deferred link events ---
|
|
309
|
+
//TODO::ADD LINK DATA ON RETURN
|
|
310
|
+
private fun sendDeferredLinkEvent(response: RequestModels.TappLinkDataResponse) {
|
|
311
|
+
val map: WritableMap = Arguments.createMap().apply {
|
|
312
|
+
putBoolean("error", response.error)
|
|
313
|
+
putString("message", response.message)
|
|
314
|
+
putString("tappUrl", response.tappUrl)
|
|
315
|
+
putString("attrTappUrl", response.attrTappUrl)
|
|
316
|
+
putString("influencer", response.influencer)
|
|
317
|
+
putBoolean("isFirstSession", response.isFirstSession ?: false)
|
|
318
|
+
putString("deepLink", response.deepLink ?: "")
|
|
319
|
+
val dataMap: WritableMap = Arguments.createMap()
|
|
320
|
+
response.data?.forEach { (key, value) ->
|
|
321
|
+
dataMap.putString(key, value)
|
|
322
|
+
}
|
|
323
|
+
putMap("data", dataMap)
|
|
324
|
+
}
|
|
325
|
+
reactApplicationContext
|
|
326
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
327
|
+
.emit("onDeferredLinkReceived", map)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private fun sendTestEvent(test: String) {
|
|
331
|
+
val map: WritableMap = Arguments.createMap().apply {
|
|
332
|
+
putString("test", test)
|
|
333
|
+
}
|
|
334
|
+
reactApplicationContext
|
|
335
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
336
|
+
.emit("onTestListener", map)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private fun convertResponseToMap(response: RequestModels.TappLinkDataResponse): WritableMap {
|
|
340
|
+
val map = Arguments.createMap()
|
|
341
|
+
map.putBoolean("error", response.error)
|
|
342
|
+
map.putString("message", response.message)
|
|
343
|
+
map.putString("tappUrl", response.tappUrl)
|
|
344
|
+
map.putString("attrTappUrl", response.attrTappUrl)
|
|
345
|
+
map.putString("influencer", response.influencer)
|
|
346
|
+
map.putBoolean("isFirstSession", response.isFirstSession ?: false)
|
|
347
|
+
val dataMap = Arguments.createMap()
|
|
348
|
+
response.data?.forEach { (key, value) ->
|
|
349
|
+
dataMap.putString(key, value)
|
|
350
|
+
}
|
|
351
|
+
map.putMap("data", dataMap)
|
|
352
|
+
return map
|
|
353
|
+
}
|
|
354
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
package com.comtappsosdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.ReactPackage
|
|
5
|
+
import com.facebook.react.bridge.NativeModule
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
8
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
9
|
+
import java.util.HashMap
|
|
10
|
+
import com.facebook.react.uimanager.ViewManager
|
|
11
|
+
|
|
12
|
+
class ComTappSoSdkPackage : ReactPackage {
|
|
13
|
+
|
|
14
|
+
private val isTurbo: Boolean
|
|
15
|
+
get() = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
|
16
|
+
|
|
17
|
+
// Legacy: create a list of native modules
|
|
18
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
19
|
+
return listOf(ComTappSoSdkModule(reactContext))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// If you don’t have any custom view managers, return an empty list
|
|
23
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
24
|
+
return emptyList()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
// (Optional) For TurboModules support in newer RN versions
|
|
29
|
+
fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
30
|
+
return ReactModuleInfoProvider {
|
|
31
|
+
val moduleInfos = HashMap<String, ReactModuleInfo>()
|
|
32
|
+
moduleInfos[ComTappSoSdkModule.NAME] = ReactModuleInfo(
|
|
33
|
+
ComTappSoSdkModule.NAME,
|
|
34
|
+
ComTappSoSdkModule.NAME,
|
|
35
|
+
false,
|
|
36
|
+
false,
|
|
37
|
+
true,
|
|
38
|
+
false,
|
|
39
|
+
isTurbo // This flag can control TurboModules
|
|
40
|
+
)
|
|
41
|
+
moduleInfos
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
//#import <ComTappSoSdkSpec/ComTappSoSdkSpec.h>
|
|
2
|
+
#import <React/RCTBridgeModule.h>
|
|
3
|
+
#import <React/RCTEventEmitter.h>
|
|
4
|
+
|
|
5
|
+
#import <Tapp/Tapp-Swift.h>
|
|
6
|
+
#import <Tapp/Tapp-umbrella.h>
|
|
7
|
+
|
|
8
|
+
#import <TappNetworking/TappNetworking-Swift.h>
|
|
9
|
+
#import <TappNetworking/Tapp-Networking-umbrella.h>
|
|
10
|
+
|
|
11
|
+
//
|
|
12
|
+
// Legacy definitions for RN versions before the new architecture.
|
|
13
|
+
// These legacy types are only needed when RCT_NEW_ARCH_ENABLED is NOT defined.
|
|
14
|
+
// We also guard the declarations so they’re only declared once.
|
|
15
|
+
//
|
|
16
|
+
#if !defined(RCT_NEW_ARCH_ENABLED)
|
|
17
|
+
#ifndef COMTAPPSOSDK_LEGACY_TYPES
|
|
18
|
+
#define COMTAPPSOSDK_LEGACY_TYPES
|
|
19
|
+
|
|
20
|
+
#import <functional>
|
|
21
|
+
namespace facebook {
|
|
22
|
+
namespace react {
|
|
23
|
+
// Define the callback type that accepts an event name as std::string and a payload.
|
|
24
|
+
using EventEmitterCallback = std::function<void(const std::string&, NSDictionary*)>;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Rename the wrapper class to avoid conflicts:
|
|
29
|
+
@interface CTEventEmitterCallbackWrapper : NSObject
|
|
30
|
+
@property (nonatomic, copy) void (^eventEmitterCallback)(NSString *eventName, NSDictionary *payload);
|
|
31
|
+
@end
|
|
32
|
+
|
|
33
|
+
// Inline helper function to convert an Objective-C block to a std::function.
|
|
34
|
+
static inline facebook::react::EventEmitterCallback CTConvertBlockToStdFunction(void (^block)(NSString *, NSDictionary *)) {
|
|
35
|
+
if (!block) return nullptr;
|
|
36
|
+
// Copy the block so it lives long enough.
|
|
37
|
+
void (^copiedBlock)(NSString *, NSDictionary *) = [block copy];
|
|
38
|
+
return [=](const std::string &eventName, NSDictionary *payload) {
|
|
39
|
+
NSString *nsEventName = [NSString stringWithUTF8String:eventName.c_str()];
|
|
40
|
+
copiedBlock(nsEventName, payload);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#endif // COMTAPPSO_LEGACY_TYPES
|
|
45
|
+
#endif // !RCT_NEW_ARCH_ENABLED
|
|
46
|
+
|
|
47
|
+
//
|
|
48
|
+
// For new architecture builds, import the generated Codegen header:
|
|
49
|
+
#if defined(RCT_NEW_ARCH_ENABLED)
|
|
50
|
+
#import "generated/ComTappSoSdkSpec/ComTappSoSdkSpec.h"
|
|
51
|
+
#endif
|
|
52
|
+
|
|
53
|
+
//
|
|
54
|
+
// Declare the main interface. For new architecture, adopt <NativeComTappSoSdkSpec, TappDelegate, RCTTurboModule>,
|
|
55
|
+
// and for legacy, adopt <RCTBridgeModule, TappDelegate>.
|
|
56
|
+
#if defined(RCT_NEW_ARCH_ENABLED)
|
|
57
|
+
@interface ComTappSoSdk : RCTEventEmitter <NativeComTappSoSdkSpec, TappDelegate, RCTTurboModule>
|
|
58
|
+
#else
|
|
59
|
+
@interface ComTappSoSdk : RCTEventEmitter <RCTBridgeModule, TappDelegate>
|
|
60
|
+
#endif
|
|
61
|
+
|
|
62
|
+
@end
|