我的应用程序的第一个视图(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"文件中的此代码。
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.ftpretive整个
self.attributesOfItem
部分称为两次。 - 可能是...
ftpProvider?.copyItem
使用相同的ftpDownload
func,所以至少我知道为什么contents()
和copyItem()
都受到影响。
相同的问题仍然存在:为什么它将这些功能调用两次,我该如何解决?
这不是显示FileProvider的实际修复的答案!
不幸的是,该库当前很笨拙,功能被称为两次(您可以通过使用"首次任命"的bool检查来防止函数(,如果服务器的慢速(-ish(,您也可能无法获得,例如。目录中文件的完整列表是因为FileProvider在服务器实际完成之前停止接收答案。
我还没有找到任何其他FTP库来进行Swift(并且仍然支持(,因此现在我使用的是Bluesocket(能够打开插座,将命令发送到服务器并从中接收命令(和构建了我自己的小库,可以发送/接收,...围绕它的文件(使用FTP代码(。