@capacitor/ios 4.1.0 → 4.1.1-dev-7e3589f9.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.
@@ -0,0 +1,66 @@
1
+ import Foundation
2
+
3
+ public class CapacitorCookieManager {
4
+ var config: InstanceConfiguration?
5
+
6
+ init(_ capConfig: InstanceConfiguration?) {
7
+ self.config = capConfig
8
+ }
9
+
10
+ public func getServerUrl() -> URL? {
11
+ return self.config?.serverURL
12
+ }
13
+
14
+ public func getServerUrl(_ call: CAPPluginCall) -> URL? {
15
+ guard let urlString = call.getString("url") else {
16
+ return getServerUrl()
17
+ }
18
+
19
+ guard let url = URL(string: urlString) else {
20
+ return getServerUrl()
21
+ }
22
+
23
+ return url
24
+ }
25
+
26
+ public func encode(_ value: String) -> String {
27
+ return value.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!
28
+ }
29
+
30
+ public func decode(_ value: String) -> String {
31
+ return value.removingPercentEncoding!
32
+ }
33
+
34
+ public func setCookie(_ url: URL, _ key: String, _ value: String) {
35
+ let jar = HTTPCookieStorage.shared
36
+ let field = ["Set-Cookie": "\(key)=\(value)"]
37
+ let cookies = HTTPCookie.cookies(withResponseHeaderFields: field, for: url)
38
+ jar.setCookies(cookies, for: url, mainDocumentURL: url)
39
+ }
40
+
41
+ public func getCookies() -> String {
42
+ let jar = HTTPCookieStorage.shared
43
+ guard let url = self.getServerUrl() else { return "" }
44
+ guard let cookies = jar.cookies(for: url) else { return "" }
45
+ return cookies.map({"\($0.name)=\($0.value)"}).joined(separator: ";")
46
+ }
47
+
48
+ public func deleteCookie(_ url: URL, _ key: String) {
49
+ let jar = HTTPCookieStorage.shared
50
+ let cookie = jar.cookies(for: url)?.first(where: { (cookie) -> Bool in
51
+ return cookie.name == key
52
+ })
53
+
54
+ if cookie != nil { jar.deleteCookie(cookie!) }
55
+ }
56
+
57
+ public func clearCookies(_ url: URL) {
58
+ let jar = HTTPCookieStorage.shared
59
+ jar.cookies(for: url)?.forEach({ (cookie) in jar.deleteCookie(cookie) })
60
+ }
61
+
62
+ public func clearAllCookies() {
63
+ let jar = HTTPCookieStorage.shared
64
+ jar.cookies?.forEach({ (cookie) in jar.deleteCookie(cookie) })
65
+ }
66
+ }
@@ -0,0 +1,52 @@
1
+ import Foundation
2
+
3
+ @objc(CAPCookiesPlugin)
4
+ public class CAPCookiesPlugin: CAPPlugin {
5
+ var cookieManager: CapacitorCookieManager?
6
+
7
+ @objc override public func load() {
8
+ cookieManager = CapacitorCookieManager(bridge?.config)
9
+ }
10
+
11
+ @objc func setCookie(_ call: CAPPluginCall) {
12
+ guard let key = call.getString("key") else { return call.reject("Must provide key") }
13
+ guard let value = call.getString("value") else { return call.reject("Must provide value") }
14
+
15
+ let url = cookieManager!.getServerUrl(call)
16
+ if url != nil {
17
+ cookieManager!.setCookie(url!, key, cookieManager!.encode(value))
18
+ call.resolve()
19
+ }
20
+ }
21
+
22
+ @objc func deleteCookie(_ call: CAPPluginCall) {
23
+ guard let key = call.getString("key") else { return call.reject("Must provide key") }
24
+ let url = cookieManager!.getServerUrl(call)
25
+ if url != nil {
26
+ let jar = HTTPCookieStorage.shared
27
+
28
+ let cookie = jar.cookies(for: url!)?.first(where: { (cookie) -> Bool in
29
+ return cookie.name == key
30
+ })
31
+
32
+ if cookie != nil {
33
+ jar.deleteCookie(cookie!)
34
+ }
35
+
36
+ call.resolve()
37
+ }
38
+ }
39
+
40
+ @objc func clearCookies(_ call: CAPPluginCall) {
41
+ let url = cookieManager!.getServerUrl(call)
42
+ if url != nil {
43
+ cookieManager!.clearCookies(url!)
44
+ call.resolve()
45
+ }
46
+ }
47
+
48
+ @objc func clearAllCookies(_ call: CAPPluginCall) {
49
+ cookieManager!.clearAllCookies()
50
+ call.resolve()
51
+ }
52
+ }
@@ -0,0 +1,41 @@
1
+ import Foundation
2
+
3
+ @objc(CAPHttpPlugin)
4
+ public class CAPHttpPlugin: CAPPlugin {
5
+ @objc func http(_ call: CAPPluginCall, _ httpMethod: String?) {
6
+ // Protect against bad values from JS before calling request
7
+ guard let u = call.getString("url") else { return call.reject("Must provide a URL"); }
8
+ guard let _ = httpMethod ?? call.getString("method") else { return call.reject("Must provide an HTTP Method"); }
9
+ guard var _ = URL(string: u) else { return call.reject("Invalid URL"); }
10
+
11
+ do {
12
+ try HttpRequestHandler.request(call, httpMethod)
13
+ } catch let e {
14
+ call.reject(e.localizedDescription)
15
+ }
16
+ }
17
+
18
+ @objc func request(_ call: CAPPluginCall) {
19
+ http(call, nil)
20
+ }
21
+
22
+ @objc func get(_ call: CAPPluginCall) {
23
+ http(call, "GET")
24
+ }
25
+
26
+ @objc func post(_ call: CAPPluginCall) {
27
+ http(call, "POST")
28
+ }
29
+
30
+ @objc func put(_ call: CAPPluginCall) {
31
+ http(call, "PUT")
32
+ }
33
+
34
+ @objc func patch(_ call: CAPPluginCall) {
35
+ http(call, "PATCH")
36
+ }
37
+
38
+ @objc func del(_ call: CAPPluginCall) {
39
+ http(call, "DELETE")
40
+ }
41
+ }
@@ -0,0 +1,150 @@
1
+ import Foundation
2
+
3
+ public class CapacitorUrlRequest: NSObject, URLSessionTaskDelegate {
4
+ private var request: URLRequest
5
+ private var headers: [String: String]
6
+
7
+ enum CapacitorUrlRequestError: Error {
8
+ case serializationError(String?)
9
+ }
10
+
11
+ init(_ url: URL, method: String) {
12
+ request = URLRequest(url: url)
13
+ request.httpMethod = method
14
+ headers = [:]
15
+ if let lang = Locale.autoupdatingCurrent.languageCode {
16
+ if let country = Locale.autoupdatingCurrent.regionCode {
17
+ headers["Accept-Language"] = "\(lang)-\(country),\(lang);q=0.5"
18
+ } else {
19
+ headers["Accept-Language"] = "\(lang);q=0.5"
20
+ }
21
+ request.addValue(headers["Accept-Language"]!, forHTTPHeaderField: "Accept-Language")
22
+ }
23
+ }
24
+
25
+ private func getRequestDataAsJson(_ data: JSValue) throws -> Data? {
26
+ // We need to check if the JSON is valid before attempting to serialize, as JSONSerialization.data will not throw an exception that can be caught, and will cause the application to crash if it fails.
27
+ if JSONSerialization.isValidJSONObject(data) {
28
+ return try JSONSerialization.data(withJSONObject: data)
29
+ } else {
30
+ throw CapacitorUrlRequest.CapacitorUrlRequestError.serializationError("[ data ] argument for request of content-type [ application/json ] must be serializable to JSON")
31
+ }
32
+ }
33
+
34
+ private func getRequestDataAsFormUrlEncoded(_ data: JSValue) throws -> Data? {
35
+ guard var components = URLComponents(url: request.url!, resolvingAgainstBaseURL: false) else { return nil }
36
+ components.queryItems = []
37
+
38
+ guard let obj = data as? JSObject else {
39
+ // Throw, other data types explicitly not supported
40
+ throw CapacitorUrlRequestError.serializationError("[ data ] argument for request with content-type [ multipart/form-data ] may only be a plain javascript object")
41
+ }
42
+
43
+ obj.keys.forEach { (key: String) in
44
+ components.queryItems?.append(URLQueryItem(name: key, value: "\(obj[key] ?? "")"))
45
+ }
46
+
47
+ if components.query != nil {
48
+ return Data(components.query!.utf8)
49
+ }
50
+
51
+ return nil
52
+ }
53
+
54
+ private func getRequestDataAsMultipartFormData(_ data: JSValue) throws -> Data {
55
+ guard let obj = data as? JSObject else {
56
+ // Throw, other data types explicitly not supported.
57
+ throw CapacitorUrlRequestError.serializationError("[ data ] argument for request with content-type [ application/x-www-form-urlencoded ] may only be a plain javascript object")
58
+ }
59
+
60
+ let strings: [String: String] = obj.compactMapValues { any in
61
+ any as? String
62
+ }
63
+
64
+ var data = Data()
65
+ let boundary = UUID().uuidString
66
+ let contentType = "multipart/form-data; boundary=\(boundary)"
67
+ request.setValue(contentType, forHTTPHeaderField: "Content-Type")
68
+ headers["Content-Type"] = contentType
69
+
70
+ strings.forEach { key, value in
71
+ data.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
72
+ data.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8)!)
73
+ data.append(value.data(using: .utf8)!)
74
+ }
75
+ data.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
76
+
77
+ return data
78
+ }
79
+
80
+ private func getRequestDataAsString(_ data: JSValue) throws -> Data {
81
+ guard let stringData = data as? String else {
82
+ throw CapacitorUrlRequestError.serializationError("[ data ] argument could not be parsed as string")
83
+ }
84
+ return Data(stringData.utf8)
85
+ }
86
+
87
+ func getRequestHeader(_ index: String) -> Any? {
88
+ var normalized = [:] as [String: Any]
89
+ self.headers.keys.forEach { (key: String) in
90
+ normalized[key.lowercased()] = self.headers[key]
91
+ }
92
+
93
+ return normalized[index.lowercased()]
94
+ }
95
+
96
+ func getRequestData(_ body: JSValue, _ contentType: String) throws -> Data? {
97
+ // If data can be parsed directly as a string, return that without processing.
98
+ if let strVal = try? getRequestDataAsString(body) {
99
+ return strVal
100
+ } else if contentType.contains("application/json") {
101
+ return try getRequestDataAsJson(body)
102
+ } else if contentType.contains("application/x-www-form-urlencoded") {
103
+ return try getRequestDataAsFormUrlEncoded(body)
104
+ } else if contentType.contains("multipart/form-data") {
105
+ return try getRequestDataAsMultipartFormData(body)
106
+ } else {
107
+ throw CapacitorUrlRequestError.serializationError("[ data ] argument could not be parsed for content type [ \(contentType) ]")
108
+ }
109
+ }
110
+
111
+ public func setRequestHeaders(_ headers: [String: String]) {
112
+ headers.keys.forEach { (key: String) in
113
+ let value = headers[key]
114
+ request.addValue(value!, forHTTPHeaderField: key)
115
+ self.headers[key] = value
116
+ }
117
+ }
118
+
119
+ public func setRequestBody(_ body: JSValue) throws {
120
+ let contentType = self.getRequestHeader("Content-Type") as? String
121
+
122
+ if contentType != nil {
123
+ request.httpBody = try getRequestData(body, contentType!)
124
+ }
125
+ }
126
+
127
+ public func setContentType(_ data: String?) {
128
+ request.setValue(data, forHTTPHeaderField: "Content-Type")
129
+ }
130
+
131
+ public func setTimeout(_ timeout: TimeInterval) {
132
+ request.timeoutInterval = timeout
133
+ }
134
+
135
+ public func getUrlRequest() -> URLRequest {
136
+ return request
137
+ }
138
+
139
+ public func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
140
+ completionHandler(nil)
141
+ }
142
+
143
+ public func getUrlSession(_ call: CAPPluginCall) -> URLSession {
144
+ let disableRedirects = call.getBool("disableRedirects") ?? false
145
+ if !disableRedirects {
146
+ return URLSession.shared
147
+ }
148
+ return URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
149
+ }
150
+ }
@@ -2,10 +2,26 @@
2
2
 
