react-native-kookit 0.2.3 → 0.2.4

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.
@@ -311,32 +311,53 @@ class FtpClient: @unchecked Sendable {
311
311
  func downloadFile(remotePath: String, localPath: String) async throws {
312
312
  guard isConnected else { throw FtpError.notConnected }
313
313
 
314
+ print("FTP DEBUG: Starting download - Remote: \(remotePath), Local: \(localPath)")
315
+
314
316
  let dataConnection = try await enterPassiveMode()
317
+ print("FTP DEBUG: Passive mode established for download")
315
318
 
316
319
  let response = try await sendCommand("RETR \(remotePath)")
317
- guard response.hasPrefix("150") || response.hasPrefix("125") else {
320
+ print("FTP DEBUG: RETR command response: \(response)")
321
+
322
+ // Extract the first line for status check
323
+ let firstLine = response.components(separatedBy: .newlines).first ?? response
324
+ guard firstLine.hasPrefix("150") || firstLine.hasPrefix("125") else {
318
325
  dataConnection.cancel()
319
- throw FtpError.commandFailed("Download failed: \(response)")
326
+ throw FtpError.commandFailed("Download failed: \(firstLine)")
320
327
  }
321
328
 
322
329
  let localURL = URL(fileURLWithPath: localPath)
323
330
 
324
331
  // Create parent directories if needed
332
+ print("FTP DEBUG: Creating parent directories for: \(localURL.deletingLastPathComponent().path)")
325
333
  try FileManager.default.createDirectory(at: localURL.deletingLastPathComponent(),
326
334
  withIntermediateDirectories: true,
327
335
  attributes: nil)
328
336
 
337
+ print("FTP DEBUG: Starting data reception...")
329
338
  let data = try await receiveData(from: dataConnection, reportProgress: true)
339
+ print("FTP DEBUG: Data reception completed, received \(data.count) bytes")
330
340
  dataConnection.cancel()
331
341
 
342
+ print("FTP DEBUG: Writing data to file...")
332
343
  try data.write(to: localURL)
344
+ print("FTP DEBUG: File written successfully")
333
345
 
334
- let finalResponse = try await readResponse()
335
- guard finalResponse.hasPrefix("226") else {
336
- try? FileManager.default.removeItem(at: localURL)
337
- throw FtpError.commandFailed("Download completion failed: \(finalResponse)")
346
+ // Check if the response already contained the completion message (226)
347
+ if response.contains("226") {
348
+ print("FTP DEBUG: Transfer completion already received in RETR response - skipping final response read")
349
+ } else {
350
+ print("FTP DEBUG: Reading final response...")
351
+ let finalResponse = try await readResponse()
352
+ let finalFirstLine = finalResponse.components(separatedBy: .newlines).first ?? finalResponse
353
+ print("FTP DEBUG: Final download response: \(finalFirstLine)")
354
+ guard finalFirstLine.hasPrefix("226") else {
355
+ try? FileManager.default.removeItem(at: localURL)
356
+ throw FtpError.commandFailed("Download completion failed: \(finalFirstLine)")
357
+ }
338
358
  }
339
359
 
360
+ print("FTP DEBUG: Download completed successfully")
340
361
  progressDelegate?.onComplete()
341
362
  }
342
363
 
@@ -454,6 +475,7 @@ class FtpClient: @unchecked Sendable {
454
475
  throw FtpError.notConnected
455
476
  }
456
477
 
478
+ print("FTP DEBUG: Sending command: \(command)")
457
479
  let commandData = "\(command)\r\n".data(using: .utf8)!
458
480
 
459
481
  return try await withCheckedThrowingContinuation { continuation in
@@ -461,13 +483,24 @@ class FtpClient: @unchecked Sendable {
461
483
 
462
484
  connection.send(content: commandData, completion: .contentProcessed { error in
463
485
  if let error = error {
486
+ print("FTP DEBUG: Send command error: \(error)")
464
487
  connectionBox.resume(throwing: error)
465
488
  } else {
489
+ print("FTP DEBUG: Command sent successfully, waiting for response...")
466
490
  Task {
467
491
  do {
468
492
  let response = try await self.readResponse()
469
- connectionBox.resume(returning: response)
493
+ print("FTP DEBUG: Command response received: \(response)")
494
+
495
+ // Store the full response for multi-line responses
496
+ if response.contains("\n") {
497
+ print("FTP DEBUG: Multi-line response detected")
498
+ connectionBox.resume(returning: response)
499
+ } else {
500
+ connectionBox.resume(returning: response)
501
+ }
470
502
  } catch {
503
+ print("FTP DEBUG: Error reading response: \(error)")
471
504
  connectionBox.resume(throwing: error)
472
505
  }
473
506
  }
@@ -481,35 +514,47 @@ class FtpClient: @unchecked Sendable {
481
514
  throw FtpError.notConnected
482
515
  }
483
516
 
517
+ print("FTP DEBUG: Reading response...")
484
518
  return try await withCheckedThrowingContinuation { continuation in
485
519
  let connectionBox = ConnectionBox<String>(continuation: continuation)
486
520
 
487
521
  connection.receive(minimumIncompleteLength: 1, maximumLength: 4096) { data, _, isComplete, error in
488
522
  if let error = error {
523
+ print("FTP DEBUG: Read response error: \(error)")
489
524
  connectionBox.resume(throwing: error)
490
525
  } else if let data = data {
526
+ print("FTP DEBUG: Received response data: \(data.count) bytes")
491
527
  // Try multiple encodings for FTP responses
492
528
  var response: String?
493
529
 
494
530
  // Try UTF-8 first
495
531
  if let utf8Response = String(data: data, encoding: .utf8) {
496
532
  response = utf8Response
533
+ print("FTP DEBUG: Response decoded with UTF-8")
497
534
  }
498
535
  // Try GBK for Chinese FTP servers
499
536
  else if let gbkResponse = String(data: data, encoding: String.Encoding(rawValue: CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(CFStringEncodings.GB_18030_2000.rawValue)))) {
500
537
  response = gbkResponse
538
+ print("FTP DEBUG: Response decoded with GBK")
501
539
  }
502
540
  // Try ASCII as fallback
503
541
  else if let asciiResponse = String(data: data, encoding: .ascii) {
504
542
  response = asciiResponse
543
+ print("FTP DEBUG: Response decoded with ASCII")
505
544
  }
506
545
 
507
546
  if let validResponse = response {
508
- connectionBox.resume(returning: validResponse.trimmingCharacters(in: .whitespacesAndNewlines))
547
+ let trimmedResponse = validResponse.trimmingCharacters(in: .whitespacesAndNewlines)
548
+ print("FTP DEBUG: Response content: '\(trimmedResponse)'")
549
+
550
+ // Return the full response for multi-line processing
551
+ connectionBox.resume(returning: trimmedResponse)
509
552
  } else {
553
+ print("FTP DEBUG: Failed to decode response")
510
554
  connectionBox.resume(throwing: FtpError.invalidResponse)
511
555
  }
512
556
  } else {
557
+ print("FTP DEBUG: No data received")
513
558
  connectionBox.resume(throwing: FtpError.invalidResponse)
514
559
  }
515
560
  }
@@ -517,7 +562,9 @@ class FtpClient: @unchecked Sendable {
517
562
  }
518
563
 
519
564
  private func enterPassiveMode() async throws -> NWConnection {
565
+ print("FTP DEBUG: Entering passive mode...")
520
566
  let response = try await sendCommand("PASV")
567
+ print("FTP DEBUG: PASV response: \(response)")
521
568
  guard response.hasPrefix("227") else {
522
569
  throw FtpError.commandFailed("Failed to enter passive mode: \(response)")
523
570
  }
@@ -541,6 +588,8 @@ class FtpClient: @unchecked Sendable {
541
588
  let host = "\(h1).\(h2).\(h3).\(h4)"
542
589
  let port = p1 * 256 + p2
543
590
 
591
+ print("FTP DEBUG: Parsed passive mode - Host: \(host), Port: \(port)")
592
+
544
593
  let dataHost = NWEndpoint.Host(host)
545
594
  let dataPort = NWEndpoint.Port(integerLiteral: UInt16(port))
546
595
  let dataEndpoint = NWEndpoint.hostPort(host: dataHost, port: dataPort)
@@ -551,15 +600,18 @@ class FtpClient: @unchecked Sendable {
551
600
  let connectionBox = NWConnectionBox(connection: dataConnection, continuation: continuation)
552
601
 
553
602
  dataConnection.stateUpdateHandler = { state in
603
+ print("FTP DEBUG: Data connection state: \(state)")
554
604
  connectionBox.handleStateUpdate(state)
555
605
  }
556
606
 
607
+ print("FTP DEBUG: Starting data connection...")
557
608
  dataConnection.start(queue: .global())
558
609
  }
559
610
  }
560
611
 
561
612
  private func receiveData(from connection: NWConnection, reportProgress: Bool = false) async throws -> Data {
562
613
  var receivedData = Data()
614
+ print("FTP DEBUG: Starting data reception, reportProgress: \(reportProgress)")
563
615
 
564
616
  return try await withCheckedThrowingContinuation { continuation in
565
617
  let connectionBox = ConnectionBox<Data>(continuation: continuation)
@@ -567,12 +619,14 @@ class FtpClient: @unchecked Sendable {
567
619
  func receiveMore() {
568
620
  connection.receive(minimumIncompleteLength: 1, maximumLength: 8192) { data, _, isComplete, error in
569
621
  if let error = error {
622
+ print("FTP DEBUG: receiveData error: \(error)")
570
623
  connectionBox.resume(throwing: error)
571
624
  return
572
625
  }
573
626
 
574
627
  if let data = data {
575
628
  receivedData.append(data)
629
+ print("FTP DEBUG: Received chunk of \(data.count) bytes, total: \(receivedData.count) bytes")
576
630
  if reportProgress {
577
631
  DispatchQueue.main.async {
578
632
  self.progressDelegate?.onProgress(transferred: Int64(receivedData.count), total: -1)
@@ -581,8 +635,10 @@ class FtpClient: @unchecked Sendable {
581
635
  }
582
636
 
583
637
  if isComplete {
638
+ print("FTP DEBUG: Data reception complete, total bytes: \(receivedData.count)")
584
639
  connectionBox.resume(returning: receivedData)
585
640
  } else {
641
+ print("FTP DEBUG: Receiving more data...")
586
642
  receiveMore()
587
643
  }
588
644
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-kookit",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "React Native module for intercepting volume button presses on iOS and Android, with FTP client functionality",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",