react-native-sdk-pianoio 0.2.5 → 0.3.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/README.md +36 -2
- package/SdkPianoio.podspec +4 -16
- package/android/build.gradle +12 -19
- package/android/gradle.properties +17 -2
- package/android/src/main/java/com/sdkpianoio/SdkPianoioModule.kt +543 -7
- package/android/src/main/java/com/sdkpianoio/SdkPianoioPackage.kt +3 -3
- package/ios/ComposerPianoImpl.swift +247 -0
- package/ios/MyComposerDelegate.swift +79 -200
- package/ios/SdkPianoio.swift +150 -0
- package/ios/SdkPianoioBridge.m +81 -0
- package/ios/services/TokenService.swift +10 -7
- package/lib/commonjs/NativeSdkPianoio.ts +13 -4
- package/lib/commonjs/PianoComposer.js +16 -9
- package/lib/commonjs/PianoComposer.js.map +1 -1
- package/lib/commonjs/debug.js +23 -0
- package/lib/commonjs/debug.js.map +1 -0
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/NativeSdkPianoio.ts +13 -4
- package/lib/module/PianoComposer.js +16 -9
- package/lib/module/PianoComposer.js.map +1 -1
- package/lib/module/debug.js +18 -0
- package/lib/module/debug.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/NativeSdkPianoio.d.ts +2 -2
- package/lib/typescript/commonjs/src/NativeSdkPianoio.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/PianoComposer.d.ts +2 -2
- package/lib/typescript/commonjs/src/PianoComposer.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/debug.d.ts +2 -0
- package/lib/typescript/commonjs/src/debug.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +1 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/NativeSdkPianoio.d.ts +2 -2
- package/lib/typescript/module/src/NativeSdkPianoio.d.ts.map +1 -1
- package/lib/typescript/module/src/PianoComposer.d.ts +2 -2
- package/lib/typescript/module/src/PianoComposer.d.ts.map +1 -1
- package/lib/typescript/module/src/debug.d.ts +2 -0
- package/lib/typescript/module/src/debug.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +1 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +31 -16
- package/src/NativeSdkPianoio.ts +13 -4
- package/src/PianoComposer.tsx +17 -10
- package/src/debug.ts +19 -0
- package/src/index.tsx +1 -0
- package/ios/ComposerPiano.swift +0 -297
- package/ios/SdkPianoio.h +0 -4
- package/ios/SdkPianoio.mm +0 -267
- package/ios/services/ComposerService.swift +0 -49
@@ -0,0 +1,247 @@
|
|
1
|
+
//
|
2
|
+
// ComposerPianoImpl.swift
|
3
|
+
// SdkPianoio
|
4
|
+
//
|
5
|
+
//
|
6
|
+
import Foundation
|
7
|
+
import PianoComposer
|
8
|
+
import PianoOAuth
|
9
|
+
import React
|
10
|
+
|
11
|
+
@objcMembers public class ComposerPianoImpl: NSObject {
|
12
|
+
private var composer: PianoComposer?
|
13
|
+
private var delegateHelper: MyComposerDelegate?
|
14
|
+
|
15
|
+
// ✅ These will hold the promise functions from React Native
|
16
|
+
var promiseResolver: RCTPromiseResolveBlock?
|
17
|
+
var promiseRejecter: RCTPromiseRejectBlock?
|
18
|
+
|
19
|
+
// This is a static property to hold the AID
|
20
|
+
public static var aid = ""
|
21
|
+
|
22
|
+
@objc public func initializeComposer(_ aid: String) {
|
23
|
+
ComposerPianoImpl.aid = aid
|
24
|
+
|
25
|
+
// 1. Correctly initialize the TokenService first.
|
26
|
+
let tokenService = TokenService()
|
27
|
+
|
28
|
+
// 2. Initialize the delegate.
|
29
|
+
self.delegateHelper = MyComposerDelegate()
|
30
|
+
|
31
|
+
// 3. Link the delegate back to this class so it can resolve promises.
|
32
|
+
self.delegateHelper?.moduleImpl = self
|
33
|
+
|
34
|
+
// 4. Initialize the composer.
|
35
|
+
self.composer = PianoComposer(
|
36
|
+
aid: ComposerPianoImpl.aid, endpoint: PianoEndpoint.productionEurope)
|
37
|
+
|
38
|
+
// 5. Set the composer's delegate property directly. This is the standard Swift way.
|
39
|
+
self.composer?.delegate = self.delegateHelper
|
40
|
+
}
|
41
|
+
|
42
|
+
@objc public func executeComposer() {
|
43
|
+
print("Esecuzione composer")
|
44
|
+
DispatchQueue.main.async {
|
45
|
+
if let composer = self.composer {
|
46
|
+
print("Calling composer.execute()")
|
47
|
+
composer.execute()
|
48
|
+
} else {
|
49
|
+
print("⚠️ Composer è nil")
|
50
|
+
self.promiseRejecter?(
|
51
|
+
"composer_nil", "Piano Composer is not initialized.", nil)
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
@objc public func executeExperience(
|
57
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
58
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
59
|
+
) {
|
60
|
+
self.promiseResolver = resolver
|
61
|
+
self.promiseRejecter = rejecter
|
62
|
+
|
63
|
+
self.executeComposer()
|
64
|
+
}
|
65
|
+
|
66
|
+
public func findViewBySelector(selector: String) -> UIView? {
|
67
|
+
return nil
|
68
|
+
}
|
69
|
+
|
70
|
+
// --- Configuration methods ---
|
71
|
+
|
72
|
+
@objc public func addTag(_ tag: String) {
|
73
|
+
_ = composer?.tag(tag)
|
74
|
+
}
|
75
|
+
|
76
|
+
@objc public func addTags(_ tags: [String]) {
|
77
|
+
_ = composer?.tags(tags)
|
78
|
+
}
|
79
|
+
|
80
|
+
@objc public func setZoneId(_ zoneId: String) {
|
81
|
+
_ = composer?.zoneId(zoneId)
|
82
|
+
}
|
83
|
+
|
84
|
+
@objc public func setReferrer(_ referrer: String) {
|
85
|
+
_ = composer?.referrer(referrer)
|
86
|
+
}
|
87
|
+
|
88
|
+
@objc public func setUrl(_ url: String) {
|
89
|
+
_ = composer?.url(url)
|
90
|
+
}
|
91
|
+
|
92
|
+
@objc public func setCustomVariable(_ name: String, value: String) {
|
93
|
+
_ = composer?.customVariable(name: name, value: value)
|
94
|
+
}
|
95
|
+
|
96
|
+
@objc public func setUserToken(_ token: String) {
|
97
|
+
_ = composer?.userToken(token)
|
98
|
+
}
|
99
|
+
|
100
|
+
// method to get values and helpers
|
101
|
+
@objc public func getAid() -> String {
|
102
|
+
if composer != nil {
|
103
|
+
return composer?.aid ?? ""
|
104
|
+
} else {
|
105
|
+
return ""
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
@objc public func getTags() -> [String] {
|
110
|
+
if let tags = composer?.tags, !tags.isEmpty {
|
111
|
+
return Array(tags)
|
112
|
+
} else {
|
113
|
+
return []
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
@objc public func getComposer() -> PianoComposer? {
|
118
|
+
return composer
|
119
|
+
}
|
120
|
+
|
121
|
+
@objc public func getZoneId() -> String {
|
122
|
+
return composer?.zoneId ?? ""
|
123
|
+
}
|
124
|
+
|
125
|
+
@objc public func getReferrer() -> String {
|
126
|
+
return composer?.referrer ?? ""
|
127
|
+
}
|
128
|
+
|
129
|
+
@objc public func getUrl() -> String {
|
130
|
+
return composer?.url ?? ""
|
131
|
+
}
|
132
|
+
|
133
|
+
@objc public func getUserToken() -> String {
|
134
|
+
return composer?.userToken ?? ""
|
135
|
+
}
|
136
|
+
|
137
|
+
// MARK: - Additional Methods for React Native Bridge
|
138
|
+
|
139
|
+
@objc public func executeComposerWithResolver(
|
140
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
141
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
142
|
+
) {
|
143
|
+
self.promiseResolver = resolver
|
144
|
+
self.promiseRejecter = rejecter
|
145
|
+
self.executeComposer()
|
146
|
+
}
|
147
|
+
|
148
|
+
@objc public func showLoginWithResolver(
|
149
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
150
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
151
|
+
) {
|
152
|
+
self.promiseResolver = resolver
|
153
|
+
self.promiseRejecter = rejecter
|
154
|
+
|
155
|
+
DispatchQueue.main.async {
|
156
|
+
if let composer = self.composer {
|
157
|
+
// This would need to be implemented based on Piano SDK's login functionality
|
158
|
+
print("Show login triggered")
|
159
|
+
resolver(true)
|
160
|
+
} else {
|
161
|
+
rejecter("composer_nil", "Piano Composer is not initialized.", nil)
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
@objc public func showTemplateWithResolver(
|
167
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
168
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
169
|
+
) {
|
170
|
+
self.promiseResolver = resolver
|
171
|
+
self.promiseRejecter = rejecter
|
172
|
+
self.executeComposer()
|
173
|
+
}
|
174
|
+
|
175
|
+
@objc public func showFormWithResolver(
|
176
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
177
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
178
|
+
) {
|
179
|
+
self.promiseResolver = resolver
|
180
|
+
self.promiseRejecter = rejecter
|
181
|
+
self.executeComposer()
|
182
|
+
}
|
183
|
+
|
184
|
+
@objc public func showRecommendationsWithResolver(
|
185
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
186
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
187
|
+
) {
|
188
|
+
self.promiseResolver = resolver
|
189
|
+
self.promiseRejecter = rejecter
|
190
|
+
self.executeComposer()
|
191
|
+
}
|
192
|
+
|
193
|
+
@objc public func nonSiteWithResolver(
|
194
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
195
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
196
|
+
) {
|
197
|
+
self.promiseResolver = resolver
|
198
|
+
self.promiseRejecter = rejecter
|
199
|
+
self.executeComposer()
|
200
|
+
}
|
201
|
+
|
202
|
+
@objc public func userSegmentTrueWithResolver(
|
203
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
204
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
205
|
+
) {
|
206
|
+
self.promiseResolver = resolver
|
207
|
+
self.promiseRejecter = rejecter
|
208
|
+
self.executeComposer()
|
209
|
+
}
|
210
|
+
|
211
|
+
@objc public func userSegmentFalseWithResolver(
|
212
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
213
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
214
|
+
) {
|
215
|
+
self.promiseResolver = resolver
|
216
|
+
self.promiseRejecter = rejecter
|
217
|
+
self.executeComposer()
|
218
|
+
}
|
219
|
+
|
220
|
+
@objc public func meterActiveWithResolver(
|
221
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
222
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
223
|
+
) {
|
224
|
+
self.promiseResolver = resolver
|
225
|
+
self.promiseRejecter = rejecter
|
226
|
+
self.executeComposer()
|
227
|
+
}
|
228
|
+
|
229
|
+
@objc public func meterExpiredWithResolver(
|
230
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
231
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
232
|
+
) {
|
233
|
+
self.promiseResolver = resolver
|
234
|
+
self.promiseRejecter = rejecter
|
235
|
+
self.executeComposer()
|
236
|
+
}
|
237
|
+
|
238
|
+
@objc public func composerExecutionCompletedWithResolver(
|
239
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
240
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
241
|
+
) {
|
242
|
+
self.promiseResolver = resolver
|
243
|
+
self.promiseRejecter = rejecter
|
244
|
+
self.executeComposer()
|
245
|
+
}
|
246
|
+
|
247
|
+
}
|
@@ -7,230 +7,109 @@
|
|
7
7
|
import Foundation
|
8
8
|
import PianoComposer
|
9
9
|
import PianoOAuth
|
10
|
-
import PianoCommon
|
11
|
-
import PianoTemplate
|
12
|
-
|
13
|
-
import SwiftUI
|
14
|
-
import WebKit
|
15
|
-
|
16
|
-
public class MyComposerDelegate: ComposerService, PianoShowTemplateDelegate {
|
17
|
-
|
18
|
-
var view: WKWebView?
|
19
|
-
|
20
|
-
func experienceExecute(composer: PianoComposer, event: XpEvent, params: ExperienceExecuteEventParams?) {
|
21
|
-
print("Evento ricevuto: \(event)")
|
22
|
-
print(event.eventType)
|
23
|
-
}
|
24
|
-
|
25
|
-
func showTemplate(params: ShowTemplateEventParams) {
|
26
|
-
if params.displayMode == .inline {
|
27
|
-
let request = URLRequest(url: URL(string: params.templateUrl)!)
|
28
|
-
view?.load(request)
|
29
|
-
}
|
30
|
-
}
|
31
|
-
|
32
|
-
public func setComposerAndDelegate(_ myComposer: PianoComposer) -> PianoComposer? {
|
33
|
-
myComposer.delegate = self;
|
34
|
-
return myComposer;
|
35
|
-
}
|
36
|
-
|
37
|
-
public func myShowLogin(composer: PianoComposer, event: XpEvent, params: [AnyHashable: Any]?) {
|
38
|
-
DispatchQueue.main.async {
|
39
|
-
PianoID.shared.aid = composer.aid;
|
40
|
-
PianoID.shared.endpoint = composer.endpoint;
|
41
|
-
PianoID.shared.signUpEnabled = true;
|
42
|
-
|
43
|
-
PianoID.shared.signIn();
|
44
|
-
};
|
45
|
-
}
|
46
|
-
|
47
|
-
public func myShowForm(composer: PianoComposer, event: XpEvent, params: [AnyHashable: Any]?) {
|
48
|
-
DispatchQueue.main.async {
|
49
|
-
PianoID.shared.formInfo(accessToken: PianoIDToken.description()) { formInfo, error in
|
50
|
-
if let error = error {
|
51
|
-
print("Errore nel recuperare il form: \(error.localizedDescription)")
|
52
|
-
return
|
53
|
-
}
|
54
|
-
|
55
|
-
guard let formInfo = formInfo else {
|
56
|
-
print("FormInfo non disponibile.")
|
57
|
-
return
|
58
|
-
}
|
59
|
-
|
60
|
-
composer.delegate?.showForm?(composer: composer, event: event, params: nil)
|
61
|
-
}
|
62
|
-
}
|
63
|
-
}
|
64
10
|
|
11
|
+
// import PianoTemplate
|
65
12
|
|
66
|
-
|
67
|
-
public func myShowTemplate(composer: PianoComposer, event: XpEvent, params: ShowTemplateEventParams?) {
|
68
|
-
if let p = params {
|
69
|
-
let webView = WKWebView()
|
70
|
-
let request = URLRequest(url: URL(string: p.templateUrl)!)
|
71
|
-
webView.load(request)
|
72
|
-
|
73
|
-
// Aggiungi webView alla vista principale
|
74
|
-
let controller = PianoShowTemplateController(p)
|
75
|
-
controller.delegate = self
|
76
|
-
controller.show()
|
77
|
-
|
78
|
-
self.execute();
|
79
|
-
}
|
80
|
-
}
|
81
|
-
|
82
|
-
public func executeExperience(composer: PianoComposer, event: XpEvent, params: ExperienceExecuteEventParams?) {
|
83
|
-
composer.delegate?.experienceExecute?(composer: composer, event: event, params: params)
|
84
|
-
}
|
13
|
+
@objcMembers public class MyComposerDelegate: NSObject, PianoComposerDelegate {
|
85
14
|
|
15
|
+
// ✅ STEP 1: Add a weak reference back to the main implementation class.
|
16
|
+
// This lets us access the stored promiseResolver and promiseRejecter.
|
17
|
+
weak var moduleImpl: ComposerPianoImpl?
|
86
18
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
public func showRecommendations(composer: PianoComposer, event: XpEvent, params: ShowRecommendationsEventParams?) {
|
93
|
-
DispatchQueue.main.async {
|
94
|
-
composer.delegate?.showRecommendations?(composer: composer, event: event, params: params)
|
95
|
-
}
|
96
|
-
}
|
97
|
-
|
98
|
-
public func nonSite(composer: PianoComposer, event: XpEvent) {
|
99
|
-
DispatchQueue.main.async {
|
100
|
-
composer.delegate?.nonSite?(composer: composer, event: event)
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
public func userSegmentTrue(composer: PianoComposer, event: XpEvent) {
|
105
|
-
DispatchQueue.main.async {
|
106
|
-
composer.delegate?.userSegmentTrue?(composer: composer, event: event)
|
107
|
-
}
|
108
|
-
}
|
109
|
-
|
110
|
-
public func userSegmentFalse(composer: PianoComposer, event: XpEvent) {
|
111
|
-
DispatchQueue.main.async {
|
112
|
-
composer.delegate?.userSegmentFalse?(composer: composer, event: event)
|
113
|
-
}
|
114
|
-
}
|
115
|
-
|
116
|
-
public func meterActive(composer: PianoComposer, event: XpEvent, params: PageViewMeterEventParams?) {
|
117
|
-
DispatchQueue.main.async {
|
118
|
-
composer.delegate?.meterActive?(composer: composer, event: event, params: params)
|
119
|
-
}
|
120
|
-
}
|
121
|
-
|
122
|
-
public func meterExpired(composer: PianoComposer, event: XpEvent, params: PageViewMeterEventParams?) {
|
123
|
-
DispatchQueue.main.async {
|
124
|
-
composer.delegate?.meterExpired?(composer: composer, event: event, params: params)
|
125
|
-
}
|
126
|
-
}
|
127
|
-
|
128
|
-
public func composerDidCompleteExecution(_ composer: PianoComposer, result: PianoComposerEdgeResult?) {
|
129
|
-
print("✅ Composer execution finished.")
|
130
|
-
|
131
|
-
// Qui puoi notificare JS, inviare un evento, ecc.
|
132
|
-
// Ad esempio: invia una notifica o chiama una callback
|
133
|
-
}
|
19
|
+
// ✅ STEP 2: This is a generic helper function to resolve the promise.
|
20
|
+
// We'll call this from all the different delegate methods.
|
21
|
+
private func resolvePromise(with eventData: [String: Any]) {
|
22
|
+
guard self.moduleImpl?.promiseResolver != nil else { return }
|
134
23
|
|
135
|
-
|
136
|
-
|
24
|
+
self.moduleImpl?.promiseResolver?(eventData)
|
25
|
+
self.clearPromiseHandlers()
|
137
26
|
}
|
138
|
-
}
|
139
|
-
|
140
|
-
|
141
|
-
|
142
27
|
|
28
|
+
private func rejectPromise(with error: Error) {
|
29
|
+
guard self.moduleImpl?.promiseRejecter != nil else { return }
|
143
30
|
|
31
|
+
let errorCode = "execution_failed"
|
32
|
+
let errorMessage = error.localizedDescription
|
33
|
+
self.moduleImpl?.promiseRejecter?(errorCode, errorMessage, error)
|
34
|
+
self.clearPromiseHandlers()
|
35
|
+
}
|
144
36
|
|
145
|
-
|
37
|
+
private func clearPromiseHandlers() {
|
38
|
+
self.moduleImpl?.promiseResolver = nil
|
39
|
+
self.moduleImpl?.promiseRejecter = nil
|
40
|
+
}
|
146
41
|
|
147
|
-
|
42
|
+
// ✅ STEP 3: Implement the real delegate methods.
|
43
|
+
// The Piano SDK will call these automatically.
|
148
44
|
|
149
|
-
|
45
|
+
public func executeExperience(
|
46
|
+
composer: PianoComposer, event: XpEvent
|
47
|
+
) {
|
48
|
+
print("✅ Delegate received: executeExperience")
|
150
49
|
|
151
|
-
|
50
|
+
// Correct: Access the experienceId from the public 'eventExecutionContext' object
|
51
|
+
let experienceId = event.eventExecutionContext?.experienceId ?? ""
|
152
52
|
|
153
|
-
|
53
|
+
let eventData: [String: Any] = [
|
54
|
+
"eventType": event.eventType,
|
55
|
+
"experienceId": experienceId,
|
56
|
+
]
|
154
57
|
|
155
|
-
|
156
|
-
|
157
|
-
}
|
58
|
+
resolvePromise(with: eventData)
|
59
|
+
}
|
158
60
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
}
|
164
|
-
})
|
165
|
-
}
|
166
|
-
}
|
61
|
+
public func showTemplate(
|
62
|
+
composer: PianoComposer, event: XpEvent, params: ShowTemplateEventParams?
|
63
|
+
) {
|
64
|
+
print("✅ Delegate received: showTemplate")
|
167
65
|
|
168
|
-
|
169
|
-
|
170
|
-
}
|
66
|
+
// Correct: Access the experienceId from the public 'eventExecutionContext' object
|
67
|
+
let experienceId = event.eventExecutionContext?.experienceId ?? ""
|
171
68
|
|
172
|
-
|
173
|
-
|
174
|
-
|
69
|
+
let eventData: [String: Any] = [
|
70
|
+
"eventType": event.eventType,
|
71
|
+
"experienceId": experienceId,
|
72
|
+
"templateUrl": params?.templateUrl ?? "",
|
73
|
+
"displayMode": params?.displayMode.rawValue ?? "",
|
74
|
+
]
|
175
75
|
|
176
|
-
|
177
|
-
|
76
|
+
resolvePromise(with: eventData)
|
77
|
+
}
|
178
78
|
|
179
|
-
|
180
|
-
|
79
|
+
public func meterExpired(
|
80
|
+
composer: PianoComposer, event: XpEvent, params: PageViewMeterEventParams?
|
81
|
+
) {
|
82
|
+
print("✅ Delegate received: meterExpired")
|
181
83
|
|
182
|
-
|
84
|
+
// Correct: Access the experienceId from the public 'eventExecutionContext' object
|
85
|
+
let experienceId = event.eventExecutionContext?.experienceId ?? ""
|
183
86
|
|
184
|
-
|
87
|
+
let eventData: [String: Any] = [
|
88
|
+
"eventType": event.eventType,
|
89
|
+
"experienceId": experienceId,
|
90
|
+
"meterName": params?.meterName ?? "",
|
91
|
+
]
|
185
92
|
|
186
|
-
|
187
|
-
|
188
|
-
_ = composer.tag("templates")
|
189
|
-
}
|
93
|
+
resolvePromise(with: eventData)
|
94
|
+
}
|
190
95
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
}
|
96
|
+
public func composerExecutionFailed(_ composer: PianoComposer, error: Error) {
|
97
|
+
print("❌ Delegate received: composerExecutionFailed")
|
98
|
+
rejectPromise(with: error)
|
99
|
+
}
|
196
100
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
}
|
101
|
+
public func composerExecutionCompleted(composer: PianoComposer) {
|
102
|
+
print("✅ Delegate received: composerExecutionCompleted")
|
103
|
+
resolvePromise(with: ["eventType": "composerExecutionCompleted"])
|
104
|
+
}
|
202
105
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
106
|
+
public func experienceExecutionFailed(composer: PianoComposer, event: XpEvent, params: FailureEventParams?) {
|
107
|
+
print("❌ Delegate received: experienceExecutionFailed")
|
108
|
+
let error = NSError(domain: "PianoSDK", code: -1, userInfo: [NSLocalizedDescriptionKey: "Experience execution failed"])
|
109
|
+
rejectPromise(with: error)
|
110
|
+
}
|
207
111
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
@State private var height: CGFloat = .zero
|
213
|
-
|
214
|
-
init(tokenService: TokenService) {
|
215
|
-
service = ShowTemplateService(tokenService: tokenService)
|
216
|
-
}
|
217
|
-
|
218
|
-
var body: some View {
|
219
|
-
if #available(iOS 14.0, *) {
|
220
|
-
VStack(spacing: 20) {
|
221
|
-
if !service.loading {
|
222
|
-
Button("Execute") {
|
223
|
-
service.execute()
|
224
|
-
}
|
225
|
-
|
226
|
-
if let wv = service.webView {
|
227
|
-
WebView(webView: wv, height: $height)
|
228
|
-
.frame(height: height > 320 ? 320 : height)
|
229
|
-
}
|
230
|
-
} else {
|
231
|
-
|
232
|
-
}
|
233
|
-
}.navigationTitle("Show template")
|
234
|
-
}
|
235
|
-
}
|
112
|
+
public func findViewBySelector(selector: String) -> UIView? {
|
113
|
+
return nil
|
114
|
+
}
|
236
115
|
}
|