3
3
  #import "CAPBridgedPlugin.h"
4
4
 
5
+ CAP_PLUGIN(CAPCookiesPlugin, "CapacitorCookies",
6
+ CAP_PLUGIN_METHOD(setCookie, CAPPluginReturnPromise);
7
+ CAP_PLUGIN_METHOD(deleteCookie, CAPPluginReturnPromise);
8
+ CAP_PLUGIN_METHOD(clearCookies, CAPPluginReturnPromise);
9
+ CAP_PLUGIN_METHOD(clearAllCookies, CAPPluginReturnPromise);
10
+ )
11
+
5
12
  CAP_PLUGIN(CAPConsolePlugin, "Console",
6
13
  CAP_PLUGIN_METHOD(log, CAPPluginReturnNone);
7
14
  )
8
15
 
16
+ CAP_PLUGIN(CAPHttpPlugin, "CapacitorHttp",
17
+ CAP_PLUGIN_METHOD(request, CAPPluginReturnPromise);
18
+ CAP_PLUGIN_METHOD(get, CAPPluginReturnPromise);
19
+ CAP_PLUGIN_METHOD(post, CAPPluginReturnPromise);
20
+ CAP_PLUGIN_METHOD(put, CAPPluginReturnPromise);
21
+ CAP_PLUGIN_METHOD(patch, CAPPluginReturnPromise);
22
+ CAP_PLUGIN_METHOD(delete, CAPPluginReturnPromise);
23
+ )
24
+
9
25
  CAP_PLUGIN(CAPWebViewPlugin, "WebView",
10
26
  CAP_PLUGIN_METHOD(setServerBasePath, CAPPluginReturnPromise);
11
27
  CAP_PLUGIN_METHOD(getServerBasePath, CAPPluginReturnPromise);
@@ -0,0 +1,172 @@
1
+ import Foundation
2
+
3
+ /// See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType
4
+ private enum ResponseType: String {
5
+ case arrayBuffer = "arraybuffer"
6
+ case blob = "blob"
7
+ case document = "document"
8
+ case json = "json"
9
+ case text = "text"
10
+
11
+ static let `default`: ResponseType = .text
12
+
13
+ init(string: String?) {
14
+ guard let string = string else {
15
+ self = .default
16
+ return
17
+ }
18
+
19
+ guard let responseType = ResponseType(rawValue: string.lowercased()) else {
20
+ self = .default
21
+ return
22
+ }
23
+
24
+ self = responseType
25
+ }
26
+ }
27
+
28
+ /// Helper that safely parses JSON Data. Otherwise returns an error (without throwing)
29
+ /// - Parameters:
30
+ /// - data: The JSON Data to parse
31
+ /// - Returns: The parsed value or an error
32
+ func tryParseJson(_ data: Data) -> Any {
33
+ do {
34
+ return try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
35
+ } catch {
36
+ return error.localizedDescription
37
+ }
38
+ }
39
+
40
+ class HttpRequestHandler {
41
+ private class CapacitorHttpRequestBuilder {
42
+ private var url: URL?
43
+ private var method: String?
44
+ private var params: [String: String]?
45
+ private var request: CapacitorUrlRequest?
46
+
47
+ /// Set the URL of the HttpRequest
48
+ /// - Throws: an error of URLError if the urlString cannot be parsed
49
+ /// - Parameters:
50
+ /// - urlString: The URL value to parse
51
+ /// - Returns: self to continue chaining functions
52
+ public func setUrl(_ urlString: String) throws -> CapacitorHttpRequestBuilder {
53
+ guard let u = URL(string: urlString) else {
54
+ throw URLError(.badURL)
55
+ }
56
+ url = u
57
+ return self
58
+ }
59
+
60
+ public func setMethod(_ method: String) -> CapacitorHttpRequestBuilder {
61
+ self.method = method
62
+ return self
63
+ }
64
+
65
+ public func setUrlParams(_ params: [String: Any]) -> CapacitorHttpRequestBuilder {
66
+ if params.count != 0 {
67
+ var cmps = URLComponents(url: url!, resolvingAgainstBaseURL: true)
68
+ if cmps?.queryItems == nil {
69
+ cmps?.queryItems = []
70
+ }
71
+
72
+ var urlSafeParams: [URLQueryItem] = []
73
+ for (key, value) in params {
74
+ if let arr = value as? [String] {
75
+ arr.forEach { str in
76
+ urlSafeParams.append(URLQueryItem(name: key, value: str))
77
+ }
78
+ } else {
79
+ urlSafeParams.append(URLQueryItem(name: key, value: (value as! String)))
80
+ }
81
+ }
82
+
83
+ cmps!.queryItems?.append(contentsOf: urlSafeParams)
84
+ url = cmps!.url!
85
+ }
86
+ return self
87
+ }
88
+
89
+ public func openConnection() -> CapacitorHttpRequestBuilder {
90
+ request = CapacitorUrlRequest(url!, method: method!)
91
+ return self
92
+ }
93
+
94
+ public func build() -> CapacitorUrlRequest {
95
+ return request!
96
+ }
97
+ }
98
+
99
+ private static func buildResponse(_ data: Data?, _ response: HTTPURLResponse, responseType: ResponseType = .default) -> [String: Any] {
100
+ var output = [:] as [String: Any]
101
+
102
+ output["status"] = response.statusCode
103
+ output["headers"] = response.allHeaderFields
104
+ output["url"] = response.url?.absoluteString
105
+
106
+ guard let data = data else {
107
+ output["data"] = ""
108
+ return output
109
+ }
110
+
111
+ let contentType = (response.allHeaderFields["Content-Type"] as? String ?? "application/default").lowercased()
112
+
113
+ if contentType.contains("application/json") || responseType == .json {
114
+ output["data"] = tryParseJson(data)
115
+ } else if responseType == .arrayBuffer || responseType == .blob {
116
+ output["data"] = data.base64EncodedString()
117
+ } else if responseType == .document || responseType == .text || responseType == .default {
118
+ output["data"] = String(data: data, encoding: .utf8)
119
+ }
120
+
121
+ return output
122
+ }
123
+
124
+ public static func request(_ call: CAPPluginCall, _ httpMethod: String?) throws {
125
+ guard let urlString = call.getString("url") else { throw URLError(.badURL) }
126
+ guard let method = httpMethod ?? call.getString("method") else { throw URLError(.dataNotAllowed) }
127
+
128
+ let headers = (call.getObject("headers") ?? [:]) as! [String: String]
129
+ let params = (call.getObject("params") ?? [:]) as! [String: Any]
130
+ let responseType = call.getString("responseType") ?? "text"
131
+ let connectTimeout = call.getDouble("connectTimeout")
132
+ let readTimeout = call.getDouble("readTimeout")
133
+
134
+ let request = try! CapacitorHttpRequestBuilder()
135
+ .setUrl(urlString)
136
+ .setMethod(method)
137
+ .setUrlParams(params)
138
+ .openConnection()
139
+ .build()
140
+
141
+ request.setRequestHeaders(headers)
142
+
143
+ // Timeouts in iOS are in seconds. So read the value in millis and divide by 1000
144
+ let timeout = (connectTimeout ?? readTimeout ?? 600000.0) / 1000.0
145
+ request.setTimeout(timeout)
146
+
147
+ if let data = call.options["data"] as? JSValue {
148
+ do {
149
+ try request.setRequestBody(data)
150
+ } catch {
151
+ // Explicitly reject if the http request body was not set successfully,
152
+ // so as to not send a known malformed request, and to provide the developer with additional context.
153
+ call.reject("Error", "REQUEST", error, [:])
154
+ return
155
+ }
156
+ }
157
+
158
+ let urlRequest = request.getUrlRequest()
159
+ let urlSession = request.getUrlSession(call)
160
+ let task = urlSession.dataTask(with: urlRequest) { (data, response, error) in
161
+ urlSession.invalidateAndCancel()
162
+ if error != nil {
163
+ return
164
+ }
165
+
166
+ let type = ResponseType(rawValue: responseType) ?? .default
167
+ call.resolve(self.buildResponse(data, response as! HTTPURLResponse, responseType: type))
168
+ }
169
+
170
+ task.resume()
171
+ }
172
+ }
@@ -243,6 +243,24 @@ internal class WebViewDelegationHandler: NSObject, WKNavigationDelegate, WKUIDel
243
243
  }
