Swift:URLSessionDownload文件说它存在,但它不存在?

sky*_*guy 11 ios nsurlsession nsurlsessiondownloadtask swift

好的,我已成功下载各种m4a文件,并通过URLSession删除它们.我的问题是在URLSessionDownloadDelegate要求的最终"完成"功能中,我有时会将以下内容打印到控制台,即使我在下载func(下载之前)检查文件是否存在于目录中.非常困惑.这是消息:

File download succesfully
    “CFNetworkDownload_1wGgxs.tmp” couldn’t be moved to “Documents” because an item with the same name already exists.
    The task finished successfully
Run Code Online (Sandbox Code Playgroud)

这是下载功能,我检查显示文件是否存在:

func goDownload()
    {
        if let audioUrl = downloadUrl { //set at beginning

            let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
            let destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent)
            print(destinationUrl)

            // to check if it exists before downloading it
            if FileManager.default.fileExists(atPath: destinationUrl.path) {
                print("********** The file already exists at path")

                // if the file doesn't exist
            } else {

                print("---------------> Starting Download")


                currentTask = session.downloadTask(with: audioUrl)
                currentTask.resume()
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是完成功能:

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {

        print("File download succesfully")
        let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

        // lets create your destination file url
        let destinationUrl = documentsDirectoryURL.appendingPathComponent((downloadUrl?.lastPathComponent)!)

        do {
            try FileManager.default.moveItem(at: location, to: destinationUrl)

            //success
            print("************** SUCCESS File moved to documents folder", downloadUrl)
            playModeStreaming = false

            self.pausePlay()
            AudioPlayerManager.shared.play(url: downloadUrl)

        } catch let error as NSError {
            print(error.localizedDescription)
        }


    }
Run Code Online (Sandbox Code Playgroud)

我甚至实现了一个检查函数,它返回文件是否存在,在获得上述消息后,它返回false:

func checkIfExists(url: URL)->Bool
    {
        return FileManager.default.fileExists(atPath: url.path)
    }
Run Code Online (Sandbox Code Playgroud)

是什么造成的?如何确保下载以便它可以播放m4a?

Gra*_*rks 5

您的代码与标题为“处理下载完成和错误”部分中Apple 的示例代码非常接近。但不完全是……你print("File download succesfully")正在做出一个很大的假设!

我看到的增量urlSession:... didFinishDownloadingTo:是您跳过了检查downloadTask.response.statusCode以确保下载成功。Apple 检查它是否在 200...299 范围内。

您可以尝试添加此 HTTP 状态代码检查,以防您收到的错误消息是伪造的并且您实际上遇到了网络故障。

来自苹果网站的检查代码:

...
didFinishDownloadingTo location: URL) {

guard let httpResponse = downloadTask.response as? HTTPURLResponse,
    (200...299).contains(httpResponse.statusCode) else {
        print ("server error")
        return
}

... now do the FileManager code
Run Code Online (Sandbox Code Playgroud)