@capawesome/capacitor-singular 0.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.
Files changed (79) hide show
  1. package/CapawesomeCapacitorSingular.podspec +19 -0
  2. package/LICENSE +21 -0
  3. package/Package.swift +26 -0
  4. package/README.md +1262 -0
  5. package/android/build.gradle +61 -0
  6. package/android/src/main/AndroidManifest.xml +5 -0
  7. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/Singular.java +443 -0
  8. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/SingularHelper.java +53 -0
  9. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/SingularPlugin.java +336 -0
  10. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/CustomException.java +20 -0
  11. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/CustomExceptions.java +34 -0
  12. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/events/DeviceAttributionInfoReceivedEvent.java +48 -0
  13. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/events/SdidReceivedEvent.java +23 -0
  14. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/events/SdidSetEvent.java +23 -0
  15. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/events/SingularLinkResolvedEvent.java +44 -0
  16. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/CreateReferrerShortLinkOptions.java +61 -0
  17. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/InitializeOptions.java +168 -0
  18. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/SetCustomUserIdOptions.java +24 -0
  19. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/SetDeviceTokenOptions.java +24 -0
  20. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/SetGlobalPropertyOptions.java +44 -0
  21. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/SetLimitAdvertisingIdentifiersOptions.java +22 -0
  22. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/SetLimitDataSharingOptions.java +22 -0
  23. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/TrackAdRevenueOptions.java +157 -0
  24. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/TrackEventOptions.java +35 -0
  25. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/TrackRevenueOptions.java +56 -0
  26. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/options/UnsetGlobalPropertyOptions.java +24 -0
  27. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/results/CreateReferrerShortLinkResult.java +23 -0
  28. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/results/GetGlobalPropertiesResult.java +31 -0
  29. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/results/GetLimitDataSharingResult.java +22 -0
  30. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/classes/results/IsAllTrackingStoppedResult.java +22 -0
  31. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/interfaces/Callback.java +5 -0
  32. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/interfaces/EmptyCallback.java +5 -0
  33. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/interfaces/NonEmptyResultCallback.java +7 -0
  34. package/android/src/main/java/io/capawesome/capacitorjs/plugins/singular/interfaces/Result.java +7 -0
  35. package/android/src/main/res/.gitkeep +0 -0
  36. package/dist/docs.json +2014 -0
  37. package/dist/esm/definitions.d.ts +925 -0
  38. package/dist/esm/definitions.js +39 -0
  39. package/dist/esm/definitions.js.map +1 -0
  40. package/dist/esm/index.d.ts +4 -0
  41. package/dist/esm/index.js +7 -0
  42. package/dist/esm/index.js.map +1 -0
  43. package/dist/esm/web.d.ts +27 -0
  44. package/dist/esm/web.js +73 -0
  45. package/dist/esm/web.js.map +1 -0
  46. package/dist/plugin.cjs.js +126 -0
  47. package/dist/plugin.cjs.js.map +1 -0
  48. package/dist/plugin.js +129 -0
  49. package/dist/plugin.js.map +1 -0
  50. package/ios/Plugin/Classes/Events/DeviceAttributionInfoReceivedEvent.swift +43 -0
  51. package/ios/Plugin/Classes/Events/SdidReceivedEvent.swift +16 -0
  52. package/ios/Plugin/Classes/Events/SdidSetEvent.swift +16 -0
  53. package/ios/Plugin/Classes/Events/SingularLinkResolvedEvent.swift +28 -0
  54. package/ios/Plugin/Classes/Events/SkanConversionValueUpdatedEvent.swift +30 -0
  55. package/ios/Plugin/Classes/Options/CreateReferrerShortLinkOptions.swift +25 -0
  56. package/ios/Plugin/Classes/Options/InitializeOptions.swift +44 -0
  57. package/ios/Plugin/Classes/Options/SetCustomUserIdOptions.swift +13 -0
  58. package/ios/Plugin/Classes/Options/SetDeviceTokenOptions.swift +30 -0
  59. package/ios/Plugin/Classes/Options/SetGlobalPropertyOptions.swift +20 -0
  60. package/ios/Plugin/Classes/Options/SetLimitAdvertisingIdentifiersOptions.swift +13 -0
  61. package/ios/Plugin/Classes/Options/SetLimitDataSharingOptions.swift +13 -0
  62. package/ios/Plugin/Classes/Options/SkanUpdateConversionValueOptions.swift +27 -0
  63. package/ios/Plugin/Classes/Options/TrackAdRevenueOptions.swift +47 -0
  64. package/ios/Plugin/Classes/Options/TrackEventOptions.swift +15 -0
  65. package/ios/Plugin/Classes/Options/TrackRevenueOptions.swift +22 -0
  66. package/ios/Plugin/Classes/Options/UnsetGlobalPropertyOptions.swift +13 -0
  67. package/ios/Plugin/Classes/Results/CreateReferrerShortLinkResult.swift +16 -0
  68. package/ios/Plugin/Classes/Results/GetGlobalPropertiesResult.swift +16 -0
  69. package/ios/Plugin/Classes/Results/GetLimitDataSharingResult.swift +16 -0
  70. package/ios/Plugin/Classes/Results/IsAllTrackingStoppedResult.swift +16 -0
  71. package/ios/Plugin/Classes/Results/SkanGetConversionValueResult.swift +20 -0
  72. package/ios/Plugin/Enums/CustomError.swift +88 -0
  73. package/ios/Plugin/Enums/SkanCoarseConversionValue.swift +31 -0
  74. package/ios/Plugin/Info.plist +24 -0
  75. package/ios/Plugin/Protocols/Result.swift +6 -0
  76. package/ios/Plugin/Singular.swift +341 -0
  77. package/ios/Plugin/SingularHelper.swift +40 -0
  78. package/ios/Plugin/SingularPlugin.swift +340 -0
  79. package/package.json +102 -0