244
244
 
245
245
  public func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
246
+
247
+ // Check if this is synchronous cookie call
248
+ do {
249
+ if let dataFromString = prompt.data(using: .utf8, allowLossyConversion: false) {
250
+ if let payload = try JSONSerialization.jsonObject(with: dataFromString, options: .fragmentsAllowed) as? [String: AnyObject] {
251
+ let type = payload["type"] as? String
252
+
253
+ if type == "CapacitorCookies" {
254
+ completionHandler(CapacitorCookieManager(bridge!.config).getCookies())
255
+ // Don't present prompt
256
+ return
257
+ }
258
+ }
259
+ }
260
+ } catch {
261
+ // Continue with regular prompt
262
+ }
263
+
246
264
  guard let viewController = bridge?.viewController else {
247
265
  return
248
266
  }
@@ -241,6 +241,209 @@ const nativeBridge = (function (exports) {
241
241
  }
242
242
  return String(msg);
243
243
  };
244
+ /**
245
+ * Safely web decode a string value (inspired by js-cookie)
246
+ * @param str The string value to decode
247
+ */
248
+ const decode = (str) => str.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
249
+ const platform = getPlatformId(win);
250
+ if (platform == 'android' || platform == 'ios') {
251
+ // patch document.cookie on Android/iOS
252
+ win.CapacitorCookiesDescriptor =
253
+ Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') ||
254
+ Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie');
255
+ Object.defineProperty(document, 'cookie', {
256
+ get: function () {
257
+ if (platform === 'ios') {
258
+ // Use prompt to synchronously get cookies.
259
+ // https://stackoverflow.com/questions/29249132/wkwebview-complex-communication-between-javascript-native-code/49474323#49474323
260
+ const payload = {
261
+ type: 'CapacitorCookies',
262
+ };
263
+ const res = prompt(JSON.stringify(payload));
264
+ return res;
265
+ }
266
+ else if (typeof win.CapacitorCookiesAndroidInterface !== 'undefined') {
267
+ return win.CapacitorCookiesAndroidInterface.getCookies();
268
+ }
269
+ },
270
+ set: function (val) {
271
+ const cookiePairs = val.split(';');
272
+ for (const cookiePair of cookiePairs) {
273
+ const cookieKey = cookiePair.split('=')[0];
274
+ const cookieValue = cookiePair.split('=')[1];
275
+ if (null == cookieValue) {
276
+ continue;
277
+ }
278
+ cap.toNative('CapacitorCookies', 'setCookie', {
279
+ key: cookieKey,
280
+ value: decode(cookieValue),
281
+ });
282
+ }
283
+ },
284
+ });
285
+ // patch fetch / XHR on Android/iOS
286
+ // store original fetch & XHR functions
287
+ win.CapacitorWebFetch = window.fetch;
288
+ win.CapacitorWebXMLHttpRequest = {
289
+ abort: window.XMLHttpRequest.prototype.abort,
290
+ open: window.XMLHttpRequest.prototype.open,
291
+ send: window.XMLHttpRequest.prototype.send,
292
+ setRequestHeader: window.XMLHttpRequest.prototype.setRequestHeader,
293
+ };
294
+ // fetch patch
295
+ window.fetch = async (resource, options) => {
296
+ if (resource.toString().startsWith('data:')) {
297
+ return win.CapacitorWebFetch(resource, options);
298
+ }
299
+ try {
300
+ // intercept request & pass to the bridge
301
+ const nativeResponse = await cap.nativePromise('CapacitorHttp', 'request', {
302
+ url: resource,
303
+ method: (options === null || options === void 0 ? void 0 : options.method) ? options.method : undefined,
304
+ data: (options === null || options === void 0 ? void 0 : options.body) ? options.body : undefined,
305
+ headers: (options === null || options === void 0 ? void 0 : options.headers) ? options.headers : undefined,
306
+ });
307
+ // intercept & parse response before returning
308
+ const response = new Response(JSON.stringify(nativeResponse.data), {
309
+ headers: nativeResponse.headers,
310
+ status: nativeResponse.status,
311
+ });
312
+ return response;
313
+ }
314
+ catch (error) {
315
+ return Promise.reject(error);
316
+ }
317
+ };
318
+ // XHR event listeners
319
+ const addEventListeners = function () {
320
+ this.addEventListener('abort', function () {
321
+ if (typeof this.onabort === 'function')
322
+ this.onabort();
323
+ });
324
+ this.addEventListener('error', function () {
325
+ if (typeof this.onerror === 'function')
326
+ this.onerror();
327
+ });
328
+ this.addEventListener('load', function () {
329
+ if (typeof this.onload === 'function')
330
+ this.onload();
331
+ });
332
+ this.addEventListener('loadend', function () {
333
+ if (typeof this.onloadend === 'function')
334
+ this.onloadend();
335
+ });
336
+ this.addEventListener('loadstart', function () {
337
+ if (typeof this.onloadstart === 'function')
338
+ this.onloadstart();
339
+ });
340
+ this.addEventListener('readystatechange', function () {
341
+ if (typeof this.onreadystatechange === 'function')
342
+ this.onreadystatechange();
343
+ });
344
+ this.addEventListener('timeout', function () {
345
+ if (typeof this.ontimeout === 'function')
346
+ this.ontimeout();
347
+ });
348
+ };
349
+ // XHR patch abort
350
+ window.XMLHttpRequest.prototype.abort = function () {
351
+ Object.defineProperties(this, {
352
+ _headers: {
353
+ value: {},
354
+ writable: true,
355
+ },
356
+ readyState: {
357
+ get: function () {
358
+ var _a;
359
+ return (_a = this._readyState) !== null && _a !== void 0 ? _a : 0;
360
+ },
361
+ set: function (val) {
362
+ this._readyState = val;
363
+ this.dispatchEvent(new Event('readystatechange'));
364
+ },
365
+ },
366
+ response: {
367
+ value: '',
368
+ writable: true,
369
+ },
370
+ responseText: {
371
+ value: '',
372
+ writable: true,
373
+ },
374
+ responseURL: {
375
+ value: '',
376
+ writable: true,
377
+ },
378
+ status: {
379
+ value: 0,
380
+ writable: true,
381
+ },
382
+ });
383
+ this.readyState = 0;
384
+ this.dispatchEvent(new Event('abort'));
385
+ this.dispatchEvent(new Event('loadend'));
386
+ };
387
+ // XHR patch open
388
+ window.XMLHttpRequest.prototype.open = function (method, url) {
389
+ this.abort();
390
+ addEventListeners.call(this);
391
+ this._method = method;
392
+ this._url = url;
393
+ this.readyState = 1;
394
+ };
395
+ // XHR patch set request header
396
+ window.XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
397
+ this._headers[header] = value;
398
+ };
399
+ // XHR patch send
400
+ window.XMLHttpRequest.prototype.send = function (body) {
401
+ try {
402
+ this.readyState = 2;
403
+ // intercept request & pass to the bridge
404
+ cap
405
+ .nativePromise('CapacitorHttp', 'request', {
406
+ url: this._url,
407
+ method: this._method,
408
+ data: body !== null ? body : undefined,
409
+ headers: this._headers,
410
+ })
411
+ .then((nativeResponse) => {
412
+ // intercept & parse response before returning
413
+ if (this.readyState == 2) {
414
+ this.dispatchEvent(new Event('loadstart'));
415
+ this.status = nativeResponse.status;
416
+ this.response = nativeResponse.data;
417
+ this.responseText = JSON.stringify(nativeResponse.data);
418
+ this.responseURL = nativeResponse.url;
419
+ this.readyState = 4;
420
+ this.dispatchEvent(new Event('load'));
421
+ this.dispatchEvent(new Event('loadend'));
422
+ }
423
+ })
424
+ .catch((error) => {
425
+ this.dispatchEvent(new Event('loadstart'));
426
+ this.status = error.status;
427
+ this.response = error.data;
428
+ this.responseText = JSON.stringify(error.data);
429
+ this.responseURL = error.url;
430
+ this.readyState = 4;
431
+ this.dispatchEvent(new Event('error'));
432
+ this.dispatchEvent(new Event('loadend'));
433
+ });
434
+ }
435
+ catch (error) {
436
+ this.dispatchEvent(new Event('loadstart'));
437
+ this.status = 500;
438
+ this.response = error;
439
+ this.responseText = error.toString();
440
+ this.responseURL = this._url;
441
+ this.readyState = 4;
442
+ this.dispatchEvent(new Event('error'));
443
+ this.dispatchEvent(new Event('loadend'));
444
+ }
445
+ };
446
+ }
244
447
  // patch window.console on iOS and store original console fns
