Первый вид моего приложения (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
использует тот же ftpDownload
func, так что, по крайней мере, я знаю, почему это касается и contents()
, и copyItem()
.
Остается тот же вопрос: почему он вызывает эти функции дважды и как я могу это исправить?