@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.
- package/Capacitor/Capacitor/AppUUID.swift +51 -0
- package/Capacitor/Capacitor/Array+Capacitor.swift +31 -0
- package/Capacitor/Capacitor/CAPApplicationDelegateProxy.swift +32 -0
- package/Capacitor/Capacitor/CAPBridge.swift +25 -0
- package/Capacitor/Capacitor/CAPBridgeDelegate.swift +6 -0
- package/Capacitor/Capacitor/CAPBridgeProtocol.swift +148 -0
- package/Capacitor/Capacitor/CAPBridgeViewController+CDVScreenOrientationDelegate.h +6 -0
- package/Capacitor/Capacitor/CAPBridgeViewController+CDVScreenOrientationDelegate.m +5 -0
- package/Capacitor/Capacitor/CAPBridgeViewController.swift +384 -0
- package/Capacitor/Capacitor/CAPBridgedJSTypes.h +18 -0
- package/Capacitor/Capacitor/CAPBridgedJSTypes.m +43 -0
- package/Capacitor/Capacitor/CAPBridgedPlugin+getMethod.swift +13 -0
- package/Capacitor/Capacitor/CAPBridgedPlugin.h +41 -0
- package/Capacitor/Capacitor/CAPFile.swift +14 -0
- package/Capacitor/Capacitor/CAPInstanceConfiguration.h +38 -0
- package/Capacitor/Capacitor/CAPInstanceConfiguration.m +93 -0
- package/Capacitor/Capacitor/CAPInstanceConfiguration.swift +78 -0
- package/Capacitor/Capacitor/CAPInstanceDescriptor.h +167 -0
- package/Capacitor/Capacitor/CAPInstanceDescriptor.m +56 -0
- package/Capacitor/Capacitor/CAPInstanceDescriptor.swift +198 -0
- package/Capacitor/Capacitor/CAPInstancePlugin.swift +10 -0
- package/Capacitor/Capacitor/CAPLog.swift +11 -0
- package/Capacitor/Capacitor/CAPNotifications.swift +69 -0
- package/Capacitor/Capacitor/CAPPlugin+LoadInstance.swift +20 -0
- package/Capacitor/Capacitor/CAPPlugin.h +60 -0
- package/Capacitor/Capacitor/CAPPlugin.m +180 -0
- package/Capacitor/Capacitor/CAPPluginCall.h +25 -0
- package/Capacitor/Capacitor/CAPPluginCall.m +36 -0
- package/Capacitor/Capacitor/CAPPluginCall.swift +97 -0
- package/Capacitor/Capacitor/CAPPluginMethod.h +36 -0
- package/Capacitor/Capacitor/CAPPluginMethod.m +44 -0
- package/Capacitor/Capacitor/CAPPluginMethod.swift +17 -0
- package/Capacitor/Capacitor/Capacitor.h +15 -0
- package/Capacitor/Capacitor/Capacitor.modulemap +8 -0
- package/Capacitor/Capacitor/CapacitorBridge.swift +768 -0
- package/Capacitor/Capacitor/CapacitorExtension.swift +24 -0
- package/Capacitor/Capacitor/Codable/JSValueDecoder.swift +479 -0
- package/Capacitor/Capacitor/Codable/JSValueEncoder.swift +671 -0
- package/Capacitor/Capacitor/Data+Capacitor.swift +22 -0
- package/Capacitor/Capacitor/DocLinks.swift +8 -0
- package/Capacitor/Capacitor/Info.plist +24 -0
- package/Capacitor/Capacitor/JS.swift +122 -0
- package/Capacitor/Capacitor/JSExport.swift +218 -0
- package/Capacitor/Capacitor/JSTypes.swift +254 -0
- package/Capacitor/Capacitor/KeyPath.swift +60 -0
- package/Capacitor/Capacitor/KeyValueStore.swift +303 -0
- package/Capacitor/Capacitor/NotificationHandlerProtocol.swift +6 -0
- package/Capacitor/Capacitor/NotificationRouter.swift +60 -0
- package/Capacitor/Capacitor/PluginCallResult.swift +106 -0
- package/Capacitor/Capacitor/PluginConfig.swift +56 -0
- package/Capacitor/Capacitor/Plugins/CapacitorCookieManager.swift +141 -0
- package/Capacitor/Capacitor/Plugins/CapacitorCookies.swift +57 -0
- package/Capacitor/Capacitor/Plugins/CapacitorHttp.swift +57 -0
- package/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift +225 -0
- package/Capacitor/Capacitor/Plugins/Console.swift +16 -0
- package/Capacitor/Capacitor/Plugins/HttpRequestHandler.swift +236 -0
- package/Capacitor/Capacitor/Plugins/SystemBars.swift +133 -0
- package/Capacitor/Capacitor/Plugins/WebView.swift +44 -0
- package/Capacitor/Capacitor/PrivacyInfo.xcprivacy +14 -0
- package/Capacitor/Capacitor/Router.swift +29 -0
- package/Capacitor/Capacitor/TmpViewController.swift +8 -0
- package/Capacitor/Capacitor/UIColor.swift +55 -0
- package/Capacitor/Capacitor/UIStatusBarManager+CAPHandleTapAction.m +37 -0
- package/Capacitor/Capacitor/WKWebView+Capacitor.m +15 -0
- package/Capacitor/Capacitor/WKWebView+Capacitor.swift +80 -0
- package/Capacitor/Capacitor/WebViewAssetHandler.swift +550 -0
- package/Capacitor/Capacitor/WebViewDelegationHandler.swift +361 -0
- package/Capacitor/Capacitor/assets/native-bridge.js +1029 -0
- package/Capacitor.podspec +23 -0
- package/CapacitorCordova/CapacitorCordova/CapacitorCordova.h +25 -0
- package/CapacitorCordova/CapacitorCordova/CapacitorCordova.modulemap +6 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.h +8 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.m +5 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDV.h +28 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailability.h +109 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailabilityDeprecated.h +21 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegate.h +49 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.h +39 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.m +149 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.h +31 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.m +81 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.h +52 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.m +116 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin+Resources.h +39 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin+Resources.m +38 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.h +76 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.m +136 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.h +25 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.m +77 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.h +82 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.m +216 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVScreenOrientationDelegate.h +33 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.h +27 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.m +74 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.h +30 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.m +37 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVWebViewProcessPoolFactory.h +34 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/CDVWebViewProcessPoolFactory.m +55 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.h +35 -0
- package/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.m +63 -0
- package/CapacitorCordova/CapacitorCordova/Info.plist +26 -0
- package/CapacitorCordova/CapacitorCordova/PrivacyInfo.xcprivacy +14 -0
- package/CapacitorCordova.podspec +26 -0
- package/LICENSE +21 -0
- package/package.json +33 -0
- 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
|
+
}
|