@capacitor-plus/ios 8.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/Capacitor/Capacitor/AppUUID.swift +51 -0
  2. package/Capacitor/Capacitor/Array+Capacitor.swift +31 -0
  3. package/Capacitor/Capacitor/CAPApplicationDelegateProxy.swift +32 -0
  4. package/Capacitor/Capacitor/CAPBridge.swift +25 -0
  5. package/Capacitor/Capacitor/CAPBridgeDelegate.swift +6 -0
  6. package/Capacitor/Capacitor/CAPBridgeProtocol.swift +148 -0
  7. package/Capacitor/Capacitor/CAPBridgeViewController+CDVScreenOrientationDelegate.h +6 -0
  8. package/Capacitor/Capacitor/CAPBridgeViewController+CDVScreenOrientationDelegate.m +5 -0
  9. package/Capacitor/Capacitor/CAPBridgeViewController.swift +384 -0
  10. package/Capacitor/Capacitor/CAPBridgedJSTypes.h +18 -0
  11. package/Capacitor/Capacitor/CAPBridgedJSTypes.m +43 -0
  12. package/Capacitor/Capacitor/CAPBridgedPlugin+getMethod.swift +13 -0
  13. package/Capacitor/Capacitor/CAPBridgedPlugin.h +41 -0
  14. package/Capacitor/Capacitor/CAPFile.swift +14 -0
  15. package/Capacitor/Capacitor/CAPInstanceConfiguration.h +38 -0
  16. package/Capacitor/Capacitor/CAPInstanceConfiguration.m +93 -0
  17. package/Capacitor/Capacitor/CAPInstanceConfiguration.swift +78 -0
  18. package/Capacitor/Capacitor/CAPInstanceDescriptor.h +167 -0
  19. package/Capacitor/Capacitor/CAPInstanceDescriptor.m +56 -0
  20. package/Capacitor/Capacitor/CAPInstanceDescriptor.swift +198 -0
  21. package/Capacitor/Capacitor/CAPInstancePlugin.swift +10 -0
  22. package/Capacitor/Capacitor/CAPLog.swift +11 -0
  23. package/Capacitor/Capacitor/CAPNotifications.swift +69 -0
  24. package/Capacitor/Capacitor/CAPPlugin+LoadInstance.swift +20 -0
  25. package/Capacitor/Capacitor/CAPPlugin.h +60 -0
  26. package/Capacitor/Capacitor/CAPPlugin.m +180 -0
  27. package/Capacitor/Capacitor/CAPPluginCall.h +25 -0
  28. package/Capacitor/Capacitor/CAPPluginCall.m +36 -0
  29. package/Capacitor/Capacitor/CAPPluginCall.swift +97 -0
  30. package/Capacitor/Capacitor/CAPPluginMethod.h +36 -0
  31. package/Capacitor/Capacitor/CAPPluginMethod.m +44 -0
  32. package/Capacitor/Capacitor/CAPPluginMethod.swift +17 -0
  33. package/Capacitor/Capacitor/Capacitor.h +15 -0
  34. package/Capacitor/Capacitor/Capacitor.modulemap +8 -0
  35. package/Capacitor/Capacitor/CapacitorBridge.swift +768 -0
  36. package/Capacitor/Capacitor/CapacitorExtension.swift +24 -0
  37. package/Capacitor/Capacitor/Codable/JSValueDecoder.swift +479 -0
  38. package/Capacitor/Capacitor/Codable/JSValueEncoder.swift +671 -0
  39. package/Capacitor/Capacitor/Data+Capacitor.swift +22 -0
  40. package/Capacitor/Capacitor/DocLinks.swift +8 -0
  41. package/Capacitor/Capacitor/Info.plist +24 -0
  42. package/Capacitor/Capacitor/JS.swift +122 -0
  43. package/Capacitor/Capacitor/JSExport.swift +218 -0
  44. package/Capacitor/Capacitor/JSTypes.swift +254 -0
  45. package/Capacitor/Capacitor/KeyPath.swift +60 -0
  46. package/Capacitor/Capacitor/KeyValueStore.swift +303 -0
  47. package/Capacitor/Capacitor/NotificationHandlerProtocol.swift +6 -0
  48. package/Capacitor/Capacitor/NotificationRouter.swift +60 -0
  49. package/Capacitor/Capacitor/PluginCallResult.swift +106 -0
  50. package/Capacitor/Capacitor/PluginConfig.swift +56 -0
  51. package/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift +141 -0
  52. package/Capacitor/Capacitor/Plugins/CapacitorCookies.swift +57 -0
  53. package/Capacitor/Capacitor/Plugins/CapacitorHttp.swift +57 -0
  54. package/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift +225 -0
  55. package/Capacitor/Capacitor/Plugins/Console.swift +16 -0
  56. package/Capacitor/Capacitor/Plugins/HttpRequestHandler.swift +236 -0
  57. package/Capacitor/Capacitor/Plugins/SystemBars.swift +133 -0
  58. package/Capacitor/Capacitor/Plugins/WebView.swift +44 -0
  59. package/Capacitor/Capacitor/PrivacyInfo.xcprivacy +14 -0
  60. package/Capacitor/Capacitor/Router.swift +29 -0
  61. package/Capacitor/Capacitor/TmpViewController.swift +8 -0
  62. package/Capacitor/Capacitor/UIColor.swift +55 -0
  63. package/Capacitor/Capacitor/UIStatusBarManager+CAPHandleTapAction.m +37 -0
  64. package/Capacitor/Capacitor/WKWebView+Capacitor.m +15 -0
  65. package/Capacitor/Capacitor/WKWebView+Capacitor.swift +80 -0
  66. package/Capacitor/Capacitor/WebViewAssetHandler.swift +550 -0
  67. package/Capacitor/Capacitor/WebViewDelegationHandler.swift +361 -0
  68. package/Capacitor/Capacitor/assets/native-bridge.js +1029 -0
  69. package/Capacitor.podspec +23 -0
  70. package/CapacitorCordova/CapacitorCordova/CapacitorCordova.h +25 -0
  71. package/CapacitorCordova/CapacitorCordova/CapacitorCordova.modulemap +6 -0
  72. package/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.h +8 -0
  73. package/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.m +5 -0
  74. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDV.h +28 -0
  75. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailability.h +109 -0
  76. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailabilityDeprecated.h +21 -0
  77. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegate.h +49 -0
  78. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.h +39 -0
  79. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.m +149 -0
  80. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.h +31 -0
  81. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.m +81 -0
  82. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.h +52 -0
  83. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.m +116 -0
  84. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin+Resources.h +39 -0
  85. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin+Resources.m +38 -0
  86. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.h +76 -0
  87. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.m +136 -0
  88. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.h +25 -0
  89. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.m +77 -0
  90. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.h +82 -0
  91. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.m +216 -0
  92. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVScreenOrientationDelegate.h +33 -0
  93. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.h +27 -0
  94. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.m +74 -0
  95. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.h +30 -0
  96. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.m +37 -0
  97. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVWebViewProcessPoolFactory.h +34 -0
  98. package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVWebViewProcessPoolFactory.m +55 -0
  99. package/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.h +35 -0
  100. package/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.m +63 -0
  101. package/CapacitorCordova/CapacitorCordova/Info.plist +26 -0
  102. package/CapacitorCordova/CapacitorCordova/PrivacyInfo.xcprivacy +14 -0
  103. package/CapacitorCordova.podspec +26 -0
  104. package/LICENSE +21 -0
  105. package/package.json +33 -0
  106. package/scripts/pods_helpers.rb +12 -0
