rn-linkrunner 1.1.2 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LinkrunnerSDK.podspec +23 -0
- package/README.md +10 -297
- package/android/build.gradle +148 -0
- package/android/gradle.properties +52 -0
- package/android/settings.gradle +6 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/io/linkrunner/LinkrunnerModule.kt +400 -0
- package/android/src/main/java/io/linkrunner/LinkrunnerPackage.kt +16 -0
- package/android/src/main/java/io/linkrunner/utils/MapUtils.kt +136 -0
- package/android/src/main/java/io/linkrunner/utils/ModelConverter.kt +226 -0
- package/ios/LinkrunnerSDK.h +5 -0
- package/ios/LinkrunnerSDK.m +31 -0
- package/ios/LinkrunnerSDK.swift +218 -0
- package/ios/Podfile +19 -0
- package/lib/commonjs/index.js +134 -271
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/index.js +134 -272
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/index.d.ts +8 -21
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +18 -14
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/react-native.config.js +18 -0
- package/src/index.ts +151 -337
- package/src/types.ts +19 -14
- package/lib/commonjs/helper.js +0 -147
- package/lib/commonjs/helper.js.map +0 -1
- package/lib/module/helper.js +0 -135
- package/lib/module/helper.js.map +0 -1
- package/lib/typescript/helper.d.ts +0 -6
- package/lib/typescript/helper.d.ts.map +0 -1
- package/src/helper.ts +0 -173
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
package io.linkrunner.utils
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
import com.facebook.react.bridge.WritableMap
|
|
6
|
+
import io.linkrunner.sdk.models.PaymentStatus
|
|
7
|
+
import io.linkrunner.sdk.models.PaymentType
|
|
8
|
+
import io.linkrunner.sdk.models.request.CapturePaymentRequest
|
|
9
|
+
import io.linkrunner.sdk.models.request.RemovePaymentRequest
|
|
10
|
+
import io.linkrunner.sdk.models.request.UserDataRequest
|
|
11
|
+
import io.linkrunner.sdk.models.IntegrationData
|
|
12
|
+
import io.linkrunner.sdk.models.response.AttributionData
|
|
13
|
+
import io.linkrunner.sdk.models.response.ClientCampaignData
|
|
14
|
+
import io.linkrunner.sdk.models.response.GeneralResponse
|
|
15
|
+
import io.linkrunner.sdk.models.response.IPLocationData
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Utility class to convert React Native ReadableMap objects to Kotlin model objects and vice versa
|
|
19
|
+
*/
|
|
20
|
+
object ModelConverter {
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Convert GeneralResponse to WritableMap
|
|
24
|
+
*/
|
|
25
|
+
fun fromGeneralResponse(response: GeneralResponse?): WritableMap? {
|
|
26
|
+
if (response == null) {
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
val map = Arguments.createMap()
|
|
31
|
+
|
|
32
|
+
// Add IP location data if available
|
|
33
|
+
response.ipLocationData?.let { ipData ->
|
|
34
|
+
map.putMap("ip_location_data", fromIPLocationData(ipData))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Add deeplink if available
|
|
38
|
+
response.deeplink?.let { deeplink ->
|
|
39
|
+
map.putString("deeplink", deeplink)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Add root domain if available
|
|
43
|
+
response.rootDomain?.let { rootDomain ->
|
|
44
|
+
map.putBoolean("root_domain", rootDomain)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return map
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Convert ClientCampaignData to WritableMap
|
|
52
|
+
*/
|
|
53
|
+
fun fromClientCampaignData(data: ClientCampaignData?): WritableMap? {
|
|
54
|
+
if (data == null) {
|
|
55
|
+
return null
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
val map = Arguments.createMap()
|
|
59
|
+
|
|
60
|
+
// Add required fields
|
|
61
|
+
map.putString("id", data.id)
|
|
62
|
+
map.putString("name", data.name)
|
|
63
|
+
map.putString("type", data.type)
|
|
64
|
+
|
|
65
|
+
// Add optional fields if available
|
|
66
|
+
data.adNetwork?.let { adNetwork ->
|
|
67
|
+
map.putString("adNetwork", adNetwork)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
data.groupName?.let { groupName ->
|
|
71
|
+
map.putString("groupName", groupName)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
data.assetGroupName?.let { assetGroupName ->
|
|
75
|
+
map.putString("assetGroupName", assetGroupName)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
data.assetName?.let { assetName ->
|
|
79
|
+
map.putString("assetName", assetName)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return map
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Convert IPLocationData to WritableMap
|
|
87
|
+
*/
|
|
88
|
+
fun fromIPLocationData(data: IPLocationData?): WritableMap? {
|
|
89
|
+
if (data == null) {
|
|
90
|
+
return null
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
val map = Arguments.createMap()
|
|
94
|
+
|
|
95
|
+
// Add all fields if available
|
|
96
|
+
data.ip?.let { ip ->
|
|
97
|
+
map.putString("ip", ip)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
data.city?.let { city ->
|
|
101
|
+
map.putString("city", city)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
data.countryLong?.let { countryLong ->
|
|
105
|
+
map.putString("countryLong", countryLong)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
data.countryShort?.let { countryShort ->
|
|
109
|
+
map.putString("countryShort", countryShort)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
data.latitude?.let { latitude ->
|
|
113
|
+
map.putDouble("latitude", latitude)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
data.longitude?.let { longitude ->
|
|
117
|
+
map.putDouble("longitude", longitude)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
data.region?.let { region ->
|
|
121
|
+
map.putString("region", region)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
data.timeZone?.let { timeZone ->
|
|
125
|
+
map.putString("timeZone", timeZone)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
data.zipCode?.let { zipCode ->
|
|
129
|
+
map.putString("zipCode", zipCode)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return map
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Convert AttributionData to WritableMap
|
|
137
|
+
*/
|
|
138
|
+
fun fromAttributionData(data: AttributionData?): WritableMap {
|
|
139
|
+
val map = Arguments.createMap()
|
|
140
|
+
|
|
141
|
+
if (data != null) {
|
|
142
|
+
// Add the deeplink if it exists
|
|
143
|
+
data.deeplink?.let { deeplink ->
|
|
144
|
+
map.putString("deeplink", deeplink)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Convert campaign data to a WritableMap if it exists
|
|
148
|
+
data.campaignData?.let { campaignData ->
|
|
149
|
+
val campaignDataMap = Arguments.createMap()
|
|
150
|
+
campaignDataMap.putString("id", campaignData.id)
|
|
151
|
+
campaignDataMap.putString("name", campaignData.name)
|
|
152
|
+
|
|
153
|
+
campaignData.adNetwork?.let { adNetwork ->
|
|
154
|
+
campaignDataMap.putString("adNetwork", adNetwork)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
campaignDataMap.putString("type", campaignData.type)
|
|
158
|
+
campaignDataMap.putString("installedAt", campaignData.installedAt)
|
|
159
|
+
|
|
160
|
+
campaignData.storeClickAt?.let { storeClickAt ->
|
|
161
|
+
campaignDataMap.putString("storeClickAt", storeClickAt)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
campaignDataMap.putString("groupName", campaignData.groupName)
|
|
165
|
+
campaignDataMap.putString("assetName", campaignData.assetName)
|
|
166
|
+
campaignDataMap.putString("assetGroupName", campaignData.assetGroupName)
|
|
167
|
+
|
|
168
|
+
map.putMap("campaignData", campaignDataMap)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return map
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Convert a ReadableMap to UserDataRequest
|
|
177
|
+
*/
|
|
178
|
+
fun toUserDataRequest(map: Map<String, Any>): UserDataRequest {
|
|
179
|
+
return UserDataRequest(
|
|
180
|
+
id = map["id"] as? String ?: "",
|
|
181
|
+
name = map["name"] as? String,
|
|
182
|
+
phone = map["phone"] as? String,
|
|
183
|
+
email = map["email"] as? String,
|
|
184
|
+
mixpanelDistinctId = map["mixpanel_distinct_id"] as? String,
|
|
185
|
+
amplitudeDeviceId = map["amplitude_device_id"] as? String,
|
|
186
|
+
posthogDistinctId = map["posthog_distinct_id"] as? String,
|
|
187
|
+
userCreatedAt = map["user_created_at"] as? String,
|
|
188
|
+
isFirstTimeUser = map["is_first_time_user"] as? Boolean
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Convert a Map to IntegrationData
|
|
194
|
+
*/
|
|
195
|
+
fun toIntegrationData(map: Map<String, Any>): IntegrationData {
|
|
196
|
+
return IntegrationData(
|
|
197
|
+
clevertapId = map["clevertapId"] as? String
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Convert a ReadableMap to CapturePaymentRequest
|
|
203
|
+
*/
|
|
204
|
+
fun toCapturePaymentRequest(map: Map<String, Any>): CapturePaymentRequest {
|
|
205
|
+
val typeString = map["type"] as? String ?: "DEFAULT"
|
|
206
|
+
val statusString = map["status"] as? String ?: "PAYMENT_COMPLETED"
|
|
207
|
+
|
|
208
|
+
return CapturePaymentRequest(
|
|
209
|
+
paymentId = map["paymentId"] as? String ?: "",
|
|
210
|
+
userId = map["userId"] as? String ?: "",
|
|
211
|
+
amount = (map["amount"] as? Number)?.toDouble() ?: 0.0,
|
|
212
|
+
type = PaymentType.valueOf(typeString),
|
|
213
|
+
status = PaymentStatus.valueOf(statusString)
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Convert a ReadableMap to RemovePaymentRequest
|
|
219
|
+
*/
|
|
220
|
+
fun toRemovePaymentRequest(map: Map<String, Any>): RemovePaymentRequest {
|
|
221
|
+
return RemovePaymentRequest(
|
|
222
|
+
paymentId = map["paymentId"] as? String ?: "",
|
|
223
|
+
userId = map["userId"] as? String ?: ""
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#import "React/RCTBridgeModule.h"
|
|
2
|
+
|
|
3
|
+
// first parameter is the name of the native module
|
|
4
|
+
// second parameter is the name of the native class that implements the module
|
|
5
|
+
@interface RCT_EXTERN_REMAP_MODULE(LinkrunnerSDK, LinkrunnerSDK, NSObject)
|
|
6
|
+
|
|
7
|
+
RCT_EXTERN_METHOD(initializeSDK:(NSDictionary *)dict)
|
|
8
|
+
|
|
9
|
+
RCT_EXTERN_METHOD(signup:(NSDictionary *)userData
|
|
10
|
+
data:(NSDictionary *)data)
|
|
11
|
+
|
|
12
|
+
RCT_EXTERN_METHOD(setUserData:(NSDictionary *)userData)
|
|
13
|
+
|
|
14
|
+
RCT_EXTERN_METHOD(trackEvent:(NSString *)eventName eventData:(NSDictionary *)eventData)
|
|
15
|
+
|
|
16
|
+
RCT_EXTERN_METHOD(capturePayment:(NSDictionary *)paymentData)
|
|
17
|
+
|
|
18
|
+
RCT_EXTERN_METHOD(removePayment:(NSDictionary *)paymentData)
|
|
19
|
+
|
|
20
|
+
RCT_EXTERN_METHOD(enablePIIHashing:(BOOL)enabled)
|
|
21
|
+
|
|
22
|
+
RCT_EXTERN_METHOD(requestTrackingAuthorization)
|
|
23
|
+
|
|
24
|
+
RCT_EXTERN_METHOD(getAttributionData:(RCTPromiseResolveBlock)resolve
|
|
25
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
26
|
+
|
|
27
|
+
RCT_EXTERN_METHOD(setAdditionalData:(NSDictionary *)integrationDataDict
|
|
28
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
29
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
30
|
+
|
|
31
|
+
@end
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import LinkrunnerKit;
|
|
3
|
+
import React
|
|
4
|
+
|
|
5
|
+
@objc(LinkrunnerSDK)
|
|
6
|
+
class LinkrunnerSDK: NSObject {
|
|
7
|
+
|
|
8
|
+
private var linkrunnerSDK: LinkrunnerKit.LinkrunnerSDK!
|
|
9
|
+
|
|
10
|
+
override init() {
|
|
11
|
+
linkrunnerSDK = LinkrunnerKit.LinkrunnerSDK.shared
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
// MARK: - Native SDK Method Wrappers
|
|
16
|
+
|
|
17
|
+
@objc func initializeSDK(_ dict: NSDictionary) -> Void {
|
|
18
|
+
guard let token = dict["token"] as? String else {
|
|
19
|
+
print("Linkrunner: token is required")
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let secretKey = dict["secretKey"] as? String
|
|
24
|
+
let keyId = dict["keyId"] as? String
|
|
25
|
+
let debug = dict["debug"] as? Bool ?? false
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
Task {
|
|
29
|
+
do {
|
|
30
|
+
try await linkrunnerSDK.initialize(token: token, secretKey: secretKey, keyId: keyId, debug: debug)
|
|
31
|
+
print("Linkrunner: SDK initialized successfully")
|
|
32
|
+
} catch {
|
|
33
|
+
print("Linkrunner: Failed to initialize SDK: \(error)")
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@objc func signup(_ userData: NSDictionary, data: NSDictionary? = nil) -> Void {
|
|
39
|
+
guard let id = userData["id"] as? String else {
|
|
40
|
+
print("Linkrunner: User ID is required")
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let userDataObj = UserData(
|
|
45
|
+
id: id,
|
|
46
|
+
name: userData["name"] as? String,
|
|
47
|
+
phone: userData["phone"] as? String,
|
|
48
|
+
email: userData["email"] as? String,
|
|
49
|
+
isFirstTimeUser: userData["is_first_time_user"] as? Bool,
|
|
50
|
+
userCreatedAt: userData["user_created_at"] as? String,
|
|
51
|
+
mixPanelDistinctId: userData["mixpanel_distinct_id"] as? String,
|
|
52
|
+
amplitudeDeviceId: userData["amplitude_device_id"] as? String,
|
|
53
|
+
posthogDistinctId: userData["posthog_distinct_id"] as? String
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
Task {
|
|
57
|
+
do {
|
|
58
|
+
if #available(iOS 15.0, *) {
|
|
59
|
+
try await linkrunnerSDK.signup(
|
|
60
|
+
userData: userDataObj,
|
|
61
|
+
additionalData: data as? [String: Any]
|
|
62
|
+
)
|
|
63
|
+
return
|
|
64
|
+
} else {
|
|
65
|
+
print("UNSUPPORTED_VERSION: iOS 15.0 or later is required")
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
print("SIGNUP_ERROR", "Failed to complete signup: \(error.localizedDescription)", error)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@objc func setUserData(_ userData: NSDictionary) -> Void {
|
|
74
|
+
guard let id = userData["id"] as? String else {
|
|
75
|
+
print("Linkrunner: User ID is required")
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let userDataObj = UserData(
|
|
80
|
+
id: id,
|
|
81
|
+
name: userData["name"] as? String,
|
|
82
|
+
phone: userData["phone"] as? String,
|
|
83
|
+
email: userData["email"] as? String,
|
|
84
|
+
isFirstTimeUser: userData["is_first_time_user"] as? Bool,
|
|
85
|
+
userCreatedAt: userData["user_created_at"] as? String,
|
|
86
|
+
mixPanelDistinctId: userData["mixpanel_distinct_id"] as? String,
|
|
87
|
+
amplitudeDeviceId: userData["amplitude_device_id"] as? String,
|
|
88
|
+
posthogDistinctId: userData["posthog_distinct_id"] as? String
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
Task {
|
|
92
|
+
do {
|
|
93
|
+
try await linkrunnerSDK.setUserData(userDataObj)
|
|
94
|
+
print("Linkrunner: User data set successfully")
|
|
95
|
+
} catch {
|
|
96
|
+
print("Linkrunner: Failed to set user data: \(error)")
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@objc func trackEvent(_ eventName: NSString, eventData: NSDictionary?) -> Void {
|
|
102
|
+
Task {
|
|
103
|
+
do {
|
|
104
|
+
try await linkrunnerSDK.trackEvent(eventName: eventName as String, eventData: eventData as? [String: Any])
|
|
105
|
+
print("Linkrunner: Event tracked successfully")
|
|
106
|
+
} catch {
|
|
107
|
+
print("Linkrunner: Failed to track event: \(error)")
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@objc func capturePayment(_ paymentData: NSDictionary) -> Void {
|
|
113
|
+
guard let userId = paymentData["userId"] as? String,
|
|
114
|
+
let amount = paymentData["amount"] as? Double else {
|
|
115
|
+
print("Linkrunner: userId and amount are required for payment capture")
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let paymentId = paymentData["paymentId"] as? String
|
|
120
|
+
let typeString = paymentData["type"] as? String ?? "DEFAULT"
|
|
121
|
+
let statusString = paymentData["status"] as? String ?? "PAYMENT_COMPLETED"
|
|
122
|
+
|
|
123
|
+
// Convert strings to enums
|
|
124
|
+
let paymentType = PaymentType(rawValue: typeString) ?? .default
|
|
125
|
+
let paymentStatus = PaymentStatus(rawValue: statusString) ?? .completed
|
|
126
|
+
|
|
127
|
+
Task {
|
|
128
|
+
do {
|
|
129
|
+
try await linkrunnerSDK.capturePayment(
|
|
130
|
+
amount: amount,
|
|
131
|
+
userId: userId,
|
|
132
|
+
paymentId: paymentId,
|
|
133
|
+
type: paymentType,
|
|
134
|
+
status: paymentStatus
|
|
135
|
+
)
|
|
136
|
+
print("Linkrunner: Payment captured successfully")
|
|
137
|
+
} catch {
|
|
138
|
+
print("Linkrunner: Failed to capture payment: \(error)")
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@objc func removePayment(_ paymentData: NSDictionary) -> Void {
|
|
144
|
+
guard let userId = paymentData["userId"] as? String else {
|
|
145
|
+
print("Linkrunner: userId is required for payment removal")
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let paymentId = paymentData["paymentId"] as? String
|
|
150
|
+
|
|
151
|
+
Task {
|
|
152
|
+
do {
|
|
153
|
+
try await linkrunnerSDK.removePayment(userId: userId, paymentId: paymentId)
|
|
154
|
+
print("Linkrunner: Payment removed successfully")
|
|
155
|
+
} catch {
|
|
156
|
+
print("Linkrunner: Failed to remove payment: \(error)")
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@objc func enablePIIHashing(_ enabled: Bool) -> Void {
|
|
162
|
+
Task {
|
|
163
|
+
await linkrunnerSDK.enablePIIHashing(enabled)
|
|
164
|
+
print("Linkrunner: PII hashing \(enabled ? "enabled" : "disabled")")
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@objc func requestTrackingAuthorization() -> Void {
|
|
169
|
+
linkrunnerSDK.requestTrackingAuthorization { status in
|
|
170
|
+
print("Linkrunner: Tracking authorization status: \(status.rawValue)")
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@objc func getAttributionData(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
175
|
+
Task {
|
|
176
|
+
do {
|
|
177
|
+
let attributionData = try await linkrunnerSDK.getAttributionData()
|
|
178
|
+
resolve(attributionData.toDictionary())
|
|
179
|
+
} catch {
|
|
180
|
+
reject("ATTRIBUTION_ERROR", "Failed to get attribution data: \(error.localizedDescription)", error)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@objc func setAdditionalData(_ integrationDataDict: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) -> Void {
|
|
186
|
+
if integrationDataDict.count == 0 {
|
|
187
|
+
reject("ADDITIONAL_DATA_ERROR", "Integration data is required", NSError(domain: "LinkrunnerSDK", code: 1, userInfo: nil))
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
let clevertapId = integrationDataDict["clevertapId"] as? String
|
|
192
|
+
|
|
193
|
+
let integrationData = IntegrationData(clevertapId: clevertapId)
|
|
194
|
+
|
|
195
|
+
Task {
|
|
196
|
+
do {
|
|
197
|
+
if #available(iOS 15.0, *) {
|
|
198
|
+
try await linkrunnerSDK.setAdditionalData(integrationData)
|
|
199
|
+
|
|
200
|
+
let response: [String: Any] = [
|
|
201
|
+
"status": "success",
|
|
202
|
+
"message": "Additional data set successfully"
|
|
203
|
+
]
|
|
204
|
+
resolve(response)
|
|
205
|
+
} else {
|
|
206
|
+
reject("UNSUPPORTED_VERSION", "iOS 15.0 or later is required", NSError(domain: "LinkrunnerSDK", code: 2, userInfo: nil))
|
|
207
|
+
}
|
|
208
|
+
} catch {
|
|
209
|
+
reject("ADDITIONAL_DATA_ERROR", "Failed to set additional data: \(error.localizedDescription)", error)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Type definition needed for RCTPromiseResolveBlock
|
|
217
|
+
typealias RCTPromiseResolveBlock = (Any?) -> Void
|
|
218
|
+
typealias RCTPromiseRejectBlock = (String, String?, Error?) -> Void
|
package/ios/Podfile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Define the global platform for your project
|
|
2
|
+
platform :ios, '15.0'
|
|
3
|
+
|
|
4
|
+
# Specify that this is a library, not an application
|
|
5
|
+
install! 'cocoapods', :deterministic_uuids => false
|
|
6
|
+
|
|
7
|
+
# This is needed since there's no Xcode project yet
|
|
8
|
+
abstract_target 'LinkrunnerSDK' do
|
|
9
|
+
# Comment the next line if you don't want to use dynamic frameworks
|
|
10
|
+
use_frameworks!
|
|
11
|
+
|
|
12
|
+
# Pods for LinkrunnerSDK
|
|
13
|
+
|
|
14
|
+
# Add the linkrunner-ios-sdk dependency
|
|
15
|
+
pod 'LinkrunnerKit', '3.0.2'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Add any other dependencies your SDK needs here
|
|
19
|
+
end
|