Swift 下载请求文件的 downloadTask 不工作

Swift downloadTask with request file download not working

我正在尝试通过发送文件 ID 从服务器下载文件。我尝试了几件事,但文件正在下载为 CFNetworkDownload.tmp 文件。

我希望它保存为现有的文件。文件类型可以是 PNG、JPEG、PDF、DOCX、PPTX、XLSX。尝试了很多东西但徒劳无功。我确定这一定很简单,我在这里无法理解

尝试了以下方法。大多数例子的不同之处在于,文件名在 URL 中。但我发送 id 并获取文件作为响应。

下面是我的代码。

func downloadFile(id : String, fileName : String) -> Void {


    let session = URLSession.shared
    let url = URL(string: qaDownloadURL+id)!

    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    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("Success: \(statusCode)")
            }

            do {



//                    let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
//                    
//                    self.savePath = documentsUrl!.absoluteString + "/" + fileName
//                    
//                    let fileURL = URL(fileURLWithPath: self.savePath)
//                    
//                    let dataFromURL = NSData(contentsOf: tempLocalUrl)
//                    dataFromURL?.write(to: fileURL, atomically: true)

                var documentsDirectory: String?

                let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)

                if paths.count > 0
                {
                    documentsDirectory = paths.first!
                }

                self.savePath = documentsDirectory!// + "/" + fileName

                let fileURL = URL(fileURLWithPath: self.savePath)


                let dataFromURL = NSData(contentsOf: tempLocalUrl)
                dataFromURL?.write(to: fileURL, atomically: true)


              //  try FileManager.default.copyItem(at: tempLocalUrl, to: fileURL)


                DispatchQueue.main.async {

                    let documentController = UIDocumentInteractionController.init(url: fileURL)
                    documentController.delegate = self
                    documentController.presentPreview(animated: true)

                }   

            } catch (let writeError) {
                print("error writing file \(self.savePath) : \(writeError)")
            }

        } else {
            print("Failure: %@", error?.localizedDescription);
        }
    }
    task.resume()

}

您不能将数据写入代表目录的位置,您需要指定包含文件名的完整路径。

使用现代 URL 相关 API 你可以用

替换整个 do
    do {
            let documentFolderURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            let fileURL = documentFolderURL.appendingPathComponent(fileName)
            try FileManager.default.copyItem(at: tempLocalUrl, to: fileURL)

            DispatchQueue.main.async {

                let documentController = UIDocumentInteractionController.init(url: fileURL)
                documentController.delegate = self
                documentController.presentPreview(animated: true)

            }    
        }

或使用 URLSessionDataTask 其中 returns 原始数据而不是将文件下载到临时位置并直接保存 Data 例如

let task = session.dataTask(with: request) { (data, response, error) in
    guard error == nil else {
        print(error!)
        return
    }
    // Success
    if let statusCode = (response as? HTTPURLResponse)?.statusCode {
        print("Success: \(statusCode)")
    }

    do {
        let documentFolderURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        let fileURL = documentFolderURL.appendingPathComponent(fileName)
        try data!.write(to: fileURL)

        DispatchQueue.main.async {

            let documentController = UIDocumentInteractionController.init(url: fileURL)
            documentController.delegate = self
            documentController.presentPreview(animated: true)

        }

    } catch  {
        print("error writing file \(fileName) : \(error)")
    }
}
task.resume()

如果这不起作用,则错误与其他地方有关。