FileProvider:“ CopyItem()”被调用两次->错误(FTP下载)

时间:2019-05-13 13:39:01

标签: ios swift ftp fileprovider

我的应用的第一个视图(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()都受到影响。

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

1 个答案:

答案 0 :(得分:0)

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

不幸的是,该库当前存在很多错误,函数被调用了两次(可以通过使用“ firstTimeCalled” bool检查来防止该错误),并且如果服务器运行缓慢(-ish),则也可能无法获取该信息。目录中文件的完整列表,因为FileProvider在服务器实际完成之前停止接收答案。

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