将文件下载到 Swift 4 (Mac OS) 中的临时位置,就像使用 curl
Download a file to a temp location in Swift 4 (Mac OS) like with curl
我正在 Swift 4 中为 MacOS 编写 CLI 工具。
如果我 "cheat" 并使用 shell 函数,然后使用 curl 命令,我会得到我想要的结果:
func shell(_ args: String...) -> Int32 {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
shell("/usr/bin/curl", "-OL", "http://mywebserver/myfile.whatever")
如何在 Swift 4 中以本地方式执行相同的操作?
我尝试使用 just 库:https://github.com/dduan/Just
但我无法弄清楚如何简单地将文件从 URL 下载到文件系统上的特定位置。
我还找到了 Swift 3 和 5 以及 iOS 的各种解决方案,但显然对我不起作用。
您可以使用downloadTask
下载
- 创建会话配置
- 使用此配置创建 URLSession
- 应用下载任务
- 下载成功后,将数据复制到目的地
let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.jpg")
//Create URL to the source file you want to download
let fileURL = URL(string: "https://en.wikipedia.org/wiki/Saint_Martin#/media/File:Saint_martin_map.PNG")
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
}
}
task.resume()
}
简单示例:由于URLSession
的异步行为,您必须在恢复数据任务后启动runloop,并在完成处理程序中停止它。
let runLoop = CFRunLoopGetCurrent()
let url = URL(string: "http://mywebserver/myfile.whatever")!
let dataTask = URLSession.shared.dataTask(with: url) { data, response, error in
let returnValue : Int32
if let error = error {
fputs("\(error.localizedDescription)\n", stderr)
returnValue = EXIT_FAILURE
} else {
let result = String(data:data!, encoding:.utf8)!
fputs("\(result)\n", stdout)
returnValue = EXIT_SUCCESS
}
CFRunLoopStop(runLoop)
exit(returnValue)
}
dataTask.resume()
CFRunLoopRun()
代码returns标准输出中的数据。可以将数据直接写入磁盘,替换
let result = String(data:data!, encoding:.utf8)!
fputs("\(result)\n", stdout)
和
let fileURL = URL(fileURLWithPath: "/Users/me/path/to/file.ext")
do {
try data!.write(to: fileURL)
} catch {
fputs("\(error.localizedDescription)\n", stderr)
}
我正在 Swift 4 中为 MacOS 编写 CLI 工具。 如果我 "cheat" 并使用 shell 函数,然后使用 curl 命令,我会得到我想要的结果:
func shell(_ args: String...) -> Int32 {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
shell("/usr/bin/curl", "-OL", "http://mywebserver/myfile.whatever")
如何在 Swift 4 中以本地方式执行相同的操作? 我尝试使用 just 库:https://github.com/dduan/Just 但我无法弄清楚如何简单地将文件从 URL 下载到文件系统上的特定位置。 我还找到了 Swift 3 和 5 以及 iOS 的各种解决方案,但显然对我不起作用。
您可以使用downloadTask
- 创建会话配置
- 使用此配置创建 URLSession
- 应用下载任务
- 下载成功后,将数据复制到目的地
let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.jpg")
//Create URL to the source file you want to download
let fileURL = URL(string: "https://en.wikipedia.org/wiki/Saint_Martin#/media/File:Saint_martin_map.PNG")
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
}
}
task.resume()
}
简单示例:由于URLSession
的异步行为,您必须在恢复数据任务后启动runloop,并在完成处理程序中停止它。
let runLoop = CFRunLoopGetCurrent()
let url = URL(string: "http://mywebserver/myfile.whatever")!
let dataTask = URLSession.shared.dataTask(with: url) { data, response, error in
let returnValue : Int32
if let error = error {
fputs("\(error.localizedDescription)\n", stderr)
returnValue = EXIT_FAILURE
} else {
let result = String(data:data!, encoding:.utf8)!
fputs("\(result)\n", stdout)
returnValue = EXIT_SUCCESS
}
CFRunLoopStop(runLoop)
exit(returnValue)
}
dataTask.resume()
CFRunLoopRun()
代码returns标准输出中的数据。可以将数据直接写入磁盘,替换
let result = String(data:data!, encoding:.utf8)!
fputs("\(result)\n", stdout)
和
let fileURL = URL(fileURLWithPath: "/Users/me/path/to/file.ext")
do {
try data!.write(to: fileURL)
} catch {
fputs("\(error.localizedDescription)\n", stderr)
}