@cappitolian/http-local-server-swifter 0.0.9 → 0.0.11

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.
@@ -16,7 +16,7 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
16
16
  private static var pendingResponses = [String: (String) -> Void]()
17
17
  private static let queue = DispatchQueue(label: "com.cappitolian.HttpLocalServerSwifter.pendingResponses", qos: .userInitiated)
18
18
 
19
- private let defaultTimeout: TimeInterval = 5.0
19
+ private let defaultTimeout: TimeInterval = 30.0 // Aumentado para debugging
20
20
  private let defaultPort: UInt16 = 8080
21
21
 
22
22
  // MARK: - Initialization
@@ -31,41 +31,31 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
31
31
 
32
32
  // MARK: - Public Methods
33
33
  @objc public func connect(_ call: CAPPluginCall) {
34
- DispatchQueue.main.async { [weak self] in
35
- guard let self = self else {
36
- call.reject("Server instance deallocated")
37
- return
38
- }
39
-
40
- // Stop existing server if running
41
- self.disconnect()
34
+ // Stop existing server if running
35
+ self.disconnect()
36
+
37
+ self.webServer = HttpServer()
38
+ self.setupHandlers()
39
+
40
+ do {
41
+ try self.startServer()
42
+ let ip = Self.getWiFiAddress() ?? "127.0.0.1"
42
43
 
43
- self.webServer = HttpServer()
44
- self.setupHandlers()
44
+ print("✅ HttpLocalServerSwifter: Server started on \(ip):\(self.defaultPort)")
45
45
 
46
- do {
47
- try self.startServer()
48
- let ip = Self.getWiFiAddress() ?? "127.0.0.1"
49
- call.resolve([
50
- "ip": ip,
51
- "port": self.defaultPort
52
- ])
53
- } catch {
54
- call.reject("Failed to start server: \(error.localizedDescription)")
55
- }
46
+ call.resolve([
47
+ "ip": ip,
48
+ "port": self.defaultPort
49
+ ])
50
+ } catch {
51
+ print("❌ HttpLocalServerSwifter: Failed to start server - \(error.localizedDescription)")
52
+ call.reject("Failed to start server: \(error.localizedDescription)")
56
53
  }
57
54
  }
58
55
 
59
56
  @objc public func disconnect(_ call: CAPPluginCall? = nil) {
60
- DispatchQueue.main.async { [weak self] in
61
- guard let self = self else {
62
- call?.reject("Server instance deallocated")
63
- return
64
- }
65
-
66
- self.disconnect()
67
- call?.resolve()
68
- }
57
+ disconnect()
58
+ call?.resolve()
69
59
  }
70
60
 
71
61
  // MARK: - Static Methods
@@ -74,6 +64,9 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
74
64
  if let callback = pendingResponses[requestId] {
75
65
  callback(body)
76
66
  pendingResponses.removeValue(forKey: requestId)
67
+ print("✅ HttpLocalServerSwifter: Response sent for requestId: \(requestId)")
68
+ } else {
69
+ print("⚠️ HttpLocalServerSwifter: No pending callback for requestId: \(requestId)")
77
70
  }
78
71
  }
79
72
  }
@@ -87,24 +80,44 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
87
80
  Self.queue.async {
88
81
  Self.pendingResponses.removeAll()
89
82
  }
83
+
84
+ print("🛑 HttpLocalServerSwifter: Server stopped")
90
85
  }
91
86
 
