FileProvider: "CopyItem()" вызывается дважды -> ошибка (загрузка по FTP)

Первый вид моего приложения (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 функция не знает, как перезаписать и, конечно, не вызывает мой код, чтобы снова удалить оригинал.

Что я могу сделать, чтобы это исправить?

Редактировать /Update:

Я создал простой "sample.txt" в корне моего ftp-сервера (текст внутри:"Hello world from sample.txt!"), А затем попытался просто прочитать файл, чтобы позже сохранить его сам. Для этого я использую этот код из файла "Sample-iOS.swift" здесь.

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.ftp Логин весь self.ftpRetrieve раздел вызывается дважды.
  • А внутри FTPHelper.ftp восстановить всю self.attributesOfItemраздел вызывается дважды.
  • И, наверное, так далее...

ftpProvider?.copyItem использует то же самое ftpDownload func, так что, по крайней мере, я знаю, почему оба contents() а также copyItem() находятся под влиянием.

Однако остается тот же вопрос: почему он вызывает эти функции дважды и как мне это исправить?

0 ответов

Это не ответ, который показывает фактическое исправление для FileProvider!

К сожалению, в настоящее время библиотека довольно глючная, функции вызываются дважды (что можно отчасти предотвратить, используя проверку bool firstTimeCalled), и если сервер работает медленно (-ish), вы также можете не получить, например, полный список файлов. в каталоге, потому что FileProvider перестает получать ответы до того, как сервер фактически завершил работу.

Я не нашел никаких других библиотек FTP для Swift, которые бы работали (и все еще поддерживаются), поэтому теперь я использую BlueSocket (который может открывать сокеты, отправлять команды на сервер и получать команды от него) и собирать свои собственные небольшая библиотека, которая может отправлять / получать,... файлы (используя коды FTP) вокруг него.

Другие вопросы по тегам