@@ -0,0 +1,341 @@
1
+ import Foundation
2
+ import Capacitor
3
+ import Singular
4
+
5
+ @objc public class SingularImpl: NSObject {
6
+ private var initializeOptions: InitializeOptions?
7
+ private var initialized = false
8
+ private let plugin: SingularPlugin
9
+
10
+ init(plugin: SingularPlugin) {
11
+ self.plugin = plugin
12
+ super.init()
13
+ NotificationCenter.default.addObserver(
14
+ self,
15
+ selector: #selector(handleOpenUrl(_:)),
16
+ name: Notification.Name.capacitorOpenURL,
17
+ object: nil
18
+ )
19
+ NotificationCenter.default.addObserver(
20
+ self,
21
+ selector: #selector(handleOpenUrl(_:)),
22
+ name: Notification.Name.capacitorOpenUniversalLink,
23
+ object: nil
24
+ )
25
+ }
26
+
27
+ deinit {
28
+ NotificationCenter.default.removeObserver(self)
29
+ }
30
+
31
+ @objc public func clearGlobalProperties(completion: @escaping (_ error: Error?) -> Void) throws {
32
+ try requireInitialized()
33
+ Singular.clearGlobalProperties()
34
+ completion(nil)
35
+ }
36
+
37
+ @objc public func createReferrerShortLink(_ options: CreateReferrerShortLinkOptions, completion: @escaping (_ result: CreateReferrerShortLinkResult?, _ error: Error?) -> Void) throws {
38
+ try requireInitialized()
39
+ Singular.createReferrerShortLink(
40
+ options.baseLink,
41
+ referrerName: options.referrerName,
42
+ referrerId: options.referrerId,
43
+ passthroughParams: options.passthroughParameters,
44
+ completionHandler: { link, error in
45
+ if let error = error {
46
+ completion(nil, error)
47
+ } else if let link = link {
48
+ completion(CreateReferrerShortLinkResult(link: link), nil)
49
+ } else {
50
+ completion(nil, CustomError.shortLinkNotCreated)
51
+ }
52
+ }
53
+ )
54
+ }
55
+
56
+ @objc public func getGlobalProperties(completion: @escaping (_ result: GetGlobalPropertiesResult?, _ error: Error?) -> Void) throws {
57
+ try requireInitialized()
58
+ completion(GetGlobalPropertiesResult(properties: Singular.getGlobalProperties()), nil)
59
+ }
60
+
61
+ @objc public func getLimitDataSharing(completion: @escaping (_ result: GetLimitDataSharingResult?, _ error: Error?) -> Void) throws {
62
+ try requireInitialized()
63
+ completion(GetLimitDataSharingResult(limit: Singular.getLimitDataSharing()), nil)
64
+ }
65
+
66
+ @objc public func initialize(_ options: InitializeOptions, completion: @escaping (_ error: Error?) -> Void) {
67
+ initializeOptions = options
68
+ if let customUserId = options.customUserId {
69
+ Singular.setCustomUserId(customUserId)
70
+ }
71
+ if let limitDataSharing = options.limitDataSharing {
72
+ Singular.limitDataSharing(limitDataSharing)
73
+ }
74
+ Singular.setSessionTimeout(Int32(options.sessionTimeout))
75
+ guard let config = createConfig(options, url: ApplicationDelegateProxy.shared.lastURL) else {
76
+ completion(CustomError.initializationFailed)
77
+ return
78
+ }
79
+ // The return value of `start` reports whether a Singular Link was resolved, not whether the SDK was started.
80
+ _ = Singular.start(config)
81
+ initialized = true
82
+ completion(nil)
83
+ }
84
+
85
+ @objc public func isAllTrackingStopped(completion: @escaping (_ result: IsAllTrackingStoppedResult?, _ error: Error?) -> Void) throws {
86
+ try requireInitialized()
87
+ completion(IsAllTrackingStoppedResult(stopped: Singular.isAllTrackingStopped()), nil)
88
+ }
89
+
90
+ @objc public func resumeAllTracking(completion: @escaping (_ error: Error?) -> Void) throws {
91
+ try requireInitialized()
92
+ Singular.resumeAllTracking()
93
+ completion(nil)
94
+ }
95
+
96
+ @objc public func setCustomUserId(_ options: SetCustomUserIdOptions, completion: @escaping (_ error: Error?) -> Void) throws {
97
+ try requireInitialized()
98
+ Singular.setCustomUserId(options.customUserId)
99
+ completion(nil)
100
+ }
101
+
102
+ @objc public func setDeviceToken(_ options: SetDeviceTokenOptions, completion: @escaping (_ error: Error?) -> Void) throws {
103
+ try requireInitialized()
104
+ Singular.registerDeviceToken(forUninstall: options.token)
105
+ completion(nil)
106
+ }
107
+
108
+ @objc public func setGlobalProperty(_ options: SetGlobalPropertyOptions, completion: @escaping (_ error: Error?) -> Void) throws {
109
+ try requireInitialized()
110
+ guard Singular.setGlobalProperty(options.key, andValue: options.value, overrideExisting: options.overrideExisting) else {
111
+ completion(CustomError.globalPropertyNotSet)
112
+ return
113
+ }
114
+ completion(nil)
115
+ }
116
+
117
+ @objc public func setLimitAdvertisingIdentifiers(_ options: SetLimitAdvertisingIdentifiersOptions, completion: @escaping (_ error: Error?) -> Void) throws {
118
+ try requireInitialized()
119
+ Singular.setLimitAdvertisingIdentifiers(options.limit)
120
+ completion(nil)
121
+ }
122
+
123
+ @objc public func setLimitDataSharing(_ options: SetLimitDataSharingOptions, completion: @escaping (_ error: Error?) -> Void) throws {
124
+ try requireInitialized()
125
+ Singular.limitDataSharing(options.limit)
126
+ completion(nil)
127
+ }
128
+
129
+ @objc public func skanGetConversionValue(completion: @escaping (_ result: SkanGetConversionValueResult?, _ error: Error?) -> Void) throws {
130
+ try requireInitialized()
131
+ completion(SkanGetConversionValueResult(value: Singular.skanGetConversionValue()), nil)
132
+ }
133
+
134
+ @objc public func skanRegisterAppForAdNetworkAttribution(completion: @escaping (_ error: Error?) -> Void) throws {
135
+ try requireInitialized()
136
+ Singular.skanRegisterAppForAdNetworkAttribution()
137
+ completion(nil)
138
+ }
139
+
140
+ @objc public func skanUpdateConversionValue(_ options: SkanUpdateConversionValueOptions, completion: @escaping (_ error: Error?) -> Void) throws {
141
+ try requireInitialized()
142
+ if options.coarseValue != nil || options.lockWindow != nil {
143
+ Singular.skanUpdateConversionValue(options.value, coarse: options.coarseValue?.skanValue ?? 0, lock: options.lockWindow ?? false)
144
+ completion(nil)
145
+ return
146
+ }
147
+ guard Singular.skanUpdateConversionValue(options.value) else {
148
+ completion(CustomError.conversionValueNotUpdated)
149
+ return
150
+ }
151
+ completion(nil)
152
+ }
153
+
154
+ @objc public func stopAllTracking(completion: @escaping (_ error: Error?) -> Void) throws {
155
+ try requireInitialized()
156
+ Singular.stopAllTracking()
157
+ completion(nil)
158
+ }
159
+
160
+ @objc public func trackAdRevenue(_ options: TrackAdRevenueOptions, completion: @escaping (_ error: Error?) -> Void) throws {
161
+ try requireInitialized()
162
+ Singular.adRevenue(createAdData(options))
163
+ completion(nil)
164
+ }
165
+
166
+ @objc public func trackEvent(_ options: TrackEventOptions, completion: @escaping (_ error: Error?) -> Void) throws {
167
+ try requireInitialized()
168
+ if let attributes = options.attributes {
169
+ Singular.event(options.name, withArgs: attributes)
170
+ } else {
171
+ Singular.event(options.name)
172
+ }
173
+ completion(nil)
174
+ }
175
+
176
+ @objc public func trackRevenue(_ options: TrackRevenueOptions, completion: @escaping (_ error: Error?) -> Void) throws {
177
+ try requireInitialized()
178
+ if let eventName = options.eventName {
179
+ if let attributes = options.attributes {
180
+ Singular.customRevenue(eventName, currency: options.currency, amount: options.amount, withAttributes: attributes)
181
+ } else {
182
+ Singular.customRevenue(eventName, currency: options.currency, amount: options.amount)
183
+ }
184
+ } else if let attributes = options.attributes {
185
+ Singular.revenue(options.currency, amount: options.amount, withAttributes: attributes)
186
+ } else {
187
+ Singular.revenue(options.currency, amount: options.amount)
188
+ }
189
+ completion(nil)
190
+ }
191
+
192
+ @objc public func trackingOptIn(completion: @escaping (_ error: Error?) -> Void) throws {
193
+ try requireInitialized()
194
+ Singular.trackingOptIn()
195
+ completion(nil)
196
+ }
197
+
198
+ @objc public func trackingUnder13(completion: @escaping (_ error: Error?) -> Void) throws {
199
+ try requireInitialized()
200
+ Singular.trackingUnder13()
201
+ completion(nil)
202
+ }
203
+
204
+ @objc public func unsetCustomUserId(completion: @escaping (_ error: Error?) -> Void) throws {
205
+ try requireInitialized()
206
+ Singular.unsetCustomUserId()
207
+ completion(nil)
208
+ }
209
+
210
+ @objc public func unsetGlobalProperty(_ options: UnsetGlobalPropertyOptions, completion: @escaping (_ error: Error?) -> Void) throws {
211
+ try requireInitialized()
212
+ Singular.unsetGlobalProperty(options.key)
213
+ completion(nil)
214
+ }
215
+
216
+ private func createAdData(_ options: TrackAdRevenueOptions) -> SingularAdData {
217
+ let adData = SingularAdData(
218
+ adPlatform: options.adPlatform,
219
+ withCurrency: options.currency,
220
+ withRevenue: NSNumber(value: options.revenue)
221
+ )
222
+ if let adGroupId = options.adGroupId {
223
+ adData.setAdGroupId(adGroupId)
224
+ }
225
+ if let adGroupName = options.adGroupName {
226
+ adData.setAdGroupName(adGroupName)
227
+ }
228
+ if let adGroupPriority = options.adGroupPriority {
229
+ adData.setAdGroupPriority(adGroupPriority)
230
+ }
231
+ if let adGroupType = options.adGroupType {
232
+ adData.setGroupType(adGroupType)
233
+ }
234
+ if let adPlacementName = options.adPlacementName {
235
+ adData.setAdPlacementName(adPlacementName)
236
+ }
237
+ if let adType = options.adType {
238
+ adData.setAdType(adType)
239
+ }
240
+ if let adUnitId = options.adUnitId {
241
+ adData.setAdUnitId(adUnitId)
242
+ }
243
+ if let adUnitName = options.adUnitName {
244
+ adData.setAdUnitName(adUnitName)
245
+ }
246
+ if let impressionId = options.impressionId {
247
+ adData.setImpressionId(impressionId)
248
+ }
249
+ if let networkName = options.networkName {
250
+ adData.setNetworkName(networkName)
251
+ }
252
+ if let placementId = options.placementId {
253
+ adData.setPlacementId(placementId)
254
+ }
255
+ if let precision = options.precision {
256
+ adData.setPrecision(precision)
257
+ }
258
+ return adData
259
+ }
260
+
261
+ private func createConfig(_ options: InitializeOptions, url: URL?) -> SingularConfig? {
262
+ guard let config = SingularConfig(apiKey: options.apiKey, andSecret: options.secret) else {
263
+ return nil
264
+ }
265
+ config.openUrl = url
266
+ config.shortLinkResolveTimeOut = options.shortLinkResolveTimeout
267
+ if let brandedDomains = options.brandedDomains {
268
+ config.brandedDomains = brandedDomains
269
+ }
270
+ if let customSdid = options.customSdid {
271
+ config.customSdid = customSdid
272
+ }
273
+ if let espDomains = options.espDomains {
274
+ config.espDomains = espDomains
275
+ }
276
+ config.limitAdvertisingIdentifiers = options.limitAdvertisingIdentifiers
277
+ config.manualSkanConversionManagement = options.iosManualSkanConversionManagement
278
+ config.skAdNetworkEnabled = options.iosSkAdNetworkEnabled
279
+ config.waitForTrackingAuthorizationWithTimeoutInterval = options.iosWaitForTrackingAuthorizationTimeout
280
+ if options.loggingEnabled {
281
+ config.enableLogging = true
282
+ config.logLevel = SingularLogLevel.debug
283
+ }
284
+ for (key, value) in options.globalProperties ?? [:] {
285
+ config.setGlobalProperty(key, withValue: value, overrideExisting: true)
286
+ }
287
+ setHandlers(config)
288
+ return config
289
+ }
290
+
291
+ @objc private func handleOpenUrl(_ notification: Notification) {
292
+ guard initialized, let options = initializeOptions else {
293
+ return
294
+ }
295
+ guard let object = notification.object as? [String: Any], let url = object["url"] as? URL else {
296
+ return
297
+ }
298
+ guard let config = createConfig(options, url: url) else {
299
+ return
300
+ }
301
+ _ = Singular.start(config)
302
+ }
303
+
304
+ private func requireInitialized() throws {
305
+ guard initialized else {
306
+ throw CustomError.notInitialized
307
+ }
308
+ }
309
+
310
+ private func setHandlers(_ config: SingularConfig) {
311
+ config.deviceAttributionCallback = { [weak self] info in
312
+ guard let info = info else {
313
+ return
314
+ }
315
+ self?.plugin.notifyDeviceAttributionInfoReceivedListeners(DeviceAttributionInfoReceivedEvent(info: info))
316
+ }
317
+ config.sdidReceivedHandler = { [weak self] sdid in
318
+ guard let sdid = sdid else {
319
+ return
320
+ }
321
+ self?.plugin.notifySdidReceivedListeners(SdidReceivedEvent(sdid: sdid))
322
+ }
323
+ config.didSetSdidHandler = { [weak self] sdid in
324
+ guard let sdid = sdid else {
325
+ return
326
+ }
327
+ self?.plugin.notifySdidSetListeners(SdidSetEvent(sdid: sdid))
328
+ }
329
+ config.singularLinksHandler = { [weak self] params in
330
+ guard let params = params else {
331
+ return
332
+ }
333
+ self?.plugin.notifySingularLinkResolvedListeners(SingularLinkResolvedEvent(params: params))
334
+ }
335
+ config.conversionValuesUpdatedCallback = { [weak self] value, coarseValue, lockWindow in
336
+ self?.plugin.notifySkanConversionValueUpdatedListeners(
337
+ SkanConversionValueUpdatedEvent(value: value, coarseValue: coarseValue, lockWindow: lockWindow)
338
+ )
339
+ }
340
+ }
341
+ }
@@ -0,0 +1,40 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ public class SingularHelper {
5
+ public static func createHashMapFromJSObject(_ object: JSObject?) -> [String: Any]? {
6
+ guard let object = object else {
7
+ return nil
8
+ }
9
+ var map: [String: Any] = [:]
10
+ for key in object.keys {
11
+ if let value = object[key] {
12
+ map[key] = value
13
+ }
14
+ }
15
+ return map
16
+ }
17
+
18
+ public static func createStringHashMapFromJSObject(_ object: JSObject?) -> [String: String]? {
19
+ guard let object = object else {
20
+ return nil
21
+ }
22
+ var map: [String: String] = [:]
23
+ for key in object.keys {
24
+ if let value = object[key] as? String {
25
+ map[key] = value
26
+ }
27
+ }
28
+ return map
29
+ }
30
+
31
+ public static func createStringJSObjectFromHashMap(_ map: [AnyHashable: Any]?) -> JSObject {
32
+ var object = JSObject()
33
+ for (key, value) in map ?? [:] {
34
+ if let key = key as? String, let value = value as? String {
35
+ object[key] = value
36
+ }
37
+ }
38
+ return object
39
+ }
40
+ }