92
87
  private func setupHandlers() {
93
88
  guard let server = webServer else { return }
89
+
90
+ server["/"] = { [weak self] request in
91
+ return self?.handleRequest(request) ?? self?.errorResponse() ?? .internalServerError
92
+ }
93
+
94
+ server["/:path"] = { [weak self] request in
95
+ return self?.handleRequest(request) ?? self?.errorResponse() ?? .internalServerError
96
+ }
97
+
98
+ // Rutas con dos segmentos: /orders/{id}
99
+ server["/:first/:second"] = { [weak self] request in
100
+ return self?.handleRequest(request) ?? self?.errorResponse() ?? .internalServerError
101
+ }
102
+
103
+ // Rutas con tres segmentos por si acaso: /orders/{id}/status
104
+ server["/:first/:second/:third"] = { [weak self] request in
105
+ return self?.handleRequest(request) ?? self?.errorResponse() ?? .internalServerError
106
+ }
107
+
108
+ print("✅ HttpLocalServerSwifter: Handlers configured")
109
+ }
110
+
111
+ private func handleRequest(_ request: HttpRequest) -> HttpResponse {
112
+ print("📨 HttpLocalServerSwifter: Received \(request.method) request to \(request.path)")
94
113
 
95
- // Catch-all handler for all HTTP methods and paths
96
- server["/(.*)"] = { [weak self] request in
97
- guard let self = self else {
98
- return self?.errorResponse() ?? .internalServerError
99
- }
100
-
101
- // Handle OPTIONS (CORS preflight)
102
- if request.method == "OPTIONS" {
103
- return self.corsResponse()
104
- }
105
-
106
- return self.processRequest(request)
114
+ // Handle OPTIONS (CORS preflight)
115
+ if request.method == "OPTIONS" {
116
+ print("🔄 HttpLocalServerSwifter: Handling CORS preflight")
117
+ return corsResponse()
107
118
  }
119
+
120
+ return processRequest(request)
108
121
  }
109
122
 
110
123
  private func processRequest(_ request: HttpRequest) -> HttpResponse {
@@ -147,7 +160,12 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
147
160
  requestData["query"] = query
148
161
  }
149
162
 
150
- delegate?.httpLocalServerSwifterDidReceiveRequest(requestData)
163
+ print("📤 HttpLocalServerSwifter: Notifying delegate with requestId: \(requestId)")
164
+
165
+ // Notify on main thread to ensure proper event delivery
166
+ DispatchQueue.main.async { [weak self] in
167
+ self?.delegate?.httpLocalServerSwifterDidReceiveRequest(requestData)
168
+ }
151
169
 
152
170
  // Wait for JS response or timeout
153
171
  let result = semaphore.wait(timeout: .now() + defaultTimeout)
@@ -159,16 +177,17 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
159
177
 
160
178
  // Handle timeout
161
179
  if result == .timedOut {
180
+ print("⏱️ HttpLocalServerSwifter: Request timeout for requestId: \(requestId)")
162
181
  let timeoutResponse = "{\"error\":\"Request timeout\",\"requestId\":\"\(requestId)\"}"
163
182
  return createJsonResponse(timeoutResponse, statusCode: 408)
164
183
  }
165
184
 
166
185
  let reply = responseString ?? "{\"error\":\"No response from handler\"}"
186
+ print("✅ HttpLocalServerSwifter: Sending response for requestId: \(requestId)")
167
187
  return createJsonResponse(reply)
168
188
  }
169
189
 
