@capacitor-plus/ios 8.3.10 → 8.3.12
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/CAPBridgeViewController.swift +17 -1
- package/Capacitor/Capacitor/CAPInstanceConfiguration.h +1 -0
- package/Capacitor/Capacitor/CAPInstanceConfiguration.m +7 -0
- package/Capacitor/Capacitor/CAPInstanceDescriptor.h +5 -0
- package/Capacitor/Capacitor/CAPInstanceDescriptor.swift +2 -0
- package/Capacitor/Capacitor/CapacitorBridge.swift +2 -2
- package/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift +1 -1
- package/Capacitor/Capacitor/assets/native-bridge.js +68 -18
- package/package.json +1 -1
|
@@ -10,6 +10,12 @@ import Cordova
|
|
|
10
10
|
|
|
11
11
|
public fileprivate(set) var webView: WKWebView?
|
|
12
12
|
|
|
13
|
+
// WKHTTPCookieStore does not retain observers, so we hold a strong reference here
|
|
14
|
+
// (else it deallocs immediately and `cookiesDidChange` never fires) plus the store
|
|
15
|
+
// it was added to, so the observer can be removed in `deinit` as the docs require.
|
|
16
|
+
private var cookieObserver: CapacitorWKCookieObserver?
|
|
17
|
+
private weak var cookieObserverStore: WKHTTPCookieStore?
|
|
18
|
+
|
|
13
19
|
public var isStatusBarVisible = true
|
|
14
20
|
public var statusBarStyle: UIStatusBarStyle = .default
|
|
15
21
|
public var statusBarAnimation: UIStatusBarAnimation = .fade
|
|
@@ -27,6 +33,12 @@ import Cordova
|
|
|
27
33
|
return false
|
|
28
34
|
}()
|
|
29
35
|
|
|
36
|
+
deinit {
|
|
37
|
+
if let cookieObserver = cookieObserver {
|
|
38
|
+
cookieObserverStore?.remove(cookieObserver)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
30
42
|
override public final func loadView() {
|
|
31
43
|
// load the configuration and set the logging flag
|
|
32
44
|
let configDescriptor = instanceDescriptor()
|
|
@@ -118,7 +130,11 @@ import Cordova
|
|
|
118
130
|
*/
|
|
119
131
|
open func webViewConfiguration(for instanceConfiguration: InstanceConfiguration) -> WKWebViewConfiguration {
|
|
120
132
|
let webViewConfiguration = WKWebViewConfiguration()
|
|
121
|
-
|
|
133
|
+
let cookieObserver = CapacitorWKCookieObserver()
|
|
134
|
+
let cookieStore = webViewConfiguration.websiteDataStore.httpCookieStore
|
|
135
|
+
cookieStore.add(cookieObserver)
|
|
136
|
+
self.cookieObserver = cookieObserver
|
|
137
|
+
self.cookieObserverStore = cookieStore
|
|
122
138
|
webViewConfiguration.allowsInlineMediaPlayback = true
|
|
123
139
|
webViewConfiguration.suppressesIncrementalRendering = false
|
|
124
140
|
webViewConfiguration.allowsAirPlayForMediaPlayback = true
|
|
@@ -13,6 +13,7 @@ NS_SWIFT_NAME(InstanceConfiguration)
|
|
|
13
13
|
@property (nonatomic, readonly, nonnull) NSArray<NSString*> *allowedNavigationHostnames;
|
|
14
14
|
@property (nonatomic, readonly, nonnull) NSURL *localURL;
|
|
15
15
|
@property (nonatomic, readonly, nonnull) NSURL *serverURL;
|
|
16
|
+
@property (nonatomic, readonly, nullable) NSURL *configURL;
|
|
16
17
|
@property (nonatomic, readonly, nullable) NSString *errorPath;
|
|
17
18
|
@property (nonatomic, readonly, nonnull) NSDictionary *pluginConfigurations;
|
|
18
19
|
@property (nonatomic, readonly) BOOL loggingEnabled;
|
|
@@ -49,6 +49,13 @@
|
|
|
49
49
|
else {
|
|
50
50
|
_serverURL = _localURL;
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
if (descriptor.configUrl != nil) {
|
|
54
|
+
_configURL = descriptor.configUrl;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
_configURL = [[NSURL alloc] initWithString:(@"capacitor.config.json")];
|
|
58
|
+
}
|
|
52
59
|
_errorPath = descriptor.errorPath;
|
|
53
60
|
// extract the one value we care about from the cordova configuration
|
|
54
61
|
_cordovaDeployDisabled = [descriptor cordovaDeployDisabled];
|
|
@@ -68,6 +68,11 @@ NS_SWIFT_NAME(InstanceDescriptor)
|
|
|
68
68
|
@discussion Defaults to nil, in which case the server URL will be constructed from @c urlScheme and @c urlHostname. If set, it will override the other properties. Set by @c server.url in the configuration file.
|
|
69
69
|
*/
|
|
70
70
|
@property (nonatomic, copy, nullable) NSString *serverURL;
|
|
71
|
+
/**
|
|
72
|
+
@brief The file URL from which Capacitor will load configuration
|
|
73
|
+
@discussion Defaults to @c capacitor.config.json located at the root of the application bundle.
|
|
74
|
+
*/
|
|
75
|
+
@property (nonatomic, copy, nullable) NSURL *configUrl;
|
|
71
76
|
/**
|
|
72
77
|
@brief The JSON dictionary that contains the plugin-specific configuration information.
|
|
73
78
|
@discussion Set by @c plugins in the configuration file.
|
|
@@ -30,6 +30,8 @@ internal extension InstanceDescriptor {
|
|
|
30
30
|
// swiftlint:disable function_body_length
|
|
31
31
|
// swiftlint:disable:next identifier_name
|
|
32
32
|
@objc func _parseConfiguration(at capacitorURL: URL?, cordovaConfiguration cordovaURL: URL?) {
|
|
33
|
+
configUrl = capacitorURL
|
|
34
|
+
|
|
33
35
|
// sanity check that the app directory is valid
|
|
34
36
|
var isDirectory: ObjCBool = ObjCBool(false)
|
|
35
37
|
if warnings.contains(.missingAppDir) == false,
|
|
@@ -305,9 +305,9 @@ open class CapacitorBridge: NSObject, CAPBridgeProtocol {
|
|
|
305
305
|
func registerPlugins() {
|
|
306
306
|
var pluginList: [AnyClass] = [CAPHttpPlugin.self, CAPConsolePlugin.self, CAPWebViewPlugin.self, CAPCookiesPlugin.self, CAPSystemBarsPlugin.self]
|
|
307
307
|
|
|
308
|
-
if autoRegisterPlugins {
|
|
308
|
+
if autoRegisterPlugins && config.configURL != nil {
|
|
309
309
|
do {
|
|
310
|
-
if let pluginJSON = Bundle.main.url(forResource:
|
|
310
|
+
if let pluginJSON = Bundle.main.url(forResource: (config.configURL!.path as NSString).deletingPathExtension, withExtension: "json") {
|
|
311
311
|
let pluginData = try Data(contentsOf: pluginJSON)
|
|
312
312
|
let registrationList = try JSONDecoder().decode(RegistrationList.self, from: pluginData)
|
|
313
313
|
|
|
@@ -172,7 +172,7 @@ open class CapacitorUrlRequest: NSObject, URLSessionTaskDelegate {
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
public func getRequestData(_ body: JSValue, _ contentType: String, _ dataType: String? = nil) throws -> Data? {
|
|
175
|
-
if dataType == "file" {
|
|
175
|
+
if dataType == "file" || dataType == "binary" {
|
|
176
176
|
guard let stringData = body as? String else {
|
|
177
177
|
throw CapacitorUrlRequestError.serializationError("[ data ] argument could not be parsed as string")
|
|
178
178
|
}
|
|
@@ -44,6 +44,33 @@ var nativeBridge = (function (exports) {
|
|
|
44
44
|
reader.onerror = reject;
|
|
45
45
|
reader.readAsBinaryString(file);
|
|
46
46
|
});
|
|
47
|
+
const readArrayBufferAsBase64 = (arrayBuffer) => {
|
|
48
|
+
const bytes = new Uint8Array(arrayBuffer);
|
|
49
|
+
const chunkSize = 0x8000;
|
|
50
|
+
let binary = '';
|
|
51
|
+
for (let i = 0; i < bytes.length; i += chunkSize) {
|
|
52
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
|
|
53
|
+
}
|
|
54
|
+
return btoa(binary);
|
|
55
|
+
};
|
|
56
|
+
const readBlobAsBase64 = (blob) => new Promise((resolve, reject) => {
|
|
57
|
+
const reader = new FileReader();
|
|
58
|
+
reader.onload = () => {
|
|
59
|
+
const result = reader.result;
|
|
60
|
+
resolve(result.indexOf(',') >= 0 ? result.split(',')[1] : result);
|
|
61
|
+
};
|
|
62
|
+
reader.onerror = reject;
|
|
63
|
+
reader.readAsDataURL(blob);
|
|
64
|
+
});
|
|
65
|
+
const readDataViewAsBase64 = (dataView) => readArrayBufferAsBase64(dataView.buffer.slice(dataView.byteOffset, dataView.byteOffset + dataView.byteLength));
|
|
66
|
+
const base64StringToArrayBuffer = (base64) => {
|
|
67
|
+
const binary = atob(base64);
|
|
68
|
+
const bytes = new Uint8Array(binary.length);
|
|
69
|
+
for (let i = 0; i < binary.length; i++) {
|
|
70
|
+
bytes[i] = binary.charCodeAt(i);
|
|
71
|
+
}
|
|
72
|
+
return bytes.buffer;
|
|
73
|
+
};
|
|
47
74
|
const convertFormData = async (formData) => {
|
|
48
75
|
const newFormData = [];
|
|
49
76
|
for (const pair of formData.entries()) {
|
|
@@ -65,9 +92,38 @@ var nativeBridge = (function (exports) {
|
|
|
65
92
|
return newFormData;
|
|
66
93
|
};
|
|
67
94
|
const convertBody = async (body, contentType) => {
|
|
68
|
-
if (body instanceof
|
|
95
|
+
if (body instanceof File) {
|
|
96
|
+
const fileData = await readFileAsBase64(body);
|
|
97
|
+
return {
|
|
98
|
+
data: fileData,
|
|
99
|
+
type: 'file',
|
|
100
|
+
headers: { 'Content-Type': body.type },
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else if (body instanceof Blob) {
|
|
104
|
+
return {
|
|
105
|
+
data: await readBlobAsBase64(body),
|
|
106
|
+
type: 'binary',
|
|
107
|
+
headers: { 'Content-Type': contentType || body.type || 'application/octet-stream' },
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
else if (body instanceof ArrayBuffer) {
|
|
111
|
+
return {
|
|
112
|
+
data: readArrayBufferAsBase64(body),
|
|
113
|
+
type: 'binary',
|
|
114
|
+
headers: { 'Content-Type': contentType || 'application/octet-stream' },
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
else if (ArrayBuffer.isView(body)) {
|
|
118
|
+
return {
|
|
119
|
+
data: readDataViewAsBase64(body),
|
|
120
|
+
type: 'binary',
|
|
121
|
+
headers: { 'Content-Type': contentType || 'application/octet-stream' },
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if ((typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) || body instanceof Uint8Array) {
|
|
69
125
|
let encodedData;
|
|
70
|
-
if (body instanceof ReadableStream) {
|
|
126
|
+
if (typeof ReadableStream !== 'undefined' && body instanceof ReadableStream) {
|
|
71
127
|
const reader = body.getReader();
|
|
72
128
|
const chunks = [];
|
|
73
129
|
while (true) {
|
|
@@ -87,7 +143,9 @@ var nativeBridge = (function (exports) {
|
|
|
87
143
|
else {
|
|
88
144
|
encodedData = body;
|
|
89
145
|
}
|
|
90
|
-
let data =
|
|
146
|
+
let data = (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image')) || contentType === 'application/octet-stream'
|
|
147
|
+
? readDataViewAsBase64(encodedData)
|
|
148
|
+
: new TextDecoder().decode(encodedData);
|
|
91
149
|
let type;
|
|
92
150
|
if (contentType === 'application/json') {
|
|
93
151
|
try {
|
|
@@ -102,7 +160,7 @@ var nativeBridge = (function (exports) {
|
|
|
102
160
|
type = 'formData';
|
|
103
161
|
}
|
|
104
162
|
else if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('image')) {
|
|
105
|
-
type = '
|
|
163
|
+
type = 'binary';
|
|
106
164
|
}
|
|
107
165
|
else if (contentType === 'application/octet-stream') {
|
|
108
166
|
type = 'binary';
|
|
@@ -128,14 +186,6 @@ var nativeBridge = (function (exports) {
|
|
|
128
186
|
type: 'formData',
|
|
129
187
|
};
|
|
130
188
|
}
|
|
131
|
-
else if (body instanceof Blob) {
|
|
132
|
-
const fileData = await readFileAsBase64(body);
|
|
133
|
-
return {
|
|
134
|
-
data: fileData,
|
|
135
|
-
type: 'file',
|
|
136
|
-
headers: { 'Content-Type': body.type },
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
189
|
return { data: body, type: 'json' };
|
|
140
190
|
};
|
|
141
191
|
const CAPACITOR_HTTP_INTERCEPTOR = '/_capacitor_http_interceptor_';
|
|
@@ -535,15 +585,15 @@ var nativeBridge = (function (exports) {
|
|
|
535
585
|
data: requestData,
|
|
536
586
|
dataType: type,
|
|
537
587
|
headers: nativeHeaders,
|
|
588
|
+
responseType: 'arraybuffer',
|
|
538
589
|
});
|
|
539
590
|
const contentType = nativeResponse.headers['Content-Type'] || nativeResponse.headers['content-type'];
|
|
540
|
-
let data = (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('application/json'))
|
|
541
|
-
? JSON.stringify(nativeResponse.data)
|
|
542
|
-
: nativeResponse.data;
|
|
543
591
|
// use null data for 204 No Content HTTP response
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
592
|
+
const data = nativeResponse.status === 204
|
|
593
|
+
? null
|
|
594
|
+
: (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith('application/json'))
|
|
595
|
+
? JSON.stringify(nativeResponse.data)
|
|
596
|
+
: base64StringToArrayBuffer(nativeResponse.data);
|
|
547
597
|
// intercept & parse response before returning
|
|
548
598
|
const response = new Response(data, {
|
|
549
599
|
headers: nativeResponse.headers,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capacitor-plus/ios",
|
|
3
|
-
"version": "8.3.
|
|
3
|
+
"version": "8.3.12",
|
|
4
4
|
"description": "Capacitor+: Enhanced Capacitor with automated upstream sync - Cross-platform apps with JavaScript and the web",
|
|
5
5
|
"homepage": "https://capgo.app/docs/plugins/capacitor-plus/",
|
|
6
6
|
"author": "Capgo Team <support@capgo.app> (https://capgo.app)",
|