@capgo/inappbrowser 8.3.0-alpha.0 → 8.3.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -60,7 +60,7 @@ import org.json.JSONObject;
60
60
  )
61
61
  public class InAppBrowserPlugin extends Plugin implements WebViewDialog.PermissionHandler {
62
62
 
63
- private final String pluginVersion = "8.3.0-alpha.0";
63
+ private final String pluginVersion = "8.3.0-alpha.1";
64
64
 
65
65
  public static final String CUSTOM_TAB_PACKAGE_NAME = "com.android.chrome"; // Change when in stable
66
66
  private CustomTabsClient customTabsClient;
@@ -29,7 +29,7 @@ public class InAppBrowserPlugin: CAPPlugin, CAPBridgedPlugin {
29
29
  case aware = "AWARE"
30
30
  case fakeVisible = "FAKE_VISIBLE"
31
31
  }
32
- private let pluginVersion: String = "8.3.0-alpha.0"
32
+ private let pluginVersion: String = "8.3.0-alpha.1"
33
33
  public let identifier = "InAppBrowserPlugin"
34
34
  public let jsName = "InAppBrowser"
35
35
  public let pluginMethods: [CAPPluginMethod] = [
@@ -6,12 +6,16 @@ public class ProxySchemeHandler: NSObject, WKURLSchemeHandler {
6
6
  weak var plugin: InAppBrowserPlugin?
7
7
  private var pendingTasks: [String: WKURLSchemeTask] = [:]
8
8
  private var pendingBodies: [String: Data] = [:]
9
- private var pendingNetworkTasks: [String: URLSessionDataTask] = [:]
9
+ private var activeTasks: [Int: (requestId: String, schemeTask: WKURLSchemeTask, dataTask: URLSessionDataTask)] = [:]
10
10
  private var stoppedRequests: Set<String> = []
11
11
  private let taskLock = NSLock()
12
12
  private let webviewId: String
13
13
  private let proxyTimeoutSeconds: TimeInterval = 10
14
14
 
15
+ private static var session: URLSession = {
16
+ return URLSession(configuration: .default)
17
+ }()
18
+
15
19
  init(plugin: InAppBrowserPlugin, webviewId: String) {
16
20
  self.plugin = plugin
17
21
  self.webviewId = webviewId
@@ -35,7 +39,7 @@ public class ProxySchemeHandler: NSObject, WKURLSchemeHandler {
35
39
  pendingTasks[requestId] = urlSchemeTask
36
40
  taskLock.unlock()
37
41
 
38
- // Encode body to base64, buffering stream data for later pass-through
42
+ // Buffer body from stream if needed (stream can only be read once)
39
43
  var base64Body: String? = nil
40
44
  if let bodyData = request.httpBody {
41
45
  base64Body = bodyData.base64EncodedString()
@@ -66,7 +70,7 @@ public class ProxySchemeHandler: NSObject, WKURLSchemeHandler {
66
70
 
67
71
  plugin?.notifyListeners("proxyRequest", data: eventData)
68
72
 
69
- // Timeout: if JS never responds, fail the request after proxyTimeoutSeconds
73
+ // Timeout: if JS never responds, fail the request
70
74
  DispatchQueue.global().asyncAfter(deadline: .now() + proxyTimeoutSeconds) { [weak self] in
71
75
  guard let self = self else { return }
72
76
  self.taskLock.lock()
@@ -77,7 +81,6 @@ public class ProxySchemeHandler: NSObject, WKURLSchemeHandler {
77
81
  self.pendingBodies.removeValue(forKey: requestId)
78
82
  self.taskLock.unlock()
79
83
 
80
- print("[InAppBrowser] Proxy request timed out after \(Int(self.proxyTimeoutSeconds))s: \(requestId)")
81
84
  task.didFailWithError(NSError(
82
85
  domain: "ProxySchemeHandler",
83
86
  code: NSURLErrorTimedOut,
@@ -88,68 +91,50 @@ public class ProxySchemeHandler: NSObject, WKURLSchemeHandler {
88
91
 
89
92
  public func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
90
93
  taskLock.lock()
91
- let requestIdToRemove = pendingTasks.first(where: { $0.value === urlSchemeTask })?.key
92
- var networkTask: URLSessionDataTask?
93
- if let key = requestIdToRemove {
94
+ // Check pending (waiting for JS)
95
+ if let key = pendingTasks.first(where: { $0.value === urlSchemeTask })?.key {
94
96
  pendingTasks.removeValue(forKey: key)
95
97
  pendingBodies.removeValue(forKey: key)
96
- networkTask = pendingNetworkTasks.removeValue(forKey: key)
97
98
  stoppedRequests.insert(key)
98
99
  }
100
+ // Check active network tasks (pass-through) — cancel the URLSessionDataTask
101
+ var networkTaskToCancel: URLSessionDataTask?
102
+ if let entry = activeTasks.first(where: { $0.value.schemeTask === urlSchemeTask }) {
103
+ networkTaskToCancel = entry.value.dataTask
104
+ activeTasks.removeValue(forKey: entry.key)
105
+ stoppedRequests.insert(entry.value.requestId)
106
+ }
99
107
  taskLock.unlock()
100
- networkTask?.cancel()
108
+ networkTaskToCancel?.cancel()
101
109
  }
102
110
 
103
111
  /// Called from handleProxyRequest plugin method with the JS response
104
112
  func handleResponse(requestId: String, responseData: [String: Any]?) {
105
113
  taskLock.lock()
106
114
  let isStopped = stoppedRequests.remove(requestId) != nil
107
- guard let urlSchemeTask = pendingTasks[requestId] else {
108
- pendingTasks.removeValue(forKey: requestId)
109
- pendingBodies.removeValue(forKey: requestId)
115
+ guard let urlSchemeTask = pendingTasks.removeValue(forKey: requestId) else {
110
116
  taskLock.unlock()
111
117
  return
112
118
  }
113
119
  let bufferedBody = pendingBodies.removeValue(forKey: requestId)
114
-
115
- if isStopped {
116
- pendingTasks.removeValue(forKey: requestId)
117
- taskLock.unlock()
118
- return
119
- }
120
-
121
- if responseData != nil {
122
- // JS provided a response — remove from pending now
123
- pendingTasks.removeValue(forKey: requestId)
124
- }
125
- // For pass-through (nil), keep pendingTasks entry so stop can find it
126
120
  taskLock.unlock()
127
121
 
122
+ if isStopped { return }
123
+
128
124
  if let responseData = responseData {
125
+ // JS provided a response — return it directly
129
126
  let statusCode = responseData["status"] as? Int ?? 200
130
127
  let headersDict = responseData["headers"] as? [String: String] ?? [:]
131
128
  let base64Body = responseData["body"] as? String ?? ""
132
-
133
129
  let bodyData = Data(base64Encoded: base64Body) ?? Data()
134
130
 
135
- guard let url = urlSchemeTask.request.url else {
136
- urlSchemeTask.didFailWithError(NSError(
137
- domain: "ProxySchemeHandler",
138
- code: -1,
139
- userInfo: [NSLocalizedDescriptionKey: "No URL"]
140
- ))
141
- return
142
- }
143
-
144
- guard let httpResponse = HTTPURLResponse(
145
- url: url,
146
- statusCode: statusCode,
147
- httpVersion: "HTTP/1.1",
148
- headerFields: headersDict
149
- ) else {
131
+ guard let url = urlSchemeTask.request.url,
132
+ let httpResponse = HTTPURLResponse(
133
+ url: url, statusCode: statusCode,
134
+ httpVersion: "HTTP/1.1", headerFields: headersDict
135
+ ) else {
150
136
  urlSchemeTask.didFailWithError(NSError(
151
- domain: "ProxySchemeHandler",
152
- code: -2,
137
+ domain: "ProxySchemeHandler", code: -2,
153
138
  userInfo: [NSLocalizedDescriptionKey: "Failed to create response"]
154
139
  ))
155
140
  return
@@ -166,69 +151,60 @@ public class ProxySchemeHandler: NSObject, WKURLSchemeHandler {
166
151
 
167
152
  private func executePassThrough(requestId: String, urlSchemeTask: WKURLSchemeTask, bufferedBody: Data?) {
168
153
  var request = urlSchemeTask.request
169
- // Restore body if it was consumed from httpBodyStream during interception
170
154
  if request.httpBody == nil, let body = bufferedBody {
171
155
  request.httpBody = body
172
156
  }
173
- let session = URLSession.shared
174
- let task = session.dataTask(with: request) { [weak self] data, response, error in
157
+
158
+ let task = Self.session.dataTask(with: request) { [weak self, weak urlSchemeTask] data, response, error in
159
+ guard let urlSchemeTask = urlSchemeTask else { return }
175
160
  guard let self = self else { return }
176
161
 
177
- // Clean up and check if this request was stopped while in-flight
162
+ // Clean up active entry and check not stopped
178
163
  self.taskLock.lock()
179
- self.pendingTasks.removeValue(forKey: requestId)
180
- self.pendingNetworkTasks.removeValue(forKey: requestId)
164
+ if let entry = self.activeTasks.first(where: { $0.value.requestId == requestId }) {
165
+ self.activeTasks.removeValue(forKey: entry.key)
166
+ }
181
167
  let wasStopped = self.stoppedRequests.remove(requestId) != nil
182
168
  self.taskLock.unlock()
183
-
184
- if wasStopped {
185
- return
186
- }
169
+ if wasStopped { return }
187
170
 
188
171
  if let error = error {
189
- if (error as NSError).code == NSURLErrorCancelled {
190
- return
172
+ if (error as NSError).code != NSURLErrorCancelled {
173
+ urlSchemeTask.didFailWithError(error)
191
174
  }
192
- urlSchemeTask.didFailWithError(error)
193
- return
194
- }
195
-
196
- guard let httpResponse = response as? HTTPURLResponse else {
197
- urlSchemeTask.didFailWithError(NSError(
198
- domain: "ProxySchemeHandler",
199
- code: -3,
200
- userInfo: [NSLocalizedDescriptionKey: "Non-HTTP response"]
201
- ))
202
- return
203
- }
204
-
205
- urlSchemeTask.didReceive(httpResponse)
206
- if let data = data {
207
- urlSchemeTask.didReceive(data)
175
+ } else {
176
+ if let response = response {
177
+ urlSchemeTask.didReceive(response)
178
+ }
179
+ if let data = data {
180
+ urlSchemeTask.didReceive(data)
181
+ }
182
+ urlSchemeTask.didFinish()
208
183
  }
209
- urlSchemeTask.didFinish()
210
184
  }
211
185
 
212
186
  taskLock.lock()
213
- pendingNetworkTasks[requestId] = task
187
+ activeTasks[task.taskIdentifier] = (requestId: requestId, schemeTask: urlSchemeTask, dataTask: task)
214
188
  taskLock.unlock()
189
+
215
190
  task.resume()
216
191
  }
217
192
 
218
193
  func cancelAllPendingTasks() {
219
194
  taskLock.lock()
220
- let tasks = pendingTasks
221
- let networkTasks = pendingNetworkTasks
195
+ let pending = pendingTasks
196
+ let active = activeTasks
222
197
  pendingTasks.removeAll()
223
198
  pendingBodies.removeAll()
224
- pendingNetworkTasks.removeAll()
199
+ activeTasks.removeAll()
225
200
  stoppedRequests.removeAll()
226
201
  taskLock.unlock()
227
202
 
228
- for (_, networkTask) in networkTasks {
229
- networkTask.cancel()
203
+ for (_, entry) in active {
204
+ entry.dataTask.cancel()
230
205
  }
231
- for (_, task) in tasks {
206
+
207
+ for (_, task) in pending {
232
208
  task.didFailWithError(NSError(
233
209
  domain: "ProxySchemeHandler",
234
210
  code: NSURLErrorCancelled,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/inappbrowser",
3
- "version": "8.3.0-alpha.0",
3
+ "version": "8.3.0-alpha.1",
4
4
  "description": "Capacitor plugin in app browser",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",