· 通过url下载文件
· 得到temp文件后copy至document
· 利用UIDocumentPickerViewController的exportToService,弹出保存文件选项
(UIDocumentPickerViewController的exportToService 在iOS11以后才适用)
override func rightBarButtonAction(btn: UIButton) {
guard let urlStr = url, let taskUrl = URL(string: urlStr) else { return }
debugPrint("文件下载url:\(taskUrl)")
let request = URLRequest(url: taskUrl)
let session = URLSession(configuration: .default)
session.downloadTask(with: request) { [weak self] tempUrl, response, error in
guard let self = self, let tempUrl = tempUrl, error == nil else {
debugPrint("文件下载失败")
SWToast.showText(message: "文件下载失败")
return
}
debugPrint("文件下载完成\(tempUrl)")
// 下载完成之后会自动删除temp中的文件,把文件移动到document中。
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
debugPrint("文件下载完成 documentsDirectory \(documentsDirectory)")
// 建议使用的文件名,一般跟服务器端的文件名一致
let destinationPath = documentsDirectory.appendingPathComponent(response?.suggestedFilename ?? "")
// 如果存在同名的
if FileManager.default.fileExists(atPath: destinationPath.path) {
do {
try FileManager.default.removeItem(atPath: destinationPath.path)
} catch _ {
}
}
debugPrint("文件下载 document下的可保存的url:\(destinationPath)")
do {
// 文件移动至document
try FileManager.default.copyItem(atPath: tempUrl.path, toPath: destinationPath.path)
// main
DispatchQueue.main.async {
self.saveFileToPhone(url: destinationPath)
}
} catch let error {
debugPrint(error)
SWToast.showText(message: "\(error.localizedDescription)")
}
}.resume()
}
func saveFileToPhone(url: URL) {
let picker = UIDocumentPickerViewController(url: url, in: .exportToService)
picker.delegate = self
picker.modalPresentationStyle = .formSheet
self.present(picker, animated: true)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
// 保存成功
SWToast.showText(message: "保存成功")
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
// SWToast.showText(message: "PickerWasCancelled")
}
如果接口返回的是流数据stream
· 下载后得到Data,data再写入文件
guard let url = URL(string: url) else { return }
var request = URLRequest(url: url)
let resultHeaders: [String: String] = ["Authorization": VKLoginManager.authorization ?? "",
"X-Frontend-Tenant-Code": tenantCode]
request.headers = HTTPHeaders(resultHeaders)
request.httpMethod = "GET"
let session = URLSession(configuration: .default)
session.dataTask(with: request) { data, response, error in
var name = Date().toString(format: "yyyyMMddHHmmss")
if let res = response as? HTTPURLResponse,
let disposition = res.allHeaderFields["Content-Disposition"] as? String {
if disposition.contains(find: "filename=") == true {
let pdfList = disposition.components(separatedBy: "filename=")
if let pdfName = pdfList.last {
if let fileName = pdfName.components(separatedBy: ".pdf").first {
name = fileName.urlDecoded
}
}
}
}
guard let outputURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent(name).appendingPathExtension("pdf")
else { fatalError("appendingPath失败") }
DispatchQueue.main.async {
do {
try data?.write(to: outputURL, options: .atomic)
//
self.saveFileToPhone(url: outputURL )
} catch let error {
debugPrint(error)
}
}
}.resume()
如图