【问题标题】:FileProvider: "CopyItem()" is called twice -> error (FTP download)FileProvider:“CopyItem()”被调用了两次 -> 错误(FTP 下载)
【发布时间】:2019-09-30 11:42:12
【问题描述】:

我的应用程序(Swift 5、Xcode 10、iOS 12)的第一个视图有一个“用户名”TextField 和一个“登录名”Button。单击该按钮检查我的 FTP 服务器上是否有输入用户名的文件,并将其下载到设备上的Documents 文件夹。为此,我使用FileProvider

我的代码:

private func download() {
    print("start download") //Only called once!
    let foldername = "myfolder"
    let filename = "mytestfile.txf"
    let server = "192.0.0.1"
    let username = "testuser"
    let password = "testpw"       

    let credential = URLCredential(user: username, password: password, persistence: .permanent)
    let ftpProvider = FTPFileProvider(baseURL: server, mode: FTPFileProvider.Mode.passive, credential: credential, cache: URLCache())

    ftpProvider?.delegate = self as FileProviderDelegate

    let fileManager = FileManager.default
    let source = "/\(foldername)/\(filename)"
    let dest = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(filename)
    let destPath = dest.path

    if fileManager.fileExists(atPath: destPath) {
        print("file already exists!")

        do {
            try fileManager.removeItem(atPath: destPath)
        } catch {
            print("error removing!") //TODO: Error
        }
        print("still exists: \(fileManager.fileExists(atPath: destPath))")
    } else {
        print("file doesn't already exist!")
    }

    let progress = ftpProvider?.copyItem(path: source, toLocalURL: dest, completionHandler: nil)
    progressBar.observedProgress = progress
}

我正在检查该文件是否已存在于设备上,因为FileProvider 似乎没有提供用于下载的copyItem 函数,该函数还可以让您覆盖本地文件。

问题是copyItem 尝试做所有事情两次:第一次下载文件成功(它实际上存在于Documents,我检查了)因为如果文件已经存在,我手动删除它。第二次尝试失败,因为文件已经存在并且这个copyItem函数不知道如何覆盖,当然也不会调用我的代码再次删除原始文件。

我能做些什么来解决这个问题?

编辑/更新:

我在我的 ftp 服务器的根目录下创建了一个简单的“sample.txt”(里面的文本:“来自 sample.txt 的 Hello world!”),然后尝试只读取该文件以便以后自己保存。为此,我使用“Sample-iOS.swift”文件here中的这段代码。

ftpProvider?.contents(path: source, completionHandler: {
    contents, error in
    if let contents = contents {
        print(String(data: contents, encoding: .utf8))
    }
})

但它也会这样做两次! “sample.txt”文件的输出是:

Optional("Hello world from sample.txt!")
Fetching on sample.txt succeed.
Optional("Hello world from sample.txt!Hello world from sample.txt!")
Fetching on sample.txt succeed.

为什么它也调用了两次?我只调用我的函数一次,“开始下载”也只打印一次。

编辑/更新 2:

我做了更多调查,发现在 contents 函数中调用了两次:

  • 这是整个self.ftpDownload 部分!
  • 在 FTPHelper.ftpLogin 中,整个 self.ftpRetrieve 部分是 调用了两次。
  • 在 FTPHelper.ftp 中检索整个self.attributesOfItem 部分被调用了两次。
  • 可能还有……

ftpProvider?.copyItem 使用相同的ftpDownload 函数,所以至少我知道为什么contents()copyItem() 都会受到影响。

同样的问题仍然存在:为什么它调用这些函数两次,我该如何解决这个问题?

【问题讨论】:

    标签: ios swift ftp fileprovider


    【解决方案1】:

    这不是显示 FileProvider 实际修复的答案!

    不幸的是,这个库目前有很多错误,函数被调用了两次(你可以通过使用“firstTimeCalled”布尔检查来防止这种情况),如果服务器很慢(-ish),你也可能不会得到例如目录中文件的完整列表,因为 FileProvider 在服务器实际完成之前停止接收答案。

    我还没有找到任何其他适用于 Swift 的 FTP 库(并且仍然受支持),所以现在我使用 BlueSocket(它能够打开套接字、向服务器发送命令并从中接收命令) ) 并构建了我自己的小型库,可以在它周围发送/接收...文件(使用 FTP 代码)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-29
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      相关资源
      最近更新 更多