ios - Swift:downloadTaskWithURL 有时 "succeeds"具有非零位置,即使文件不存在

标签 ios swift avfoundation nsurlsession nsurlsessiondownloadtask

downloadTaskWithURL 函数有时会为不存在的文件返回一个非零位置。

在测试环境中http://192.168.0.102:3000/p/1461224691.mp4没有文件

大多数时候,在此 URL 上调用 downloadTaskWithURL 会产生预期的错误消息:

Error downloading message during network operation. Download URL: http://192.168.0.102:3000/p/1461224691.mp4. Location: nil. Error: Optional(Error Domain=NSURLErrorDomain Code=-1100 "The requested URL was not found on this server." UserInfo=0x17547b640 {NSErrorFailingURLKey=http://192.168.0.102:3000/p/1461224691.mp4, NSLocalizedDescription=The requested URL was not found on this server., NSErrorFailingURLStringKey=http://192.168.0.102:3000/p/1461224691.mp4})

偶尔,downloadTaskWithURL 会以不确定的方式相信文件存在,并向 location 变量写入一些内容。因此,保护​​条件不会失败,代码会继续执行……这是不应该的。

fileManager.moveItemAtURL(location!, toURL: fileURL) 创建的永久文件只有 1 个字节,确认网络文件从一开始就不存在。

为什么 downloadTaskWithURL 会这样?

func download() {
    // Verify <networkURL>
    guard let downloadURL = NSURL(string: networkURL) where !networkURL.isEmpty else {
        print("Error downloading message: invalid download URL. URL: \(networkURL)")
        return
    }

    // Generate filename for storing locally
    let suffix = (networkURL as NSString).pathExtension
    let localFilename = getUniqueFilename("." + suffix)

    // Create download request
    let task = NSURLSession.sharedSession().downloadTaskWithURL(downloadURL) { location, response, error in
        guard location != nil && error == nil else {
            print("Error downloading message during network operation. Download URL: \(downloadURL). Location: \(location). Error: \(error)")
            return
        }

        // If here, no errors so save message to permanent location
        let fileManager = NSFileManager.defaultManager()
        do {
            let documents = try fileManager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
            let fileURL = documents.URLByAppendingPathComponent(localFilename)
            try fileManager.moveItemAtURL(location!, toURL: fileURL)
            self.doFileDownloaded(fileURL, localFilename: localFilename)
            print("Downloaded file @ \(localFilename). Download URL: \(downloadURL)")
        } catch {
            print("Error downloading message during save operation. Network URL: \(self.networkURL). Filename: \(localFilename). Error: \(error)")
        }
    }

    // Start download
    print("Starting download @ \(downloadURL)")
    task.resume()
}

最佳答案

澄清一下,服务器返回 404,但下载任务返回一个基本为空的文件?并且您确定服务器确实返回了错误代码(通过验证服务器日志)?

无论哪种方式,我都建议检查响应对象中的状态代码。如果不是 200,则下载任务可能只是下载了错误页面的响应正文。或者,如果状态代码为 0,则连接超时。无论哪种方式,都将其视为失败。

您也可以尝试强制这一切发生在单个线程上,看看不确定性是否消失。

关于ios - Swift:downloadTaskWithURL 有时 "succeeds"具有非零位置,即使文件不存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36807020/

相关文章:

ios - 为什么我不必在 Swift 中使用 NSBundle 之前导入 Foundation?

swift - 字段子集的集合差异

android - 适用于 Android/iOS/WinPhone 的 Xamarin 共性层

ios - 强制 UILabel 显示 2 行

ios - 使用键值编码的核心数据验证

objective-c - swift 中的 Objective C static const

ios - 如何将文件从 Swift 中的文档/收件箱移动到内部应用程序,如 "try FileManager.default.moveItem"?

ios - 有没有办法拦截应用程序中的音频输出以在 iOS 上显示音频可视化工具?

ios - 可以在启动相机应用程序时控制白平衡模式吗? (iOS)

ios - 如何在 iOS 6 中获取 "Turn on WiFi for more Accurate User Location"