245
448
  const isIos = getPlatformId(win) === 'ios';
246
449
  if (win.console && isIos) {
package/LICENSE CHANGED
@@ -1,23 +1,21 @@
1
- Copyright 2017-present Ionic
2
- https://ionic.io
3
-
4
1
  MIT License
5
2
 
6
- Permission is hereby granted, free of charge, to any person obtaining
7
- a copy of this software and associated documentation files (the
8
- "Software"), to deal in the Software without restriction, including
9
- without limitation the rights to use, copy, modify, merge, publish,
10
- distribute, sublicense, and/or sell copies of the Software, and to
11
- permit persons to whom the Software is furnished to do so, subject to
12
- the following conditions:
3
+ Copyright (c) 2017-present Drifty Co.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
13
11
 
14
- The above copyright notice and this permission notice shall be
15
- included in all copies or substantial portions of the Software.
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
16
14
 
17
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/ios",
3
- "version": "4.1.0",
3
+ "version": "4.1.1-dev-7e3589f9.0",
4
4
  "description": "Capacitor: Cross-platform apps with JavaScript and the web",
5
5
  "homepage": "https://capacitorjs.com",
6
6
  "author": "Ionic Team <hi@ionic.io> (https://ionic.io)",
@@ -25,10 +25,10 @@
25
25
  "xc:build:CapacitorCordova": "cd CapacitorCordova && xcodebuild && cd .."
26
26
  },
27
27
  "peerDependencies": {
28
- "@capacitor/core": "^4.0.0"
28
+ "@capacitor/core": "^4.1.0"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"
32
32
  },
33
- "gitHead": "0b5c2b740e9613512a100051b8822fd1361f4aeb"
33
+ "gitHead": "7e3589f9bb4673b595f2718e444e2bd07c7749e1"
34
34
  }