FTP transfers work correctly on older iPhone models but not on newer models, why?

Here is the code that handles the FTP upload:

let finalRemoteName = self.fileName + ".jpg"
let dispatch = DispatchQueue(label: "Uploader", qos : .background)
let ftp = FTPAccess.init(baseUrl: FTP_URL, userName: FTP_USERNAME, password: FTP_PW, remotePath: "")
dispatch.async {
  guard let ftpStream = ftp.ftpWriteStream(forFileName:
  finalRemoteName) 
     else {
         self.errorMessage = "Failed to create FTPStream"
         self.result = .Error
         self.resultMessage = "Failed"
         return
     }  
  if CFWriteStreamOpen(ftpStream) == false {
     self.errorMessage = "Could not open FTPStream"
     self.resultMessage = "Failed"
     self.result = .Error
  }
  let fileSize = self.data.count
  let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: fileSize)
  self.data.copyBytes(to: buffer, count: fileSize)
  defer {
      CFWriteStreamClose(ftpStream)
      buffer.deallocate(capacity: fileSize)}
      var offset: Int = 0
      var dataToSendSize: Int = fileSize
  repeat {
      DispatchQueue.main.async {
         self.progress = 1.0 -  
         Float(dataToSendSize) / Float(fileSize)
  }
      let bytesWritten = CFWriteStreamWrite(ftpStream, 
          &buffer[offset], dataToSendSize)
  if (bytesWritten > 0) {
      offset += bytesWritten.littleEndian
      dataToSendSize -= bytesWritten
      continue
  }
  else if (bytesWritten < 0) {
      self.errorMessage = "FTP Upload Error"
      self.resultMessage = "Failed"
      self.result = .Error
      return
  }
  else if (bytesWritten == 0) {
     print("Finished Upload")
     DispatchQueue.main.sync {
     self.resultMessage = "Success"
     self.result = .Success
   }
   return
   }
 }.   while (true) }. 
 return self.result
 }
}

}`

Again, this works perfectly on the simulator, all versions, and for older iPhone models. On newer iPhone models the upload simply isn't working and I'm not sure why.

Here are my questions?

  1. How would you go about capturing the error message IF there is an error message being captured because it's not causing a crash that would show up in TestFlight?

  2. Could this possibly be a case of the info file being incorrect for an app that communicates with an external FTP server? If so, why does it work for older phones but not newer ones and what is the solution?

  3. Another problem I'm facing is that the upload speed is terribly slow. It's not like this on the Android version of the app so I know it's not an issue with the server itself. Do you see anything in here that would possibly limit the chunk size of the uploaded image possibly? Is there another reason I'm missing?

OK, let’s start with the big picture…

Why are you using FTP?

From Apple’s perspective, we’ve not just deprecated our FTP APIs but we’ve deprecated the entire FTP protocol. You should move away from FTP if at all possible. See my On FTP post for more on this.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I simply want to know WHY it doesn't work on newer models in any case?

The reality of software development is that sometimes things break. If a supported API changes behaviour in a way that breaks compatibility with your app, you can file a bug report about that. And if you test assiduously with pre-release seeds, it’s possible that you can detect, and Apple can correct, such misbehaviour before any of your customers are affected.

In contrast, there’s little point in filing a bug against a deprecated API, like CFFTPStream, because Apple engineering will just send it back as ‘not to be fixed’.

I’ve not seen any reports about CFFTPStream being completely broken on modern systems. It’s possible that your usage pattern is what’s triggering this behaviour. Your code is very strange. If you continue to rely on CFFTPStream, you should switch to using it asynchronously with a delegate. The SimpleFTPSample sample code shows the pattern I recommend.

However, I encourage you to move away from CFFTPStream sooner rather than later. Ideally you shouldn’t use FTP at all but if your client insists on this feature then CFFTPStream is not the right solution. One day it will break completely, or Apple remove it, at which point you’ll have to urgently switch to a different FTP implementation. It’s better to get switch that out of the way now, while your CFFTPStream is working well enough to keep your current product in play.

So, in summary:

  • Test SimpleFTPSample against your server to see if it works.

  • If it does, adopt its design pattern in your main app as a short-term solution.

  • Work with your client to come up with a plan for switching off CFFTPStream sooner rather than later. That means writing, or acquiring, your own FTP implementation.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks, I think I was hoping someone would tell me that there's a setting in the info list that I need to enable or something on newer versions. I'll try implementing the simpleFTP.

FTP transfers work correctly on older iPhone models but not on newer models, why?
 
 
Q