@@ -0,0 +1,671 @@
1
+ //
2
+ // JSValueEncoder.swift
3
+ // Capacitor
4
+ //
5
+ // Created by Steven Sherry on 12/8/23.
6
+ // Copyright © 2023 Drifty Co. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+ import Combine
11
+
12
+ /// An encoder than can encode ``JSValue`` objects from `Encodable` types
13
+ public final class JSValueEncoder: TopLevelEncoder {
14
+ /// The strategy to use when encoding `nil` values
15
+ public enum OptionalEncodingStrategy {
16
+ /// Encode `nil` values as `NSNull`
17
+ case explicitNulls
18
+ /// Excludes the value from the encoded object altogether
19
+ case undefined
20
+ }
21
+
22
+ /// The strategies available for encoding .nan, .infinity, and -.infinity
23
+ public enum NonConformingFloatEncodingStrategy: Equatable {
24
+ /// Throws an error when encountering an exceptional floating-point value
25
+ case `throw`
26
+ /// Converts to the provided strings
27
+ case convertToString(positiveInfinity: String, negativeInfinity: String, nan: String)
28
+ /// Encodes directly into an NSNumber
29
+ case deferred
30
+ }
31
+
32
+ /// The strategy to use when encoding `Date` values
33
+ public typealias DateEncodingStrategy = JSONEncoder.DateEncodingStrategy
34
+
35
+ /// The strategy to use when encoding `Data` values
36
+ public typealias DataEncodingStrategy = JSONEncoder.DataEncodingStrategy
37
+
38
+ fileprivate struct Options {
39
+ var optionalStrategy: OptionalEncodingStrategy
40
+ var dateStrategy: DateEncodingStrategy
41
+ var dataStrategy: DataEncodingStrategy
42
+ var nonConformingFloatStrategy: NonConformingFloatEncodingStrategy
43
+ }
44
+
45
+ private var options: Options
46
+
47
+ /// The strategy to use when encoding `nil` values
48
+ public var optionalEncodingStrategy: OptionalEncodingStrategy {
49
+ get { options.optionalStrategy }
50
+ set { options.optionalStrategy = newValue }
51
+ }
52
+
53
+ /// The strategy to use when encoding dates
54
+ public var dateEncodingStrategy: DateEncodingStrategy {
55
+ get { options.dateStrategy }
56
+ set { options.dateStrategy = newValue }
57
+ }
58
+
59
+ /// The encoding strategy to use when encoding raw data
60
+ public var dataEncodingStrategy: DataEncodingStrategy {
61
+ get { options.dataStrategy }
62
+ set { options.dataStrategy = newValue }
63
+ }
64
+
65
+ /// The encoding strategy to use when the encoder encounters exceptional floating-point values
66
+ public var nonConformingFloatEncodingStrategy: NonConformingFloatEncodingStrategy {
67
+ get { options.nonConformingFloatStrategy }
68
+ set { options.nonConformingFloatStrategy = newValue }
69
+ }
70
+
71
+ /// Creates a new `JSValueEncoder`
72
+ /// - Parameter optionalEncodingStrategy: The strategy to use when encoding `nil` values. Defaults to ``OptionalEncodingStrategy-swift.enum/undefined``
73
+ /// - Parameter dateEncodingStrategy: Defaults to `DateEncodingStrategy.deferredToDate`
74
+ /// - Parameter dataEncodingStrategy: Defaults to `DataEncodingStrategy.deferredToData`
75
+ /// - Parameter nonConformingFloatEncodingStategy: Defaults to ``NonConformingFloatEncodingStrategy-swift.enum/deferred``
76
+ public init(
77
+ optionalEncodingStrategy: OptionalEncodingStrategy = .undefined,
78
+ dateEncodingStrategy: DateEncodingStrategy = .deferredToDate,
79
+ dataEncodingStrategy: DataEncodingStrategy = .deferredToData,
80
+ nonConformingFloatEncodingStategy: NonConformingFloatEncodingStrategy = .deferred
81
+ ) {
82
+ self.options = .init(
83
+ optionalStrategy: optionalEncodingStrategy,
84
+ dateStrategy: dateEncodingStrategy,
85
+ dataStrategy: dataEncodingStrategy,
86
+ nonConformingFloatStrategy: nonConformingFloatEncodingStategy
87
+ )
88
+ }
89
+
90
+ /// Encodes an `Encodable` value to a ``JSValue``
91
+ /// - Parameter value: The value to encode to ``JSValue``
92
+ /// - Returns: The encoded ``JSValue``
93
+ /// - Throws: An error if the value could not be encoded as a ``JSValue``
94
+ public func encode<T>(_ value: T) throws -> JSValue where T: Encodable {
95
+ let encoder = _JSValueEncoder(options: options)
96
+ try encoder.encodeGeneric(value)
97
+ guard let value = encoder.data else {
98
+ throw EncodingError.invalidValue(
99
+ value,
100
+ .init(
101
+ codingPath: encoder.codingPath,
102
+ debugDescription: "\(value) was unable to be encoded as a JSValue"
103
+ )
104
+ )
105
+ }
106
+
107
+ return value
108
+ }
109
+
110
+ /// Encodes an `Encodable` value to a ``JSObject``
111
+ /// - Parameter value: The value to encode to a ``JSObject``
112
+ /// - Returns: The encoded ``JSObject``
113
+ /// - Throws: An error if the value could not be encoded as a ``JSObject``
114
+ ///
115
+ /// This method is a convenience method for encoding an `Encodable` value to a ``JSObject``.
116
+ /// It is equivalent to calling ``encode(_:)`` and casting the result to a ``JSObject`` and
117
+ /// throwing an error if the cast fails.
118
+ public func encodeJSObject<T>(_ value: T) throws -> JSObject where T: Encodable {
119
+ guard let object = try encode(value) as? JSObject else {
120
+ throw EncodingError.invalidValue(
121
+ value,
122
+ .init(
123
+ codingPath: [],
124
+ debugDescription: "\(value) was unable to be encoded as a JSObject"
125
+ )
126
+ )
127
+ }
128
+
129
+ return object
130
+ }
131
+ }
132
+
133
+ private protocol JSValueEncodingContainer {
134
+ var data: JSValue? { get }
135
+ }
136
+
137
+ private enum EncodingContainer: JSValueEncodingContainer {
138
+ case singleValue(SingleValueContainer)
139
+ case unkeyed(UnkeyedContainer)
140
+ case keyed(AnyKeyedContainer)
141
+
142
+ var data: JSValue? {
143
+ switch self {
144
+ case let .singleValue(container):
145
+ return container.data
146
+ case let .unkeyed(container):
147
+ return container.data
148
+ case let .keyed(container):
149
+ return container.data
150
+ }
151
+ }
152
+
153
+ var type: String {
154
+ switch self {
155
+ case .singleValue:
156
+ "SingleValueContainer"
157
+ case .unkeyed:
158
+ "UnkeyedContainer"
159
+ case .keyed:
160
+ "KeyedContainer"
161
+ }
162
+ }
163
+ }
164
+
165
+ private typealias Options = JSValueEncoder.Options
166
+
167
+ private final class _JSValueEncoder: JSValueEncodingContainer {
168
+ var codingPath: [CodingKey] = []
169
+ var data: JSValue? {
170
+ containers.data
171
+ }
172
+
173
+ var options: Options
174
+
175
+ var userInfo: CodingUserInfo = [:]
176
+ fileprivate var containers: [EncodingContainer] = []
177
+
178
+ init(options: Options) {
179
+ self.options = options
180
+ }
181
+ }
182
+
183
+ extension Array: JSValueEncodingContainer where Element == EncodingContainer {
184
+ var data: JSValue? {
185
+ guard count != 0 else { return nil }
186
+ guard count != 1 else { return self[0].data }
187
+ var data: (any JSValue)?
188
+
189
+ for container in self {
190
+ if data == nil {
191
+ data = container.data
192
+ } else {
193
+ // The top-level container is
194
+ switch container {
195
+ case let .keyed(container):
196
+ guard let obj = data as? JSObject else { break }
197
+ data = obj.merging(container.object() ?? [:]) { $1 }
198
+ case let .unkeyed(container):
199
+ guard var copy = data as? JSArray else { break }
200
+ copy.append(contentsOf: container.array ?? [])
201
+ data = copy
202
+ default:
203
+ break
204
+ }
205
+ }
206
+ }
207
+
208
+ return data
209
+ }
210
+ }
211
+
212
+ private enum EncodedValue {
213
+ case value(any JSValue)
214
+ case nestedContainer(any JSValueEncodingContainer)
215
+ }
216
+
217
+ extension _JSValueEncoder: Encoder {
218
+ func addContainer(_ container: EncodingContainer) {
219
+ guard !containers.isEmpty else {
220
+ containers.append(container)
221
+ return
222
+ }
223
+
224
+ for existingContainer in containers {
225
+ switch (existingContainer, container) {
226
+ case (.unkeyed, .unkeyed), (.keyed, .keyed):
227
+ containers.append(container)
228
+ default:
229
+ preconditionFailure("Sibling top-level containers must be of the same type. Attempted to add a \(container)")
230
+ }
231
+ }
232
+ }
233
+
234
+ func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key: CodingKey {
235
+ let container = KeyedContainer<Key>(
236
+ codingPath: codingPath,
237
+ userInfo: userInfo,
238
+ options: options
239
+ )
240
+ addContainer(.keyed(.init(container)))
241
+ return KeyedEncodingContainer(container)
242
+ }
243
+
244
+ func unkeyedContainer() -> UnkeyedEncodingContainer {
245
+ let container = UnkeyedContainer(
246
+ codingPath: codingPath,
247
+ userInfo: userInfo,
248
+ options: options
249
+ )
250
+ addContainer(.unkeyed(container))
251
+ return container
252
+ }
253
+
254
+ func singleValueContainer() -> SingleValueEncodingContainer {
255
+ let container = SingleValueContainer(
256
+ codingPath: codingPath,
257
+ userInfo: userInfo,
258
+ options: options
259
+ )
260
+ addContainer(.singleValue(container))
261
+ return container
262
+ }
263
+
264
+ fileprivate func encodeGeneric<T>(_ value: T) throws where T: Encodable {
265
+ switch value {
266
+ case let value as Date:
267
+ switch options.dateStrategy {
268
+ case .deferredToDate:
269
+ try value.encode(to: self)
270
+ case .millisecondsSince1970:
271
+ try (value.timeIntervalSince1970 * Double(MSEC_PER_SEC)).encode(to: self)
272
+ case .secondsSince1970:
273
+ try value.timeIntervalSince1970.encode(to: self)
274
+ case .iso8601:
275
+ let formattedDate = ISO8601DateFormatter().string(from: value)
276
+ try formattedDate.encode(to: self)
277
+ case .formatted(let formatter):
278
+ let formattedDate = formatter.string(from: value)
279
+ try formattedDate.encode(to: self)
280
+ case .custom(let encode):
281
+ try encode(value, self)
282
+ @unknown default:
283
+ try value.encode(to: self)
284
+ }
285
+ case let value as URL:
286
+ try value.absoluteString.encode(to: self)
287
+ case let value as Data:
288
+ switch options.dataStrategy {
289
+ case .deferredToData:
290
+ try value.encode(to: self)
291
+ case .base64:
292
+ try value.base64EncodedString().encode(to: self)
293
+ case .custom(let encode):
294
+ try encode(value, self)
295
+ @unknown default:
296
+ try value.encode(to: self)
297
+ }
298
+ default:
299
+ try value.encode(to: self)
300
+ }
301
+ }
302
+ }
303
+
304
+ private final class KeyedContainer<Key> where Key: CodingKey {
305
+ var object: JSObject? {
306
+ encodedKeyedValue?.reduce(into: [:]) { obj, next in
307
+ let (key, value) = next
308
+ switch value {
309
+ case .value(let value):
310
+ obj[key] = value
311
+ case .nestedContainer(let container):
312
+ obj[key] = container.data
313
+ }
314
+ }
315
+ }
316
+
317
+ var codingPath: [CodingKey]
318
+ var userInfo: CodingUserInfo
319
+ var options: Options
320
+ private var encodedKeyedValue: [String: EncodedValue]?
321
+
322
+ init(codingPath: [CodingKey], userInfo: CodingUserInfo, options: Options) {
323
+ self.codingPath = codingPath
324
+ self.userInfo = userInfo
325
+ self.options = options
326
+ }
327
+ }
328
+
329
+ extension KeyedContainer: KeyedEncodingContainerProtocol {
330
+ func insert(_ value: JSValue, for key: Key) {
331
+ insert(.value(value), for: key)
332
+ }
333
+
334
+ func insert<K: CodingKey>(_ encodedValue: EncodedValue, for key: K) {
335
+ if encodedKeyedValue == nil {
336
+ encodedKeyedValue = [key.stringValue: encodedValue]
337
+ } else {
338
+ encodedKeyedValue![key.stringValue] = encodedValue
339
+ }
340
+ }
341
+
342
+ func encodeNil(forKey key: Key) throws {
343
+ insert(NSNull(), for: key)
344
+ }
345
+
346
+ func encode<T>(_ value: T, forKey key: Key) throws where T: Encodable {
347
+ let encoder = _JSValueEncoder(options: options)
348
+ try encoder.encodeGeneric(value)
349
+ insert(.nestedContainer(encoder), for: key)
350
+ }
351
+
352
+ // This is a perectly valid name for this method. The underscore is to avoid a conflict with the
353
+ // protocol requirement.
354
+ // swiftlint:disable:next identifier_name
355
+ func _encodeIfPresent<T>(_ value: T?, forKey key: Key) throws where T: Encodable {
356
+ switch options.optionalStrategy {
357
+ case .explicitNulls:
358
+ if let value = value {
359
+ try encode(value, forKey: key)
360
+ } else {
361
+ try encodeNil(forKey: key)
362
+ }
363
+ case .undefined:
364
+ guard let value = value else { return }
365
+ try encode(value, forKey: key)
366
+ }
367
+ }
368
+
369
+ func encodeIfPresent<T>(_ value: T?, forKey key: Key) throws where T: Encodable {
370
+ try _encodeIfPresent(value, forKey: key)
371
+ }
372
+
373
+ func encodeIfPresent(_ value: Bool?, forKey key: Key) throws {
374
+ try _encodeIfPresent(value, forKey: key)
375
+ }
376
+
377
+ func encodeIfPresent(_ value: String?, forKey key: Key) throws {
378
+ try _encodeIfPresent(value, forKey: key)
379
+ }
380
+
381
+ func encodeIfPresent(_ value: Double?, forKey key: Key) throws {
382
+ try _encodeIfPresent(value, forKey: key)
383
+ }
384
+
385
+ func encodeIfPresent(_ value: Float?, forKey key: Key) throws {
386
+ try _encodeIfPresent(value, forKey: key)
387
+ }
388
+
389
+ func encodeIfPresent(_ value: Int?, forKey key: Key) throws {
390
+ try _encodeIfPresent(value, forKey: key)
391
+ }
392
+
393
+ func encodeIfPresent(_ value: Int8?, forKey key: Key) throws {
394
+ try _encodeIfPresent(value, forKey: key)
395
+ }
396
+
397
+ func encodeIfPresent(_ value: Int16?, forKey key: Key) throws {
398
+ try _encodeIfPresent(value, forKey: key)
399
+ }
400
+
401
+ func encodeIfPresent(_ value: Int32?, forKey key: Key) throws {
402
+ try _encodeIfPresent(value, forKey: key)
403
+ }
404
+
405
+ func encodeIfPresent(_ value: Int64?, forKey key: Key) throws {
406
+ try _encodeIfPresent(value, forKey: key)
407
+ }
408
+
409
+ func encodeIfPresent(_ value: UInt?, forKey key: Key) throws {
410
+ try _encodeIfPresent(value, forKey: key)
411
+ }
412
+
413
+ func encodeIfPresent(_ value: UInt8?, forKey key: Key) throws {
414
+ try _encodeIfPresent(value, forKey: key)
415
+ }
416
+
417
+ func encodeIfPresent(_ value: UInt16?, forKey key: Key) throws {
418
+ try _encodeIfPresent(value, forKey: key)
419
+ }
420
+
421
+ func encodeIfPresent(_ value: UInt32?, forKey key: Key) throws {
422
+ try _encodeIfPresent(value, forKey: key)
423
+ }
424
+
425
+ func encodeIfPresent(_ value: UInt64?, forKey key: Key) throws {
426
+ try _encodeIfPresent(value, forKey: key)
427
+ }
428
+
429
+ func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer<NestedKey> where NestedKey: CodingKey {
430
+ var newPath = codingPath
431
+ newPath.append(key)
432
+
433
+ let nestedContainer = KeyedContainer<NestedKey>(
434
+ codingPath: newPath,
435
+ userInfo: userInfo,
436
+ options: options
437
+ )
438
+
439
+ insert(.nestedContainer(nestedContainer), for: key)
440
+ return KeyedEncodingContainer(nestedContainer)
441
+ }
442
+
443
+ func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer {
444
+ var newPath = codingPath
445
+ newPath.append(key)
446
+ let nestedContainer = UnkeyedContainer(
447
+ codingPath: codingPath,
448
+ userInfo: userInfo,
449
+ options: options
450
+ )
451
+ insert(.nestedContainer(nestedContainer), for: key)
452
+ return nestedContainer
453
+ }
454
+
455
+ enum SuperKey: String, CodingKey {
456
+ case `super`
457
+ }
458
+
459
+ func superEncoder() -> Encoder {
460
+ let encoder = _JSValueEncoder(options: options)
461
+ insert(.nestedContainer(encoder), for: SuperKey.super)
462
+ return encoder
463
+ }
464
+
465
+ func superEncoder(forKey key: Key) -> Encoder {
466
+ let encoder = _JSValueEncoder(options: options)
467
+ insert(.nestedContainer(encoder), for: key)
468
+ return encoder
469
+ }
470
+ }
471
+
472
+ private class AnyKeyedContainer: JSValueEncodingContainer {
473
+ var data: JSValue? { object() }
474
+ var object: () -> JSObject?
475
+
476
+ init<Key>(_ keyedContainer: KeyedContainer<Key>) where Key: CodingKey {
477
+ object = { keyedContainer.object }
478
+ }
479
+ }
480
+
481
+ extension KeyedContainer: JSValueEncodingContainer {
482
+ var data: JSValue? { object }
483
+ }
484
+
485
+ private final class UnkeyedContainer {
486
+ var array: JSArray? {
487
+ encodedUnkeyedValue?.reduce(into: []) { arr, next in
488
+ switch next {
489
+ case .value(let value):
490
+ arr.append(value)
491
+ case .nestedContainer(let container):
492
+ guard let data = container.data else { return }
493
+ arr.append(data)
494
+ }
495
+ }
496
+ }
497
+
498
+ var codingPath: [CodingKey]
499
+ var userInfo: CodingUserInfo
500
+ var options: Options
501
+ private var encodedUnkeyedValue: [EncodedValue]?
502
+
503
+ init(codingPath: [CodingKey], userInfo: CodingUserInfo, options: Options) {
504
+ self.codingPath = codingPath
505
+ self.userInfo = userInfo
506
+ self.options = options
507
+ }
508
+ }
509
+
510
+ extension UnkeyedContainer: UnkeyedEncodingContainer {
511
+ private func append(_ value: any JSValue) {
512
+ append(.value(value))
513
+ }
514
+
515
+ private func append(_ value: EncodedValue) {
516
+ if encodedUnkeyedValue == nil {
517
+ encodedUnkeyedValue = [value]
518
+ } else {
519
+ encodedUnkeyedValue!.append(value)
520
+ }
521
+ }
522
+
523
+ var count: Int {
524
+ array?.count ?? 0
525
+ }
526
+
527
+ func encodeNil() throws {
528
+ append(NSNull())
529
+ }
530
+
531
+ func encode<T>(_ value: T) throws where T: Encodable {
532
+ let encoder = _JSValueEncoder(options: options)
533
+ try encoder.encodeGeneric(value)
534
+ append(.nestedContainer(encoder))
535
+ }
536
+
537
+ func nestedUnkeyedContainer() -> UnkeyedEncodingContainer {
538
+ let nestedContainer = UnkeyedContainer(
539
+ codingPath: codingPath,
540
+ userInfo: userInfo,
541
+ options: options
542
+ )
543
+ append(.nestedContainer(nestedContainer))
544
+ return nestedContainer
545
+ }
546
+
547
+ func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> where NestedKey: CodingKey {
548
+ let nestedContainer = KeyedContainer<NestedKey>(
549
+ codingPath: codingPath,
550
+ userInfo: userInfo,
551
+ options: options
552
+ )
553
+ append(.nestedContainer(nestedContainer))
554
+ return KeyedEncodingContainer(nestedContainer)
555
+ }
556
+
557
+ func superEncoder() -> Encoder {
558
+ let encoder = _JSValueEncoder(options: options)
559
+ append(.nestedContainer(encoder))
560
+ return encoder
561
+ }
562
+ }
563
+
564
+ extension UnkeyedContainer: JSValueEncodingContainer {
565
+ var data: JSValue? { array }
566
+ }
567
+
568
+ private final class SingleValueContainer {
569
+ var data: JSValue?
570
+ var codingPath: [CodingKey]
571
+ var userInfo: CodingUserInfo
572
+ var options: Options
573
+
574
+ init(codingPath: [CodingKey], userInfo: CodingUserInfo, options: Options) {
575
+ self.codingPath = codingPath
576
+ self.userInfo = userInfo
577
+ self.options = options
578
+ }
579
+ }
580
+
581
+ extension SingleValueContainer: SingleValueEncodingContainer {
582
+ func encodeNil() throws {
583
+ data = NSNull()
584
+ }
585
+
586
+ func encode(_ value: Bool) throws {
587
+ data = value
588
+ }
589
+
590
+ func encode(_ value: String) throws {
591
+ data = value
592
+ }
593
+
594
+ func encode(_ value: Double) throws {
595
+ try encodeFloat(value)
596
+ }
597
+
598
+ // swiftlint:disable force_cast
599
+ private func encodeFloat<N>(_ value: N) throws where N: FloatingPoint {
600
+ if value.isFinite {
601
+ data = value as! NSNumber
602
+ } else {
603
+ switch options.nonConformingFloatStrategy {
604
+ case .deferred:
605
+ data = value as! NSNumber
606
+ case let .convertToString(positiveInfinity: pos, negativeInfinity: neg, nan: nan):
607
+ if value == .infinity { data = pos }
608
+ if value == -.infinity { data = neg }
609
+ if value.isNaN { data = nan }
610
+ case .throw:
611
+ throw EncodingError.invalidValue(
612
+ value,
613
+ .init(codingPath: codingPath, debugDescription: "Unable to encode \(value) to JSValue")
614
+ )
615
+ }
616
+ }
617
+ }
618
+ // swiftlint:enable force_cast
619
+
620
+ func encode(_ value: Float) throws {
621
+ try encodeFloat(value)
622
+ }
623
+
624
+ func encode(_ value: Int) throws {
625
+ data = value as NSNumber
626
+ }
627
+
628
+ func encode(_ value: Int8) throws {
629
+ data = value as NSNumber
630
+ }
631
+
632
+ func encode(_ value: Int16) throws {
633
+ data = value as NSNumber
634
+ }
635
+
636
+ func encode(_ value: Int32) throws {
637
+ data = value as NSNumber
638
+ }
639
+
640
+ func encode(_ value: Int64) throws {
641
+ data = value as NSNumber
642
+ }
643
+
644
+ func encode(_ value: UInt) throws {
645
+ data = value as NSNumber
646
+ }
647
+
648
+ func encode(_ value: UInt8) throws {
649
+ data = value as NSNumber
650
+ }
651
+
652
+ func encode(_ value: UInt16) throws {
653
+ data = value as NSNumber
654
+ }
655
+
656
+ func encode(_ value: UInt32) throws {
657
+ data = value as NSNumber
658
+ }
659
+
660
+ func encode(_ value: UInt64) throws {
661
+ data = value as NSNumber
662
+ }
663
+
664
+ func encode<T>(_ value: T) throws where T: Encodable {
665
+ let encoder = _JSValueEncoder(options: options)
666
+ try encoder.encodeGeneric(value)
667
+ data = encoder.data
668
+ }
669
+ }
670
+
671
+ extension SingleValueContainer: JSValueEncodingContainer {}
@@ -0,0 +1,22 @@
1
+ extension Data: CapacitorExtension {}
2
+ public extension CapacitorExtensionTypeWrapper where T == Data {
3
+
4
+ static func data(base64EncodedOrDataUrl: String) -> Data? {
5
+ if isBase64DataUrl(base64EncodedOrDataUrl) {
6
+ if let url = URL(string: base64EncodedOrDataUrl) {
7
+ do {
8
+ return try T(contentsOf: url)
9
+ } catch {
10
+ return nil
11
+ }
12
+ }
13
+ return nil
14
+ } else {
15
+ return T(base64Encoded: base64EncodedOrDataUrl)
16
+ }
17
+ }
18
+
19
+ private static func isBase64DataUrl(_ base64EncodedOrDataUrl: String) -> Bool {
20
+ return base64EncodedOrDataUrl.starts(with: "data:") && base64EncodedOrDataUrl.contains("base64,")
21
+ }
22
+ }
@@ -0,0 +1,8 @@
1
+ import Foundation
2
+
3
+ enum DocLinks: String {
4
+ case CAPPluginMethodSelector = "plugins/ios/#defining-methods"
5
+ case NSPhotoLibraryAddUsageDescription = "https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW73"
6
+ case NSPhotoLibraryUsageDescription = "https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW17"
7
+ case NSCameraUsageDescription = "https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW24"
8
+ }