Swift-下载文件后保存文件到“文件”APP

· 通过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()

如图


exportToService.jpeg

你可能感兴趣的:(Swift-下载文件后保存文件到“文件”APP)