170
190
  private func extractBody(from request: HttpRequest) -> String? {
171
- // request.body ya es [UInt8], no es opcional
172
191
  let bodyBytes = request.body
173
192
 
174
193
  guard !bodyBytes.isEmpty else {
@@ -179,7 +198,6 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
179
198
  }
180
199
 
181
200
  private func extractHeaders(from request: HttpRequest) -> [String: String] {
182
- // Swifter headers es [(String, String)], convertir a [String: String]
183
201
  var headersDict: [String: String] = [:]
184
202
  for (key, value) in request.headers {
185
203
  headersDict[key] = value
@@ -188,7 +206,6 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
188
206
  }
189
207
 
190
208
  private func extractQuery(from request: HttpRequest) -> [String: String] {
191
- // request.queryParams también es [(String, String)]
192
209
  var queryDict: [String: String] = [:]
193
210
  for (key, value) in request.queryParams {
194
211
  queryDict[key] = value
@@ -254,8 +271,14 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
254
271
  )
255
272
  }
256
273
 
257
- // Swifter starts on all interfaces (0.0.0.0) by default
258
- try server.start(defaultPort, forceIPv4: true)
274
+ // Try to start on the default port
275
+ do {
276
+ try server.start(defaultPort, forceIPv4: true)
277
+ print("✅ HttpLocalServerSwifter: Server listening on port \(defaultPort)")
278
+ } catch {
279
+ print("❌ HttpLocalServerSwifter: Failed to bind to port \(defaultPort): \(error)")
280
+ throw error
281
+ }
259
282
  }
260
283
 
261
284
  // MARK: - Network Utilities
@@ -264,6 +287,7 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
264
287
  var ifaddr: UnsafeMutablePointer<ifaddrs>?
265
288
 
266
289
  guard getifaddrs(&ifaddr) == 0 else {
290
+ print("❌ HttpLocalServerSwifter: Failed to get network interfaces")
267
291
  return nil
268
292
  }
269
293
 
@@ -304,6 +328,8 @@ public protocol HttpLocalServerSwifterDelegate: AnyObject {
304
328
 
305
329
  address = String(cString: hostname)
306
330
 
331
+ print("📡 HttpLocalServerSwifter: Found \(name) interface with IP: \(address ?? "unknown")")
332
+
307
333
  // Prefer en0 (WiFi) over pdp_ip0 (cellular)
308
334
  if name == "en0" {
309
335
  break
@@ -1,10 +1,6 @@
1
1
  import Foundation
2
2
  import Capacitor
3
3
 
4
- /**
5
- * Capacitor plugin for running a local HTTP server on the device.
6
- * Allows receiving HTTP requests and sending responses from JavaScript.
7
- */
8
4
  @objc(HttpLocalServerSwifterPlugin)
9
5
  public class HttpLocalServerSwifterPlugin: CAPPlugin, CAPBridgedPlugin, HttpLocalServerSwifterDelegate {
10
6
  // MARK: - CAPBridgedPlugin Properties
@@ -19,59 +15,56 @@ public class HttpLocalServerSwifterPlugin: CAPPlugin, CAPBridgedPlugin, HttpLoca
19
15
  // MARK: - Properties
20
16
  private var localServer: HttpLocalServerSwifter?
21
17
 
22
- // MARK: - Plugin Methods
18
+ // MARK: - Lifecycle
19
+ public override func load() {
20
+ print("✅ HttpLocalServerSwifterPlugin: Plugin loaded")
21
+ }
23
22
 
24
- /**
25
- * Starts the local HTTP server.
26
- * @return ip: The server's IP address
27
- * @return port: The port the server is listening on
28
- */
23
+ // MARK: - Plugin Methods
29
24
  @objc func connect(_ call: CAPPluginCall) {
25
+ print("📞 HttpLocalServerSwifterPlugin: connect() called")
26
+
30
27
  if localServer == nil {
31
28
  localServer = HttpLocalServerSwifter(delegate: self)
29
+ print("✅ HttpLocalServerSwifterPlugin: Server instance created")
32
30
  }
31
+
33
32
  localServer?.connect(call)
34
33
  }
35
34
 
36
- /**
37
- * Stops the local HTTP server.
38
- * Cleans up all resources and pending requests.
39
- */
40
35
  @objc func disconnect(_ call: CAPPluginCall) {
36
+ print("📞 HttpLocalServerSwifterPlugin: disconnect() called")
37
+
41
38
  if localServer != nil {
42
39
  localServer?.disconnect(call)
40
+ localServer = nil
43
41
  } else {
44
42
  call.resolve()
45
43
  }
46
44
  }
47
45
 
48
- /**
49
- * Sends a response back to the client that made the request.
50
- * @param requestId Unique request ID (received in 'onRequest')
51
- * @param body Response body (typically stringified JSON)
52
- */
53
46
  @objc func sendResponse(_ call: CAPPluginCall) {
54
47
  guard let requestId = call.getString("requestId") else {
48
+ print("❌ HttpLocalServerSwifterPlugin: Missing requestId")
55
49
  call.reject("Missing requestId")
56
50
  return
57
51
  }
58
52
 
59
53
  guard let body = call.getString("body") else {
54
+ print("❌ HttpLocalServerSwifterPlugin: Missing body")
60
55
  call.reject("Missing body")
61
56
  return
62
57
  }
63
58
 
59
+ print("📤 HttpLocalServerSwifterPlugin: sendResponse for requestId: \(requestId)")
64
60
  HttpLocalServerSwifter.handleJsResponse(requestId: requestId, body: body)
65
61
  call.resolve()
66
62
  }
67
63
 
68
64
  // MARK: - HttpLocalServerSwifterDelegate
69
-
70
- /**
71
- * Delegate method called when the server receives an HTTP request.
72
- * Notifies JavaScript via the 'onRequest' event.
73
- */
74
65
  public func httpLocalServerSwifterDidReceiveRequest(_ data: [String: Any]) {
66
+ print("📨 HttpLocalServerSwifterPlugin: Received request, notifying listeners")
67
+ print(" Request data: \(data)")
75
68
  notifyListeners("onRequest", data: data)
76
69
  }
77
70
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cappitolian/http-local-server-swifter",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "Runs a local HTTP server on your device, accessible over LAN. Supports connect, disconnect, GET, and POST methods with IP and port discovery.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",