react-native-sdk-pianoio 0.4.5 → 0.4.6
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.
|
@@ -273,19 +273,23 @@ class ComposerPianoImpl {
|
|
|
273
273
|
// MARK: - Configuration Methods (Setters)
|
|
274
274
|
|
|
275
275
|
fun addTag(tag: String) {
|
|
276
|
-
Log.d(TAG, "Adding tag: $tag")
|
|
276
|
+
Log.d(TAG, "[addTag] Adding tag: '$tag'")
|
|
277
277
|
if (!this.tags.contains(tag)) {
|
|
278
278
|
this.tags.add(tag)
|
|
279
|
+
Log.d(TAG, "[addTag] Tag added. Current tags: [${this.tags.joinToString(", ")}]")
|
|
280
|
+
} else {
|
|
281
|
+
Log.d(TAG, "[addTag] Tag already exists. Current tags: [${this.tags.joinToString(", ")}]")
|
|
279
282
|
}
|
|
280
283
|
}
|
|
281
284
|
|
|
282
285
|
fun addTags(tags: List<String>) {
|
|
283
|
-
Log.d(TAG, "Adding tags: $tags")
|
|
286
|
+
Log.d(TAG, "[addTags] Adding tags: [${tags.joinToString(", ")}]")
|
|
284
287
|
for (tag in tags) {
|
|
285
288
|
if (!this.tags.contains(tag)) {
|
|
286
289
|
this.tags.add(tag)
|
|
287
290
|
}
|
|
288
291
|
}
|
|
292
|
+
Log.d(TAG, "[addTags] Tags after addition: [${this.tags.joinToString(", ")}] (count: ${this.tags.size})")
|
|
289
293
|
}
|
|
290
294
|
|
|
291
295
|
fun setZoneId(zoneId: String) {
|
|
@@ -323,33 +327,36 @@ class ComposerPianoImpl {
|
|
|
323
327
|
// MARK: - Cleanup Methods
|
|
324
328
|
|
|
325
329
|
fun clearTags() {
|
|
326
|
-
Log.d(TAG, "Clearing tags")
|
|
330
|
+
Log.d(TAG, "[clearTags] Clearing all tags. Current tags before clear: [${this.tags.joinToString(", ")}] (count: ${this.tags.size})")
|
|
327
331
|
this.tags.clear()
|
|
332
|
+
Log.d(TAG, "[clearTags] Tags cleared. Current tags after clear: [${this.tags.joinToString(", ")}] (count: ${this.tags.size})")
|
|
328
333
|
}
|
|
329
334
|
|
|
330
335
|
fun clearCustomVariables() {
|
|
331
|
-
Log.d(TAG, "Clearing custom variables")
|
|
336
|
+
Log.d(TAG, "[clearCustomVariables] Clearing custom variables")
|
|
332
337
|
this.customVariables.clear()
|
|
333
338
|
}
|
|
334
339
|
|
|
335
340
|
fun removeTag(tag: String) {
|
|
336
|
-
Log.d(TAG, "Removing tag: $tag")
|
|
337
|
-
this.tags.remove(tag)
|
|
341
|
+
Log.d(TAG, "[removeTag] Removing tag: '$tag'. Tags before: [${this.tags.joinToString(", ")}]")
|
|
342
|
+
val removed = this.tags.remove(tag)
|
|
343
|
+
Log.d(TAG, "[removeTag] Tag removed: $removed. Tags after: [${this.tags.joinToString(", ")}]")
|
|
338
344
|
}
|
|
339
345
|
|
|
340
346
|
fun removeCustomVariable(key: String) {
|
|
341
|
-
Log.d(TAG, "Removing custom variable: $key")
|
|
347
|
+
Log.d(TAG, "[removeCustomVariable] Removing custom variable: $key")
|
|
342
348
|
this.customVariables.remove(key)
|
|
343
349
|
}
|
|
344
350
|
|
|
345
351
|
fun clearConfiguration() {
|
|
346
|
-
Log.d(TAG, "Clearing all configurations")
|
|
352
|
+
Log.d(TAG, "[clearConfiguration] Clearing all configurations")
|
|
347
353
|
this.clearTags()
|
|
348
354
|
this.clearCustomVariables()
|
|
349
355
|
this.zoneId = null
|
|
350
356
|
this.referrer = null
|
|
351
357
|
this.url = null
|
|
352
358
|
this.userToken = null
|
|
359
|
+
Log.d(TAG, "[clearConfiguration] All configurations cleared")
|
|
353
360
|
}
|
|
354
361
|
|
|
355
362
|
// MARK: - Execution Methods
|
|
@@ -361,13 +368,18 @@ class ComposerPianoImpl {
|
|
|
361
368
|
* @throws IllegalStateException if the composer has not been initialized.
|
|
362
369
|
*/
|
|
363
370
|
fun executeComposer(promise: Promise) {
|
|
371
|
+
Log.d(TAG, "")
|
|
372
|
+
Log.d(TAG, "=".repeat(80))
|
|
364
373
|
Log.d(TAG, "=== STARTING COMPOSER EXECUTION ===")
|
|
374
|
+
Log.d(TAG, "=".repeat(80))
|
|
365
375
|
Log.d(TAG, "Current configuration:")
|
|
366
376
|
Log.d(TAG, " - AID: ${ComposerPianoImpl.aid}")
|
|
367
|
-
Log.d(TAG, " - Tags: ${this.tags}")
|
|
368
|
-
Log.d(TAG, " -
|
|
369
|
-
Log.d(TAG, " -
|
|
370
|
-
Log.d(TAG, " -
|
|
377
|
+
Log.d(TAG, " - Tags count: ${this.tags.size}")
|
|
378
|
+
Log.d(TAG, " - Tags: [${this.tags.joinToString(", ")}]")
|
|
379
|
+
Log.d(TAG, " - Tags detail: ${this.tags}")
|
|
380
|
+
Log.d(TAG, " - Zone ID: ${this.zoneId ?: "(not set)"}")
|
|
381
|
+
Log.d(TAG, " - Referrer: ${this.referrer ?: "(not set)"}")
|
|
382
|
+
Log.d(TAG, " - URL: ${this.url ?: "(not set)"}")
|
|
371
383
|
Log.d(TAG, " - User Token: ${if (userToken != null) "Set" else "Not set"}")
|
|
372
384
|
Log.d(TAG, " - Custom Variables: ${this.customVariables}")
|
|
373
385
|
|
|
@@ -390,6 +402,13 @@ class ComposerPianoImpl {
|
|
|
390
402
|
customParams.request(key, value)
|
|
391
403
|
}
|
|
392
404
|
|
|
405
|
+
Log.d(TAG, "")
|
|
406
|
+
Log.d(TAG, ">>> BUILDING EXPERIENCE REQUEST <<<")
|
|
407
|
+
Log.d(TAG, ">>> Tags being passed to ExperienceRequest.Builder(): [${this.tags.joinToString(", ")}]")
|
|
408
|
+
Log.d(TAG, ">>> Tags count: ${this.tags.size}")
|
|
409
|
+
Log.d(TAG, ">>> ⚠️ IF TAGS APPEAR HERE AFTER clearTags(), THE BUG IS IN THE WRAPPER")
|
|
410
|
+
Log.d(TAG, ">>> ⚠️ IF TAGS APPEAR IN PIANO REQUEST BUT NOT HERE, THE BUG IS IN PIANO SDK")
|
|
411
|
+
|
|
393
412
|
val request =
|
|
394
413
|
ExperienceRequest.Builder()
|
|
395
414
|
.tags(this.tags)
|
|
@@ -399,7 +418,11 @@ class ComposerPianoImpl {
|
|
|
399
418
|
.customParams(customParams)
|
|
400
419
|
.debug(true) // Enable debug mode for more logging
|
|
401
420
|
.build()
|
|
402
|
-
Log.d(TAG, "ExperienceRequest created with debug mode ON")
|
|
421
|
+
Log.d(TAG, "✓ ExperienceRequest created with debug mode ON")
|
|
422
|
+
Log.d(TAG, "⚠️ NOTE: Piano Composer SDK does NOT provide getters to verify internal state")
|
|
423
|
+
Log.d(TAG, "⚠️ We can only verify OUR wrapper state, not Piano's singleton state")
|
|
424
|
+
Log.d(TAG, "⚠️ If bug exists, it's in Piano SDK's internal tag management")
|
|
425
|
+
Log.d(TAG, "=".repeat(80))
|
|
403
426
|
|
|
404
427
|
// Collect all events instead of resolving on first event
|
|
405
428
|
val collectedEvents = mutableListOf<WritableMap>()
|
|
@@ -2,6 +2,7 @@ import Foundation
|
|
|
2
2
|
import PianoComposer
|
|
3
3
|
import PianoOAuth
|
|
4
4
|
import React
|
|
5
|
+
import os.log
|
|
5
6
|
|
|
6
7
|
/// ComposerPianoImpl - Main implementation class for the Piano SDK on iOS.
|
|
7
8
|
@objcMembers public class ComposerPianoImpl: NSObject {
|
|
@@ -32,27 +33,27 @@ import React
|
|
|
32
33
|
* @throws Error if initialization fails
|
|
33
34
|
*/
|
|
34
35
|
public func initialize(aid: String, isSandbox: Bool) throws {
|
|
35
|
-
|
|
36
|
+
NSLog("[ComposerPianoImpl] Initializing with AID: \(aid), isSandbox: \(isSandbox)")
|
|
36
37
|
|
|
37
38
|
// Validate input parameter
|
|
38
39
|
guard !aid.isEmpty else {
|
|
39
|
-
|
|
40
|
+
NSLog("[ComposerPianoImpl] ERROR: AID cannot be empty")
|
|
40
41
|
throw NSError(domain: "PianoSDK", code: -1, userInfo: [NSLocalizedDescriptionKey: "AID cannot be empty"])
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
// Store the AID
|
|
44
45
|
self.aid = aid
|
|
45
|
-
|
|
46
|
+
NSLog("[ComposerPianoImpl] AID stored: \(aid)")
|
|
46
47
|
|
|
47
48
|
do {
|
|
48
49
|
// 1. Initialize and store the TokenService
|
|
49
50
|
self.tokenService = TokenService()
|
|
50
51
|
self.tokenService?.initialize(aid: aid, isSandbox: isSandbox)
|
|
51
|
-
|
|
52
|
+
NSLog("[ComposerPianoImpl] TokenService initialized with sandbox=\(isSandbox)")
|
|
52
53
|
|
|
53
54
|
// 2. Initialize the Composer instance
|
|
54
55
|
let endpoint = isSandbox ? PianoEndpoint.sandbox : PianoEndpoint.production
|
|
55
|
-
|
|
56
|
+
NSLog("[ComposerPianoImpl] Using endpoint: \(endpoint)")
|
|
56
57
|
self.composer = PianoComposer(aid: aid, endpoint: endpoint)
|
|
57
58
|
|
|
58
59
|
guard self.composer != nil else {
|
|
@@ -62,10 +63,10 @@ import React
|
|
|
62
63
|
// 3. Initialize and set up the delegate
|
|
63
64
|
self.delegate = MyComposerDelegate(impl: self)
|
|
64
65
|
self.composer?.delegate = self.delegate
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
NSLog("[ComposerPianoImpl] Delegate initialized and set")
|
|
67
|
+
NSLog("[ComposerPianoImpl] Initialization completed successfully")
|
|
67
68
|
} catch {
|
|
68
|
-
|
|
69
|
+
NSLog("[ComposerPianoImpl] Error during initialization: \(error.localizedDescription)")
|
|
69
70
|
throw error
|
|
70
71
|
}
|
|
71
72
|
}
|
|
@@ -103,42 +104,52 @@ import React
|
|
|
103
104
|
// MARK: - Configuration Methods (Setters)
|
|
104
105
|
|
|
105
106
|
public func addTag(_ tag: String) {
|
|
106
|
-
|
|
107
|
-
self.tags.
|
|
107
|
+
NSLog("[ComposerPianoImpl] [addTag] Adding tag: '\(tag)'")
|
|
108
|
+
if !self.tags.contains(tag) {
|
|
109
|
+
self.tags.append(tag)
|
|
110
|
+
NSLog("[ComposerPianoImpl] [addTag] Tag added. Current tags: [\(self.tags.joined(separator: ", "))]")
|
|
111
|
+
} else {
|
|
112
|
+
NSLog("[ComposerPianoImpl] [addTag] Tag already exists. Current tags: [\(self.tags.joined(separator: ", "))]")
|
|
113
|
+
}
|
|
108
114
|
}
|
|
109
115
|
|
|
110
116
|
public func addTags(_ tags: [String]) {
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
NSLog("[ComposerPianoImpl] [addTags] Adding tags: [\(tags.joined(separator: ", "))]")
|
|
118
|
+
for tag in tags {
|
|
119
|
+
if !self.tags.contains(tag) {
|
|
120
|
+
self.tags.append(tag)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
NSLog("[ComposerPianoImpl] [addTags] Tags after addition: [\(self.tags.joined(separator: ", "))] (count: \(self.tags.count))")
|
|
113
124
|
}
|
|
114
125
|
|
|
115
126
|
public func setZoneId(_ zoneId: String) {
|
|
116
|
-
|
|
127
|
+
NSLog("[ComposerPianoImpl] Setting zoneId: \(zoneId)")
|
|
117
128
|
self.zoneId = zoneId
|
|
118
129
|
}
|
|
119
130
|
|
|
120
131
|
public func setReferrer(_ referrer: String) {
|
|
121
|
-
|
|
132
|
+
NSLog("[ComposerPianoImpl] Setting referrer: \(referrer)")
|
|
122
133
|
self.referrer = referrer
|
|
123
134
|
}
|
|
124
135
|
|
|
125
136
|
public func setUrl(_ url: String) {
|
|
126
|
-
|
|
137
|
+
NSLog("[ComposerPianoImpl] Setting url: \(url)")
|
|
127
138
|
self.url = url
|
|
128
139
|
}
|
|
129
140
|
|
|
130
141
|
public func setCustomVariables(_ variables: [String: String]) {
|
|
131
|
-
|
|
142
|
+
NSLog("[ComposerPianoImpl] Setting custom variables")
|
|
132
143
|
self.customVariables = variables
|
|
133
144
|
}
|
|
134
145
|
|
|
135
146
|
public func addCustomVariable(_ name: String, value: String) {
|
|
136
|
-
|
|
147
|
+
NSLog("[ComposerPianoImpl] Adding custom variable: \(name) = \(value)")
|
|
137
148
|
self.customVariables[name] = value
|
|
138
149
|
}
|
|
139
150
|
|
|
140
151
|
public func setUserToken(_ token: String) {
|
|
141
|
-
|
|
152
|
+
NSLog("[ComposerPianoImpl] Setting userToken")
|
|
142
153
|
self.userToken = token
|
|
143
154
|
_ = self.composer?.userToken(token)
|
|
144
155
|
}
|
|
@@ -146,29 +157,36 @@ import React
|
|
|
146
157
|
// MARK: - Cleanup Methods
|
|
147
158
|
|
|
148
159
|
public func clearTags() {
|
|
160
|
+
NSLog("[ComposerPianoImpl] [clearTags] Clearing all tags. Current tags before clear: [\(self.tags.joined(separator: ", "))] (count: \(self.tags.count))")
|
|
149
161
|
self.tags.removeAll()
|
|
162
|
+
NSLog("[ComposerPianoImpl] [clearTags] Tags cleared. Current tags after clear: [\(self.tags.joined(separator: ", "))] (count: \(self.tags.count))")
|
|
150
163
|
}
|
|
151
164
|
|
|
152
165
|
public func clearCustomVariables() {
|
|
166
|
+
NSLog("[ComposerPianoImpl] [clearCustomVariables] Clearing custom variables")
|
|
153
167
|
self.customVariables.removeAll()
|
|
154
168
|
}
|
|
155
169
|
|
|
156
170
|
public func removeTag(_ tag: String) {
|
|
171
|
+
NSLog("[ComposerPianoImpl] [removeTag] Removing tag: '\(tag)'. Tags before: [\(self.tags.joined(separator: ", "))]")
|
|
157
172
|
self.tags.removeAll { $0 == tag }
|
|
173
|
+
NSLog("[ComposerPianoImpl] [removeTag] Tags after: [\(self.tags.joined(separator: ", "))]")
|
|
158
174
|
}
|
|
159
175
|
|
|
160
176
|
public func removeCustomVariable(key: String) {
|
|
177
|
+
NSLog("[ComposerPianoImpl] [removeCustomVariable] Removing custom variable: \(key)")
|
|
161
178
|
self.customVariables.removeValue(forKey: key)
|
|
162
179
|
}
|
|
163
180
|
|
|
164
181
|
public func clearConfiguration() {
|
|
165
|
-
|
|
182
|
+
NSLog("[ComposerPianoImpl] [clearConfiguration] Clearing all configurations")
|
|
166
183
|
self.clearTags()
|
|
167
184
|
self.clearCustomVariables()
|
|
168
185
|
self.zoneId = nil
|
|
169
186
|
self.referrer = nil
|
|
170
187
|
self.url = nil
|
|
171
188
|
self.userToken = nil
|
|
189
|
+
NSLog("[ComposerPianoImpl] [clearConfiguration] All configurations cleared")
|
|
172
190
|
}
|
|
173
191
|
|
|
174
192
|
// MARK: - Execution Method
|
|
@@ -178,20 +196,25 @@ import React
|
|
|
178
196
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
179
197
|
) {
|
|
180
198
|
guard let composer = self.composer else {
|
|
181
|
-
|
|
199
|
+
NSLog("[ComposerPianoImpl] ERROR: executeExperience called but composer is not initialized.")
|
|
182
200
|
rejecter("INIT_ERROR", "Composer not initialized.", nil)
|
|
183
201
|
return
|
|
184
202
|
}
|
|
185
203
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
204
|
+
NSLog("")
|
|
205
|
+
NSLog(String(repeating: "=", count: 80))
|
|
206
|
+
NSLog("[ComposerPianoImpl] === STARTING COMPOSER EXECUTION ===")
|
|
207
|
+
NSLog(String(repeating: "=", count: 80))
|
|
208
|
+
NSLog("[ComposerPianoImpl] Current configuration:")
|
|
209
|
+
NSLog("[ComposerPianoImpl] - AID: \(self.aid ?? "(not set)")")
|
|
210
|
+
NSLog("[ComposerPianoImpl] - Tags count: \(self.tags.count)")
|
|
211
|
+
NSLog("[ComposerPianoImpl] - Tags: [\(self.tags.joined(separator: ", "))]")
|
|
212
|
+
NSLog("[ComposerPianoImpl] - Tags detail: \(self.tags)")
|
|
213
|
+
NSLog("[ComposerPianoImpl] - Zone ID: \(self.zoneId ?? "(not set)")")
|
|
214
|
+
NSLog("[ComposerPianoImpl] - Referrer: \(self.referrer ?? "(not set)")")
|
|
215
|
+
NSLog("[ComposerPianoImpl] - URL: \(self.url ?? "(not set)")")
|
|
216
|
+
NSLog("[ComposerPianoImpl] - User Token: \(self.userToken != nil ? "Set" : "Not set")")
|
|
217
|
+
NSLog("[ComposerPianoImpl] - Custom Variables: \(self.customVariables)")
|
|
195
218
|
|
|
196
219
|
self.experienceResolver = resolver
|
|
197
220
|
self.experienceRejecter = rejecter
|
|
@@ -203,7 +226,7 @@ import React
|
|
|
203
226
|
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { [weak self] in
|
|
204
227
|
// Check if the promise hasn't been resolved yet
|
|
205
228
|
if self?.experienceResolver != nil {
|
|
206
|
-
|
|
229
|
+
NSLog("[ComposerPianoImpl] WARNING: No events received within timeout period (5 seconds)")
|
|
207
230
|
let timeoutResult = [
|
|
208
231
|
"eventType": "noEvents",
|
|
209
232
|
"message": "No events received within timeout period"
|
|
@@ -214,6 +237,13 @@ import React
|
|
|
214
237
|
}
|
|
215
238
|
}
|
|
216
239
|
|
|
240
|
+
NSLog("")
|
|
241
|
+
NSLog("[ComposerPianoImpl] >>> BUILDING EXPERIENCE REQUEST <<<")
|
|
242
|
+
NSLog("[ComposerPianoImpl] >>> Tags being passed to composer: [\(self.tags.joined(separator: ", "))]")
|
|
243
|
+
NSLog("[ComposerPianoImpl] >>> Tags count: \(self.tags.count)")
|
|
244
|
+
NSLog("[ComposerPianoImpl] >>> ⚠️ IF TAGS APPEAR HERE AFTER clearTags(), THE BUG IS IN THE WRAPPER")
|
|
245
|
+
NSLog("[ComposerPianoImpl] >>> ⚠️ IF TAGS APPEAR IN PIANO REQUEST BUT NOT HERE, THE BUG IS IN PIANO SDK")
|
|
246
|
+
|
|
217
247
|
_ =
|
|
218
248
|
composer
|
|
219
249
|
.tags(self.tags)
|
|
@@ -221,19 +251,25 @@ import React
|
|
|
221
251
|
.referrer(self.referrer ?? "")
|
|
222
252
|
.url(self.url ?? "")
|
|
223
253
|
|
|
254
|
+
NSLog("[ComposerPianoImpl] ⚠️ NOTE: PianoComposer SDK does NOT provide getters to verify internal state")
|
|
255
|
+
NSLog("[ComposerPianoImpl] ⚠️ We can only verify OUR wrapper state, not Piano's singleton state")
|
|
256
|
+
NSLog("[ComposerPianoImpl] ⚠️ If bug exists, it's in Piano SDK's internal tag management")
|
|
257
|
+
|
|
224
258
|
if !self.customVariables.isEmpty {
|
|
225
|
-
|
|
259
|
+
NSLog("[ComposerPianoImpl] Applying \(self.customVariables.count) custom variables...")
|
|
226
260
|
for (key, value) in self.customVariables {
|
|
227
|
-
|
|
261
|
+
NSLog("[ComposerPianoImpl] - Applying custom variable: '\(key)' = '\(value)'")
|
|
228
262
|
_ = composer.customVariable(name: key, value: value)
|
|
229
263
|
}
|
|
230
|
-
|
|
264
|
+
NSLog("[ComposerPianoImpl] Custom variables applied successfully.")
|
|
231
265
|
} else {
|
|
232
|
-
|
|
266
|
+
NSLog("[ComposerPianoImpl] No custom variables to apply.")
|
|
233
267
|
}
|
|
234
268
|
|
|
235
|
-
|
|
269
|
+
NSLog("[ComposerPianoImpl] ✓ Experience request configured")
|
|
270
|
+
NSLog(String(repeating: "=", count: 80))
|
|
271
|
+
NSLog("[ComposerPianoImpl] Calling composer.execute()")
|
|
236
272
|
composer.execute()
|
|
237
|
-
|
|
273
|
+
NSLog("[ComposerPianoImpl] composer.execute() called - collecting events for 2 seconds...")
|
|
238
274
|
}
|
|
239
275
|
}
|
|
@@ -20,9 +20,10 @@ import React
|
|
|
20
20
|
// MARK: - Promise Handling Helpers
|
|
21
21
|
|
|
22
22
|
private func collectEvent(eventData: [String: Any]) {
|
|
23
|
-
|
|
23
|
+
NSLog("[MyComposerDelegate] Event collected: \(eventData)")
|
|
24
24
|
collectedEvents.append(eventData)
|
|
25
|
-
|
|
25
|
+
NSLog("[MyComposerDelegate] Total events collected so far: \(collectedEvents.count)")
|
|
26
|
+
NSLog("[MyComposerDelegate] Event added to collection (\(collectedEvents.count) total)")
|
|
26
27
|
|
|
27
28
|
// If this is the first event, start the collection timeout
|
|
28
29
|
if collectedEvents.count == 1 {
|
|
@@ -31,13 +32,13 @@ import React
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
private func startEventCollectionTimeout() {
|
|
34
|
-
|
|
35
|
+
NSLog("[MyComposerDelegate] Starting event collection timeout (2 seconds)...")
|
|
35
36
|
|
|
36
37
|
// Cancel any existing timeout
|
|
37
38
|
timeoutWorkItem?.cancel()
|
|
38
39
|
|
|
39
40
|
let workItem = DispatchWorkItem { [weak self] in
|
|
40
|
-
|
|
41
|
+
NSLog("[MyComposerDelegate] Event collection timeout reached - resolving with \(self?.collectedEvents.count ?? 0) events")
|
|
41
42
|
self?.resolveWithCollectedEvents()
|
|
42
43
|
}
|
|
43
44
|
|
|
@@ -46,37 +47,44 @@ import React
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
private func resolveWithCollectedEvents() {
|
|
49
|
-
guard !promiseResolved else {
|
|
50
|
+
guard !promiseResolved else {
|
|
51
|
+
NSLog("[MyComposerDelegate] Promise already resolved - skipping")
|
|
52
|
+
return
|
|
53
|
+
}
|
|
50
54
|
promiseResolved = true
|
|
51
55
|
|
|
52
|
-
guard let resolver = self.impl?.experienceResolver else {
|
|
56
|
+
guard let resolver = self.impl?.experienceResolver else {
|
|
57
|
+
NSLog("[MyComposerDelegate] No resolver available")
|
|
58
|
+
return
|
|
59
|
+
}
|
|
53
60
|
|
|
54
61
|
let result: [String: Any]
|
|
55
62
|
|
|
56
63
|
switch collectedEvents.count {
|
|
57
64
|
case 0:
|
|
58
|
-
|
|
65
|
+
NSLog("[MyComposerDelegate] No events collected - returning noEvents result")
|
|
59
66
|
result = [
|
|
60
67
|
"eventType": "noEvents",
|
|
61
68
|
"message": "No events received"
|
|
62
69
|
]
|
|
63
70
|
case 1:
|
|
64
|
-
|
|
71
|
+
NSLog("[MyComposerDelegate] Single event collected - returning event directly")
|
|
65
72
|
result = collectedEvents[0]
|
|
66
73
|
default:
|
|
67
|
-
|
|
74
|
+
NSLog("[MyComposerDelegate] Multiple events collected - returning as array")
|
|
68
75
|
result = [
|
|
69
76
|
"eventType": "multipleEvents",
|
|
70
77
|
"events": collectedEvents
|
|
71
78
|
]
|
|
72
79
|
}
|
|
73
80
|
|
|
81
|
+
NSLog("[MyComposerDelegate] Resolving promise with result type: \(result["eventType"] ?? "unknown")")
|
|
74
82
|
resolver(result)
|
|
75
83
|
clearPromiseHandlers()
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
public func initializeEventCollection() {
|
|
79
|
-
|
|
87
|
+
NSLog("[MyComposerDelegate] Initializing event collection system")
|
|
80
88
|
collectedEvents.removeAll()
|
|
81
89
|
promiseResolved = false
|
|
82
90
|
timeoutWorkItem?.cancel()
|
|
@@ -84,7 +92,11 @@ import React
|
|
|
84
92
|
}
|
|
85
93
|
|
|
86
94
|
private func rejectPromise(with error: Error) {
|
|
87
|
-
|
|
95
|
+
NSLog("[MyComposerDelegate] Rejecting promise with error: \(error.localizedDescription)")
|
|
96
|
+
guard let rejecter = self.impl?.experienceRejecter else {
|
|
97
|
+
NSLog("[MyComposerDelegate] No rejecter available")
|
|
98
|
+
return
|
|
99
|
+
}
|
|
88
100
|
let errorCode = "EXECUTION_FAILED"
|
|
89
101
|
let errorMessage = error.localizedDescription
|
|
90
102
|
rejecter(errorCode, errorMessage, error)
|
|
@@ -92,6 +104,7 @@ import React
|
|
|
92
104
|
}
|
|
93
105
|
|
|
94
106
|
private func clearPromiseHandlers() {
|
|
107
|
+
NSLog("[MyComposerDelegate] Clearing promise handlers and event collection")
|
|
95
108
|
timeoutWorkItem?.cancel()
|
|
96
109
|
timeoutWorkItem = nil
|
|
97
110
|
collectedEvents.removeAll()
|
|
@@ -105,83 +118,85 @@ import React
|
|
|
105
118
|
public func showLogin(
|
|
106
119
|
composer: PianoComposer, event: XpEvent, params: ShowLoginEventParams?
|
|
107
120
|
) {
|
|
108
|
-
|
|
121
|
+
NSLog("[MyComposerDelegate] === SHOW LOGIN EVENT RECEIVED ===")
|
|
109
122
|
var eventData = paramsToDictionary(params)
|
|
110
123
|
eventData["eventType"] = "showLogin"
|
|
111
|
-
|
|
124
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
112
125
|
collectEvent(eventData: eventData)
|
|
113
126
|
}
|
|
114
127
|
|
|
115
128
|
public func showTemplate(
|
|
116
129
|
composer: PianoComposer, event: XpEvent, params: ShowTemplateEventParams?
|
|
117
130
|
) {
|
|
118
|
-
|
|
131
|
+
NSLog("[MyComposerDelegate] === SHOW TEMPLATE EVENT RECEIVED ===")
|
|
119
132
|
var eventData = paramsToDictionary(params)
|
|
120
133
|
eventData["eventType"] = "showTemplate"
|
|
121
|
-
|
|
134
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
122
135
|
collectEvent(eventData: eventData)
|
|
123
136
|
}
|
|
124
137
|
|
|
125
138
|
public func showForm(
|
|
126
139
|
composer: PianoComposer, event: XpEvent, params: ShowFormEventParams?
|
|
127
140
|
) {
|
|
128
|
-
|
|
141
|
+
NSLog("[MyComposerDelegate] === SHOW FORM EVENT RECEIVED ===")
|
|
129
142
|
var eventData = paramsToDictionary(params)
|
|
130
143
|
eventData["eventType"] = "showForm"
|
|
131
|
-
|
|
144
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
132
145
|
collectEvent(eventData: eventData)
|
|
133
146
|
}
|
|
134
147
|
|
|
135
148
|
public func showRecommendations(
|
|
136
149
|
composer: PianoComposer, event: XpEvent, params: ShowRecommendationsEventParams?
|
|
137
150
|
) {
|
|
138
|
-
|
|
151
|
+
NSLog("[MyComposerDelegate] === SHOW RECOMMENDATIONS EVENT RECEIVED ===")
|
|
139
152
|
var eventData = paramsToDictionary(params)
|
|
140
153
|
eventData["eventType"] = "showRecommendations"
|
|
141
|
-
|
|
154
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
142
155
|
collectEvent(eventData: eventData)
|
|
143
156
|
}
|
|
144
157
|
|
|
145
158
|
public func nonSite(composer: PianoComposer, event: XpEvent) {
|
|
146
|
-
|
|
159
|
+
NSLog("[MyComposerDelegate] === NON SITE EVENT RECEIVED ===")
|
|
147
160
|
let eventData = [
|
|
148
161
|
"eventType": "nonSite"
|
|
149
162
|
] as [String : Any]
|
|
150
|
-
|
|
163
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
151
164
|
collectEvent(eventData: eventData)
|
|
152
165
|
}
|
|
153
166
|
|
|
154
167
|
public func setResponseVariable(
|
|
155
168
|
composer: PianoComposer, event: XpEvent, params: SetResponseVariableParams?
|
|
156
169
|
) {
|
|
157
|
-
|
|
170
|
+
NSLog("[MyComposerDelegate] === SET RESPONSE VARIABLE EVENT RECEIVED ===")
|
|
158
171
|
var eventData = paramsToDictionary(params)
|
|
159
172
|
eventData["eventType"] = "setResponseVariable"
|
|
160
|
-
|
|
173
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
161
174
|
collectEvent(eventData: eventData)
|
|
162
175
|
}
|
|
163
176
|
|
|
164
177
|
public func meterActive(
|
|
165
178
|
composer: PianoComposer, event: XpEvent, params: PageViewMeterEventParams?
|
|
166
179
|
) {
|
|
167
|
-
|
|
168
|
-
|
|
180
|
+
NSLog("[MyComposerDelegate] === METER ACTIVE EVENT RECEIVED ===")
|
|
181
|
+
NSLog("[MyComposerDelegate] Meter name: \(params?.meterName ?? "N/A")")
|
|
182
|
+
NSLog("[MyComposerDelegate] Event params: \(params != nil ? String(describing: params!) : "nil")")
|
|
169
183
|
var eventData = paramsToDictionary(params)
|
|
170
184
|
eventData["eventType"] = "meter"
|
|
171
185
|
eventData["meterState"] = "active" // Add state to differentiate from expired
|
|
172
|
-
|
|
186
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
173
187
|
collectEvent(eventData: eventData)
|
|
174
188
|
}
|
|
175
189
|
|
|
176
190
|
public func meterExpired(
|
|
177
191
|
composer: PianoComposer, event: XpEvent, params: PageViewMeterEventParams?
|
|
178
192
|
) {
|
|
179
|
-
|
|
180
|
-
|
|
193
|
+
NSLog("[MyComposerDelegate] === METER EXPIRED EVENT RECEIVED ===")
|
|
194
|
+
NSLog("[MyComposerDelegate] Meter name: \(params?.meterName ?? "N/A")")
|
|
195
|
+
NSLog("[MyComposerDelegate] Event params: \(params != nil ? String(describing: params!) : "nil")")
|
|
181
196
|
var eventData = paramsToDictionary(params)
|
|
182
197
|
eventData["eventType"] = "meter"
|
|
183
198
|
eventData["meterState"] = "expired" // Add state to differentiate from active
|
|
184
|
-
|
|
199
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
185
200
|
collectEvent(eventData: eventData)
|
|
186
201
|
}
|
|
187
202
|
|
|
@@ -189,12 +204,12 @@ import React
|
|
|
189
204
|
* Called when the user segment is true.
|
|
190
205
|
*/
|
|
191
206
|
public func userSegmentTrue(composer: PianoComposer, event: XpEvent) {
|
|
192
|
-
|
|
207
|
+
NSLog("[MyComposerDelegate] === USER SEGMENT TRUE EVENT RECEIVED ===")
|
|
193
208
|
let eventData = [
|
|
194
209
|
"eventType": "userSegment",
|
|
195
210
|
"state": true
|
|
196
211
|
] as [String : Any]
|
|
197
|
-
|
|
212
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
198
213
|
collectEvent(eventData: eventData)
|
|
199
214
|
}
|
|
200
215
|
|
|
@@ -202,12 +217,12 @@ import React
|
|
|
202
217
|
* Called when the user segment is false.
|
|
203
218
|
*/
|
|
204
219
|
public func userSegmentFalse(composer: PianoComposer, event: XpEvent) {
|
|
205
|
-
|
|
220
|
+
NSLog("[MyComposerDelegate] === USER SEGMENT FALSE EVENT RECEIVED ===")
|
|
206
221
|
let eventData = [
|
|
207
222
|
"eventType": "userSegment",
|
|
208
223
|
"state": false
|
|
209
224
|
] as [String : Any]
|
|
210
|
-
|
|
225
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
211
226
|
collectEvent(eventData: eventData)
|
|
212
227
|
}
|
|
213
228
|
|
|
@@ -217,10 +232,10 @@ import React
|
|
|
217
232
|
public func experienceExecute(
|
|
218
233
|
composer: PianoComposer, event: XpEvent, params: ExperienceExecuteEventParams?
|
|
219
234
|
) {
|
|
220
|
-
|
|
235
|
+
NSLog("[MyComposerDelegate] === EXPERIENCE EXECUTE EVENT RECEIVED ===")
|
|
221
236
|
var eventData = paramsToDictionary(params)
|
|
222
237
|
eventData["eventType"] = "experienceExecute"
|
|
223
|
-
|
|
238
|
+
NSLog("[MyComposerDelegate] Event data: \(eventData)")
|
|
224
239
|
collectEvent(eventData: eventData)
|
|
225
240
|
}
|
|
226
241
|
|
|
@@ -230,9 +245,10 @@ import React
|
|
|
230
245
|
public func experienceExecutionFailed(
|
|
231
246
|
composer: PianoComposer, event: XpEvent, params: FailureEventParams?
|
|
232
247
|
) {
|
|
233
|
-
|
|
248
|
+
NSLog("[MyComposerDelegate] === EXPERIENCE EXECUTION FAILED EVENT ===")
|
|
234
249
|
let eventData = paramsToDictionary(params)
|
|
235
|
-
|
|
250
|
+
NSLog("[MyComposerDelegate] Failure details: \(eventData)")
|
|
251
|
+
NSLog("[MyComposerDelegate] Experience execution failed - rejecting promise")
|
|
236
252
|
let error = NSError(
|
|
237
253
|
domain: "PianoSDK",
|
|
238
254
|
code: -1,
|
|
@@ -246,8 +262,9 @@ import React
|
|
|
246
262
|
* This is a lifecycle callback that indicates Piano has finished processing.
|
|
247
263
|
*/
|
|
248
264
|
public func composerExecutionCompleted(composer: PianoComposer) {
|
|
249
|
-
|
|
250
|
-
|
|
265
|
+
NSLog("[MyComposerDelegate] === COMPOSER EXECUTION COMPLETED ===")
|
|
266
|
+
NSLog("[MyComposerDelegate] Piano composer has finished execution")
|
|
267
|
+
NSLog("[MyComposerDelegate] Total events collected: \(collectedEvents.count)")
|
|
251
268
|
// Note: This is just a lifecycle notification, we don't send it as an event
|
|
252
269
|
// The actual events have already been collected and will be sent via the timeout
|
|
253
270
|
}
|
package/ios/SdkPianoio.swift
CHANGED
|
@@ -22,27 +22,27 @@ class SdkPianoio: NSObject {
|
|
|
22
22
|
aid: String, isSandbox: Bool, resolver: @escaping RCTPromiseResolveBlock,
|
|
23
23
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
24
24
|
) {
|
|
25
|
-
|
|
25
|
+
NSLog("[\(Self.TAG)] initialize called with AID: \(aid), isSandbox: \(isSandbox)")
|
|
26
26
|
|
|
27
27
|
do {
|
|
28
28
|
guard !aid.isEmpty else {
|
|
29
|
-
|
|
29
|
+
NSLog("[\(Self.TAG)] Initialization failed: AID cannot be empty")
|
|
30
30
|
rejecter("INIT_ERROR", "AID cannot be empty", nil)
|
|
31
31
|
return
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
if isInitialized {
|
|
35
|
-
|
|
35
|
+
NSLog("[\(Self.TAG)] Already initialized.")
|
|
36
36
|
resolver(true)
|
|
37
37
|
return
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
try moduleImpl.initialize(aid: aid, isSandbox: isSandbox)
|
|
41
41
|
isInitialized = true
|
|
42
|
-
|
|
42
|
+
NSLog("[\(Self.TAG)] Initialization successful.")
|
|
43
43
|
resolver(true)
|
|
44
44
|
} catch {
|
|
45
|
-
|
|
45
|
+
NSLog("[\(Self.TAG)] Initialization failed: \(error.localizedDescription)")
|
|
46
46
|
rejecter("INIT_ERROR", "Failed to initialize Piano SDK: \(error.localizedDescription)", error)
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -54,7 +54,7 @@ class SdkPianoio: NSObject {
|
|
|
54
54
|
tag: String, resolver: @escaping RCTPromiseResolveBlock,
|
|
55
55
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
56
56
|
) {
|
|
57
|
-
|
|
57
|
+
NSLog("[\(Self.TAG)] addTag called with: '\(tag)'")
|
|
58
58
|
|
|
59
59
|
guard validateInitialization(rejecter: rejecter),
|
|
60
60
|
validateParameter(tag, paramName: "tag", rejecter: rejecter) else {
|
|
@@ -62,6 +62,7 @@ class SdkPianoio: NSObject {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
moduleImpl.addTag(tag)
|
|
65
|
+
NSLog("[\(Self.TAG)] addTag completed successfully")
|
|
65
66
|
resolver(true)
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -70,7 +71,7 @@ class SdkPianoio: NSObject {
|
|
|
70
71
|
tags: [String], resolver: @escaping RCTPromiseResolveBlock,
|
|
71
72
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
72
73
|
) {
|
|
73
|
-
|
|
74
|
+
NSLog("[\(Self.TAG)] addTags called with \(tags.count) tags: [\(tags.joined(separator: ", "))]")
|
|
74
75
|
|
|
75
76
|
guard validateInitialization(rejecter: rejecter),
|
|
76
77
|
validateArray(tags, paramName: "tags", rejecter: rejecter) else {
|
|
@@ -78,6 +79,7 @@ class SdkPianoio: NSObject {
|
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
moduleImpl.addTags(tags)
|
|
82
|
+
NSLog("[\(Self.TAG)] addTags completed successfully")
|
|
81
83
|
resolver(true)
|
|
82
84
|
}
|
|
83
85
|
|
|
@@ -86,7 +88,7 @@ class SdkPianoio: NSObject {
|
|
|
86
88
|
zoneId: String, resolver: @escaping RCTPromiseResolveBlock,
|
|
87
89
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
88
90
|
) {
|
|
89
|
-
|
|
91
|
+
NSLog("[\(Self.TAG)] setZoneId called with: \(zoneId)")
|
|
90
92
|
|
|
91
93
|
guard validateInitialization(rejecter: rejecter) else {
|
|
92
94
|
return
|
|
@@ -101,7 +103,7 @@ class SdkPianoio: NSObject {
|
|
|
101
103
|
referrer: String, resolver: @escaping RCTPromiseResolveBlock,
|
|
102
104
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
103
105
|
) {
|
|
104
|
-
|
|
106
|
+
NSLog("[\(Self.TAG)] setReferrer called with: \(referrer)")
|
|
105
107
|
|
|
106
108
|
guard validateInitialization(rejecter: rejecter) else {
|
|
107
109
|
return
|
|
@@ -116,7 +118,7 @@ class SdkPianoio: NSObject {
|
|
|
116
118
|
url: String, resolver: @escaping RCTPromiseResolveBlock,
|
|
117
119
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
118
120
|
) {
|
|
119
|
-
|
|
121
|
+
NSLog("[\(Self.TAG)] setUrl called with: \(url)")
|
|
120
122
|
|
|
121
123
|
guard validateInitialization(rejecter: rejecter) else {
|
|
122
124
|
return
|
|
@@ -131,7 +133,7 @@ class SdkPianoio: NSObject {
|
|
|
131
133
|
token: String, resolver: @escaping RCTPromiseResolveBlock,
|
|
132
134
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
133
135
|
) {
|
|
134
|
-
|
|
136
|
+
NSLog("[\(Self.TAG)] setUserToken called")
|
|
135
137
|
|
|
136
138
|
guard validateInitialization(rejecter: rejecter) else {
|
|
137
139
|
return
|
|
@@ -146,7 +148,7 @@ class SdkPianoio: NSObject {
|
|
|
146
148
|
name: String, value: String, resolver: @escaping RCTPromiseResolveBlock,
|
|
147
149
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
148
150
|
) {
|
|
149
|
-
|
|
151
|
+
NSLog("[\(Self.TAG)] addCustomVariable called with: \(name) = \(value)")
|
|
150
152
|
|
|
151
153
|
guard validateInitialization(rejecter: rejecter),
|
|
152
154
|
validateParameter(name, paramName: "name", rejecter: rejecter),
|
|
@@ -163,7 +165,7 @@ class SdkPianoio: NSObject {
|
|
|
163
165
|
variables: [String: String], resolver: @escaping RCTPromiseResolveBlock,
|
|
164
166
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
165
167
|
) {
|
|
166
|
-
|
|
168
|
+
NSLog("[\(Self.TAG)] setCustomVariables called")
|
|
167
169
|
|
|
168
170
|
guard validateInitialization(rejecter: rejecter),
|
|
169
171
|
validateDictionary(variables, paramName: "variables", rejecter: rejecter) else {
|
|
@@ -188,12 +190,14 @@ class SdkPianoio: NSObject {
|
|
|
188
190
|
func executeExperience(
|
|
189
191
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
190
192
|
) {
|
|
191
|
-
|
|
193
|
+
NSLog("[\(Self.TAG)] executeExperience called")
|
|
192
194
|
|
|
193
195
|
guard validateInitialization(rejecter: rejecter) else {
|
|
196
|
+
NSLog("[\(Self.TAG)] executeExperience failed: SDK not initialized")
|
|
194
197
|
return
|
|
195
198
|
}
|
|
196
199
|
|
|
200
|
+
NSLog("[\(Self.TAG)] Delegating to moduleImpl.executeExperience()")
|
|
197
201
|
moduleImpl.executeExperience(resolver: resolver, rejecter: rejecter)
|
|
198
202
|
}
|
|
199
203
|
|
|
@@ -203,7 +207,7 @@ class SdkPianoio: NSObject {
|
|
|
203
207
|
func signIn(
|
|
204
208
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
205
209
|
) {
|
|
206
|
-
|
|
210
|
+
NSLog("[\(Self.TAG)] signIn called")
|
|
207
211
|
|
|
208
212
|
guard validateInitialization(rejecter: rejecter) else {
|
|
209
213
|
return
|
|
@@ -221,7 +225,7 @@ class SdkPianoio: NSObject {
|
|
|
221
225
|
func signOut(
|
|
222
226
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
223
227
|
) {
|
|
224
|
-
|
|
228
|
+
NSLog("[\(Self.TAG)] signOut called")
|
|
225
229
|
|
|
226
230
|
guard validateInitialization(rejecter: rejecter) else {
|
|
227
231
|
return
|
|
@@ -239,7 +243,7 @@ class SdkPianoio: NSObject {
|
|
|
239
243
|
func getCurrentUser(
|
|
240
244
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
241
245
|
) {
|
|
242
|
-
|
|
246
|
+
NSLog("[\(Self.TAG)] getCurrentUser called")
|
|
243
247
|
|
|
244
248
|
guard validateInitialization(rejecter: rejecter) else {
|
|
245
249
|
return
|
|
@@ -272,7 +276,7 @@ class SdkPianoio: NSObject {
|
|
|
272
276
|
func isAuthenticated(
|
|
273
277
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
274
278
|
) {
|
|
275
|
-
|
|
279
|
+
NSLog("[\(Self.TAG)] isAuthenticated called")
|
|
276
280
|
|
|
277
281
|
guard validateInitialization(rejecter: rejecter) else {
|
|
278
282
|
return
|
|
@@ -293,21 +297,23 @@ class SdkPianoio: NSObject {
|
|
|
293
297
|
func getStatus(
|
|
294
298
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
295
299
|
) {
|
|
296
|
-
|
|
300
|
+
NSLog("[\(Self.TAG)] getStatus called")
|
|
297
301
|
|
|
298
302
|
guard validateInitialization(rejecter: rejecter) else {
|
|
299
303
|
return
|
|
300
304
|
}
|
|
301
305
|
|
|
306
|
+
let tags = moduleImpl.getTags()
|
|
302
307
|
let statusMap: [String: Any] = [
|
|
303
308
|
"initialized": isInitialized,
|
|
304
309
|
"aid": moduleImpl.getAid(),
|
|
305
|
-
"tags":
|
|
310
|
+
"tags": tags,
|
|
306
311
|
"zoneId": moduleImpl.getZoneId(),
|
|
307
312
|
"referrer": moduleImpl.getReferrer(),
|
|
308
313
|
"url": moduleImpl.getUrl(),
|
|
309
314
|
"customVariables": moduleImpl.getCustomVariables()
|
|
310
315
|
]
|
|
316
|
+
NSLog("[\(Self.TAG)] Status retrieved - Tags count: \(tags.count), Tags: [\(tags.joined(separator: ", "))]")
|
|
311
317
|
resolver(statusMap)
|
|
312
318
|
}
|
|
313
319
|
|
|
@@ -315,7 +321,7 @@ class SdkPianoio: NSObject {
|
|
|
315
321
|
func isInitialized(
|
|
316
322
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
317
323
|
) {
|
|
318
|
-
|
|
324
|
+
NSLog("[\(Self.TAG)] isInitialized called")
|
|
319
325
|
resolver(isInitialized)
|
|
320
326
|
}
|
|
321
327
|
|
|
@@ -324,7 +330,7 @@ class SdkPianoio: NSObject {
|
|
|
324
330
|
tag: String, resolver: @escaping RCTPromiseResolveBlock,
|
|
325
331
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
326
332
|
) {
|
|
327
|
-
|
|
333
|
+
NSLog("[\(Self.TAG)] removeTag called with: \(tag)")
|
|
328
334
|
|
|
329
335
|
guard validateInitialization(rejecter: rejecter),
|
|
330
336
|
validateParameter(tag, paramName: "tag", rejecter: rejecter) else {
|
|
@@ -340,7 +346,7 @@ class SdkPianoio: NSObject {
|
|
|
340
346
|
key: String, resolver: @escaping RCTPromiseResolveBlock,
|
|
341
347
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
342
348
|
) {
|
|
343
|
-
|
|
349
|
+
NSLog("[\(Self.TAG)] removeCustomVariable called with: \(key)")
|
|
344
350
|
|
|
345
351
|
guard validateInitialization(rejecter: rejecter),
|
|
346
352
|
validateParameter(key, paramName: "key", rejecter: rejecter) else {
|
|
@@ -355,13 +361,14 @@ class SdkPianoio: NSObject {
|
|
|
355
361
|
func clearTags(
|
|
356
362
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
357
363
|
) {
|
|
358
|
-
|
|
364
|
+
NSLog("[\(Self.TAG)] clearTags called")
|
|
359
365
|
|
|
360
366
|
guard validateInitialization(rejecter: rejecter) else {
|
|
361
367
|
return
|
|
362
368
|
}
|
|
363
369
|
|
|
364
370
|
moduleImpl.clearTags()
|
|
371
|
+
NSLog("[\(Self.TAG)] clearTags completed successfully")
|
|
365
372
|
resolver(true)
|
|
366
373
|
}
|
|
367
374
|
|
|
@@ -369,7 +376,7 @@ class SdkPianoio: NSObject {
|
|
|
369
376
|
func clearCustomVariables(
|
|
370
377
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
371
378
|
) {
|
|
372
|
-
|
|
379
|
+
NSLog("[\(Self.TAG)] clearCustomVariables called")
|
|
373
380
|
|
|
374
381
|
guard validateInitialization(rejecter: rejecter) else {
|
|
375
382
|
return
|
|
@@ -383,7 +390,7 @@ class SdkPianoio: NSObject {
|
|
|
383
390
|
func clearConfiguration(
|
|
384
391
|
resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock
|
|
385
392
|
) {
|
|
386
|
-
|
|
393
|
+
NSLog("[\(Self.TAG)] clearConfiguration called")
|
|
387
394
|
|
|
388
395
|
guard validateInitialization(rejecter: rejecter) else {
|
|
389
396
|
return
|
|
@@ -399,7 +406,7 @@ class SdkPianoio: NSObject {
|
|
|
399
406
|
rejecter: RCTPromiseRejectBlock
|
|
400
407
|
) -> Bool {
|
|
401
408
|
guard isInitialized else {
|
|
402
|
-
|
|
409
|
+
NSLog("[\(Self.TAG)] Validation failed: SDK not initialized.")
|
|
403
410
|
rejecter("NOT_INITIALIZED", "Piano SDK not initialized. Call initialize() first.", nil)
|
|
404
411
|
return false
|
|
405
412
|
}
|
|
@@ -410,7 +417,7 @@ class SdkPianoio: NSObject {
|
|
|
410
417
|
_ value: String?, paramName: String, rejecter: RCTPromiseRejectBlock
|
|
411
418
|
) -> Bool {
|
|
412
419
|
guard let value = value, !value.isEmpty else {
|
|
413
|
-
|
|
420
|
+
NSLog("[\(Self.TAG)] Validation failed: Parameter '\(paramName)' is null or empty.")
|
|
414
421
|
rejecter("INVALID_PARAMETER", "Parameter '\(paramName)' cannot be empty", nil)
|
|
415
422
|
return false
|
|
416
423
|
}
|
|
@@ -421,7 +428,7 @@ class SdkPianoio: NSObject {
|
|
|
421
428
|
_ array: [T]?, paramName: String, rejecter: RCTPromiseRejectBlock
|
|
422
429
|
) -> Bool {
|
|
423
430
|
guard let array = array, !array.isEmpty else {
|
|
424
|
-
|
|
431
|
+
NSLog("[\(Self.TAG)] Validation failed: Array '\(paramName)' is null or empty.")
|
|
425
432
|
rejecter("INVALID_PARAMETER", "Array '\(paramName)' cannot be empty", nil)
|
|
426
433
|
return false
|
|
427
434
|
}
|
|
@@ -432,7 +439,7 @@ class SdkPianoio: NSObject {
|
|
|
432
439
|
_ dict: [K: V]?, paramName: String, rejecter: RCTPromiseRejectBlock
|
|
433
440
|
) -> Bool {
|
|
434
441
|
guard let dict = dict else {
|
|
435
|
-
|
|
442
|
+
NSLog("[\(Self.TAG)] Validation failed: Dictionary '\(paramName)' is null.")
|
|
436
443
|
rejecter("INVALID_PARAMETER", "Dictionary '\(paramName)' cannot be null", nil)
|
|
437
444
|
return false
|
|
438
445
|
}
|
package/ios/TokenService.swift
CHANGED
|
@@ -42,17 +42,21 @@ public class TokenService: NSObject, PianoIDDelegate {
|
|
|
42
42
|
|
|
43
43
|
public func initialize(aid: String, isSandbox: Bool = false) {
|
|
44
44
|
if isInitialized {
|
|
45
|
+
NSLog("[TokenService] Already initialized - skipping")
|
|
45
46
|
return
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
NSLog("[TokenService] Initializing with AID: \(aid), isSandbox: \(isSandbox)")
|
|
48
49
|
|
|
49
50
|
PianoID.shared.aid = aid
|
|
50
51
|
PianoID.shared.endpoint = isSandbox ? PianoEndpoint.sandbox : PianoEndpoint.production
|
|
51
52
|
PianoID.shared.delegate = self
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
NSLog("[TokenService] PianoID configured:")
|
|
55
|
+
NSLog("[TokenService] - AID: \(aid)")
|
|
56
|
+
NSLog("[TokenService] - Endpoint: \(PianoID.shared.endpoint)")
|
|
57
|
+
NSLog("[TokenService] - Delegate: Set")
|
|
54
58
|
isInitialized = true
|
|
55
|
-
|
|
59
|
+
NSLog("[TokenService] Initialization completed successfully")
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
// MARK: - Authentication Methods
|
|
@@ -61,32 +65,36 @@ public class TokenService: NSObject, PianoIDDelegate {
|
|
|
61
65
|
|
|
62
66
|
public func signIn(resolver: @escaping (Any?) -> Void, rejecter: @escaping (String?, String?, Error?) -> Void) {
|
|
63
67
|
if !isInitialized {
|
|
64
|
-
|
|
68
|
+
NSLog("[TokenService] ERROR: Not initialized. Call initialize() first.")
|
|
65
69
|
rejecter("INIT_ERROR", "TokenService not initialized", nil)
|
|
66
70
|
return
|
|
67
71
|
}
|
|
68
|
-
|
|
72
|
+
NSLog("[TokenService] Starting sign in flow")
|
|
73
|
+
NSLog("[TokenService] Setting up promise handlers")
|
|
69
74
|
self.signInResolver = resolver
|
|
70
75
|
self.signInRejecter = rejecter
|
|
76
|
+
NSLog("[TokenService] Calling PianoID.shared.signIn()")
|
|
71
77
|
PianoID.shared.signIn()
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
|
|
75
81
|
public func signOut(resolver: @escaping (Any?) -> Void, rejecter: @escaping (String?, String?, Error?) -> Void) {
|
|
76
82
|
if !isInitialized {
|
|
77
|
-
|
|
83
|
+
NSLog("[TokenService] ERROR: Not initialized.")
|
|
78
84
|
rejecter("INIT_ERROR", "TokenService not initialized", nil)
|
|
79
85
|
return
|
|
80
86
|
}
|
|
81
87
|
guard let token = self.cachedToken else {
|
|
82
|
-
|
|
88
|
+
NSLog("[TokenService] No user is signed in - already signed out")
|
|
83
89
|
resolver(["success": true]) // Already signed out
|
|
84
90
|
return
|
|
85
91
|
}
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
NSLog("[TokenService] Starting sign out flow")
|
|
94
|
+
NSLog("[TokenService] Current token: \(token.accessToken.prefix(20))...")
|
|
88
95
|
self.signOutResolver = resolver
|
|
89
96
|
self.signOutRejecter = rejecter
|
|
97
|
+
NSLog("[TokenService] Calling PianoID.shared.signOut()")
|
|
90
98
|
PianoID.shared.signOut(token: token.accessToken)
|
|
91
99
|
}
|
|
92
100
|
|
|
@@ -94,9 +102,11 @@ public class TokenService: NSObject, PianoIDDelegate {
|
|
|
94
102
|
|
|
95
103
|
public func getCurrentUser() -> User? {
|
|
96
104
|
guard let token = self.cachedToken else {
|
|
105
|
+
NSLog("[TokenService] getCurrentUser: No cached token available")
|
|
97
106
|
return nil
|
|
98
107
|
}
|
|
99
108
|
|
|
109
|
+
NSLog("[TokenService] getCurrentUser: Decoding JWT token")
|
|
100
110
|
// Decode the JWT to get the claims
|
|
101
111
|
let claims = decode(jwtToken: token.accessToken)
|
|
102
112
|
|
|
@@ -106,7 +116,7 @@ public class TokenService: NSObject, PianoIDDelegate {
|
|
|
106
116
|
let userId = claims?["sub"] as? String ?? "unknown"
|
|
107
117
|
let email = claims?["email"] as? String ?? "unknown"
|
|
108
118
|
|
|
109
|
-
|
|
119
|
+
NSLog("[TokenService] Extracted user - ID: \(userId), Email: \(email)")
|
|
110
120
|
|
|
111
121
|
return User(
|
|
112
122
|
id: userId,
|
|
@@ -116,17 +126,20 @@ public class TokenService: NSObject, PianoIDDelegate {
|
|
|
116
126
|
}
|
|
117
127
|
|
|
118
128
|
public func isAuthenticated() -> Bool {
|
|
119
|
-
|
|
129
|
+
let isAuth = self.cachedToken != nil
|
|
130
|
+
NSLog("[TokenService] isAuthenticated: \(isAuth)")
|
|
131
|
+
return isAuth
|
|
120
132
|
}
|
|
121
133
|
|
|
122
134
|
// MARK: - PianoIDDelegate Implementation
|
|
123
135
|
|
|
124
136
|
public func signIn(result: PianoIDSignInResult!, withError error: Error!) {
|
|
125
137
|
if let r = result {
|
|
126
|
-
|
|
138
|
+
NSLog("[TokenService] === SIGN IN SUCCESSFUL ===")
|
|
139
|
+
NSLog("[TokenService] Caching token")
|
|
127
140
|
self.cachedToken = r.token
|
|
128
141
|
let user = self.getCurrentUser()
|
|
129
|
-
|
|
142
|
+
|
|
130
143
|
let resultMap: [String: Any] = [
|
|
131
144
|
"success": true,
|
|
132
145
|
"uid": user?.id ?? "",
|
|
@@ -134,34 +147,42 @@ public class TokenService: NSObject, PianoIDDelegate {
|
|
|
134
147
|
"accessToken": user?.accessToken ?? "",
|
|
135
148
|
"authenticated": true
|
|
136
149
|
]
|
|
150
|
+
NSLog("[TokenService] Resolving sign in promise with user: \(user?.email ?? "unknown")")
|
|
137
151
|
self.signInResolver?(resultMap)
|
|
138
152
|
} else if let e = error {
|
|
139
|
-
|
|
153
|
+
NSLog("[TokenService] === SIGN IN FAILED ===")
|
|
154
|
+
NSLog("[TokenService] Error: \(e.localizedDescription)")
|
|
140
155
|
self.signInRejecter?("SIGNIN_ERROR", e.localizedDescription, e)
|
|
141
156
|
}
|
|
142
157
|
|
|
158
|
+
NSLog("[TokenService] Cleaning up sign in promise handlers")
|
|
143
159
|
self.signInResolver = nil
|
|
144
160
|
self.signInRejecter = nil
|
|
145
161
|
}
|
|
146
162
|
|
|
147
163
|
public func signOut(withError error: Error!) {
|
|
148
164
|
if let e = error {
|
|
149
|
-
|
|
165
|
+
NSLog("[TokenService] === SIGN OUT FAILED ===")
|
|
166
|
+
NSLog("[TokenService] Error: \(e.localizedDescription)")
|
|
150
167
|
self.signOutRejecter?("SIGNOUT_ERROR", e.localizedDescription, e)
|
|
151
168
|
} else {
|
|
152
|
-
|
|
169
|
+
NSLog("[TokenService] === SIGN OUT SUCCESSFUL ===")
|
|
170
|
+
NSLog("[TokenService] Clearing cached token")
|
|
153
171
|
self.cachedToken = nil
|
|
154
172
|
self.signOutResolver?(["success": true])
|
|
155
173
|
}
|
|
174
|
+
NSLog("[TokenService] Cleaning up sign out promise handlers")
|
|
156
175
|
// Clean up promises
|
|
157
176
|
self.signOutResolver = nil
|
|
158
177
|
self.signOutRejecter = nil
|
|
159
178
|
}
|
|
160
179
|
|
|
161
180
|
public func cancel() {
|
|
162
|
-
|
|
181
|
+
NSLog("[TokenService] === USER CANCELLED ===")
|
|
182
|
+
NSLog("[TokenService] User cancelled the authentication flow")
|
|
163
183
|
// If there's an active sign-in promise, reject it.
|
|
164
184
|
if let rejecter = self.signInRejecter {
|
|
185
|
+
NSLog("[TokenService] Rejecting sign in promise due to cancellation")
|
|
165
186
|
rejecter("CANCELLED", "User cancelled the sign-in process.", nil)
|
|
166
187
|
self.signInResolver = nil
|
|
167
188
|
self.signInRejecter = nil
|
|
@@ -171,25 +192,29 @@ public class TokenService: NSObject, PianoIDDelegate {
|
|
|
171
192
|
// MARK: - Helper Methods
|
|
172
193
|
|
|
173
194
|
private func decode(jwtToken jwt: String) -> [String: Any]? {
|
|
195
|
+
NSLog("[TokenService] [decode] Decoding JWT token")
|
|
174
196
|
let segments = jwt.components(separatedBy: ".")
|
|
175
197
|
guard segments.count > 1 else {
|
|
176
|
-
|
|
198
|
+
NSLog("[TokenService] [decode] ERROR: Invalid token format - expected 3 segments, got \(segments.count)")
|
|
177
199
|
return nil
|
|
178
200
|
}
|
|
179
|
-
|
|
201
|
+
|
|
202
|
+
NSLog("[TokenService] [decode] Token has \(segments.count) segments")
|
|
180
203
|
var base64String = segments[1]
|
|
181
204
|
let requiredLength = Int(4 * ceil(Float(base64String.count) / 4.0))
|
|
182
205
|
let nbrPaddings = requiredLength - base64String.count
|
|
183
206
|
if nbrPaddings > 0 {
|
|
207
|
+
NSLog("[TokenService] [decode] Adding \(nbrPaddings) padding characters")
|
|
184
208
|
let padding = String(repeating: "=", count: nbrPaddings)
|
|
185
209
|
base64String = base64String.appending(padding)
|
|
186
210
|
}
|
|
187
|
-
|
|
211
|
+
|
|
188
212
|
guard let data = Data(base64Encoded: base64String, options: .ignoreUnknownCharacters) else {
|
|
189
|
-
|
|
213
|
+
NSLog("[TokenService] [decode] ERROR: Could not decode base64 payload")
|
|
190
214
|
return nil
|
|
191
215
|
}
|
|
192
|
-
|
|
216
|
+
|
|
217
|
+
NSLog("[TokenService] [decode] Successfully decoded JWT payload")
|
|
193
218
|
return try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
|
|
194
219
|
}
|
|
195
220
|
}
|