FileProvider: «CopyItem ()» вызывается дважды -> ошибка (загрузка по FTP) - PullRequest
0 голосов
/ 13 мая 2019

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

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

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

Я создал простой «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.ftpLogin весь раздел self.ftpRetrieve вызывается дважды.
  • А внутри FTPHelper.ftpRetrieve весь раздел self.attributesOfItem вызывается дважды.
  • И, вероятно, так далее ...

ftpProvider?.copyItem использует тот же ftpDownloadfunc, так что, по крайней мере, я знаю, почему это касается и contents(), и copyItem().

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...