FileProvider:"CopyItem()";被称为两次->错误(FTP下载) [英] FileProvider: "CopyItem()" is called twice -> error (FTP download)

查看:99
本文介绍了FileProvider:"CopyItem()";被称为两次->错误(FTP下载)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The first view of my app (Swift 5, Xcode 10, iOS 12) has a "username" TextField and a "login" Button. Clicking on the button checks if there's a file for the entered username on my FTP server and downloads it to the Documents folder on the device. For this I'm using 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函数,该函数还可以覆盖本地文件.

I'm checking if the file already exists on the device because FileProvider doesn't seem to provide a copyItem function for downloading that also lets you overwrite the local file.

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

The problem is that copyItem tries to do everything twice: Downloading the file the first time succeeds (and it actually exists in Documents, I checked) because I manually delete the file if it already exists. The second try fails because the file already exists and this copyItem function doesn't know how to overwrite and of course doesn't call my code to delete the original again.

该如何解决?

编辑/更新:

我在ftp服务器的根目录下创建了一个简单的"sample.txt"(内部文本:"sample.txt的Hello world!"),然后尝试读取该文件以供以后自己保存.为此,我使用"Sample-iOS.swift"文件中的代码

I created a simple "sample.txt" at the root of my ftp server (text inside :"Hello world from sample.txt!"), then tried to just read the file to later save it myself. For this I'm using this code from the "Sample-iOS.swift" file here.

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

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

But it also does this twice! The output for the "sample.txt" file is:

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.

为什么还要两次调用呢?我只调用一次函数,开始下载"也只打印一次.

Why is it calling this twice too? I'm only calling my function once and "start download" is also only printed once.

编辑/更新2:

我做了更多的调查,发现在contents函数中两次被称为什么:

I did some more investigating and found out what's called twice in the contents function:

  • 这是整个self.ftpDownload部分!
  • 在FTPHelper.ftpLogin中,整个self.ftpRetrieve部分为 叫了两次.
  • 在FTPHelper.ftp内并检索整个self.attributesOfItem 部分被调用两次.
  • 大概如此...
  • It's the whole self.ftpDownload section!
  • And inside FTPHelper.ftpLogin the whole self.ftpRetrieve section is called twice.
  • And inside FTPHelper.ftpRetrieve the whole self.attributesOfItem section is called twice.
  • And probably so on...

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

ftpProvider?.copyItem uses the same ftpDownload func, so at least I know why both contents() and copyItem() are affected.

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

The same question remains though: Why is it calling these functions twice and how do I fix this?

推荐答案

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

This isn't an answer that shows an actual fix for FileProvider!

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

Unfortunately the library is pretty buggy currently, with functions being called twice (which you can kind of prevent by using a "firstTimeCalled" bool check) and if the server's slow(-ish), you also might not get e.g. the full list of files in a directory because FileProvider stops receiving answers before the server's actually done.

我还没有找到其他可以正常工作的Swift库FTP库(并且仍然受支持),所以现在我在使用

I haven't found any other FTP libraries for Swift that work (and are still supported), so now I'm using BlueSocket (which is able to open sockets, send commands to the server and receive commands from it) and built my own small library that can send/receive,... files (using the FTP codes) around it.

这篇关于FileProvider:"CopyItem()";被称为两次->错误(FTP下载)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