Swift downloadTask请求文件下载不起作用

时间:2017-04-19 09:38:12

标签: ios swift3 nsurlsession nsurlsessiondownloadtask

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

我希望它保存为存在的文件。文件类型可以是PNG,JPEG,PDF,DOCX,PPTX,XLSX。尝试了许多事情,但徒劳无功。我确信它一定是简单的,我不知道在这里理解

尝试以下方法。大多数示例中存在差异,文件名在URL中。但我发送id并获取文件作为回应。

How to download file in swift?

How To Download Multiple Files Sequentially using NSURLSession downloadTask in Swift

以下是我的代码。

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()

}

1 个答案:

答案 0 :(得分:2)

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

使用与现代网址相关的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返回原始数据,而不是将文件下载到临时位置并直接保存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()

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