【问题标题】:Alamofire download issueAlamofire 下载问题
【发布时间】:2017-01-22 06:09:57
【问题描述】:

我正在尝试使用带有 Xcode 8.0 和 Swift 3.0 的 Alamofire 4.0.0 在我的代码中下载 this picture

这是我的要求:

    func download(_ path: String, _ completionHandler: @escaping (Any?) -> ()) {
        let stringURL = "https://slove.tulleb.com/uploads/6/6/0/2/66027561/2791411.jpg-1447979839.png"

        print("Requesting \(stringURL)...")

        _ = Alamofire.download(stringURL)
            .responseData { response in
                print(response)

                if let data = response.result.value {
                    completionHandler(UIImage(data: data))
                } else {
                    completionHandler(nil)
                }
        }
    }

我从服务器得到以下答案:

失败: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.inputFileReadFailed(file:///private/var/mobile/Containers/Data/Application/50400F41-47FD-4276-8903-F48D942D064A/tmp/CFNetworkDownload_D1Aqkh.tmp))

我不知道如何解决这个问题... Alamofire 新版本有问题还是我在某个地方忘记了什么?

谢谢!

【问题讨论】:

    标签: swift alamofire


    【解决方案1】:

    Official answer from cnoon (Alamofire member):

    嗨@Tulleb,

    很抱歉没有尽快回复您。 @katopz 的例子是 不是同一类型的请求。该示例演示了如何使用 数据任务,而不是下载任务。如果您不想下载 文件,您可以改为执行以下操作:

    Alamofire.request(url).responseData { response in
         guard let data = response.result.value else { return }
         let image = UIImage(data: data)
         print(image)
    }
    

    但是,要回答您的原始问题,您遇到了沙盒权限问题。我们允许您使用 下载 API 而不指定用于操作的目标闭包 macOS 等系统,您可以在其中访问自己以外的文件 沙盒。但是,在 iOS 上,您不能直接访问 沙盒之外的文件。这就是为什么你看到 .inputFileReadFailed 错误。

    有几种方法可以解决这个问题。

    选项 1

    您可以使用请求 API 下载数据,如上图所示 将图像数据下载到内存,而不是磁盘。

    选项 2

    您可以在访问数据之前将文件移动到沙箱中 使用目的地闭包。以下是如何做到这一点的示例:

    let destination: DownloadRequest.DownloadFileDestination = { _, _ in
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,
    .userDomainMask, true)[0]
    let documentsURL = URL(fileURLWithPath: documentsPath, isDirectory: true)
    let fileURL = documentsURL.appendingPathComponent("image.png")
    
    return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) }
    
    Alamofire.download("https://httpbin.org/image/png", to:
    destination).responseData { response in
        debugPrint(response)
    
        if let data = response.result.value {
            let image = UIImage(data: data)
            print(image)
        } else {
            print("Data was invalid")
        }
    }
    

    // 输出:

    // [请求]:https://httpbin.org/image/png // [响应]: { 网址:https://httpbin.org/image/png } { status code: 200, headers { // "Access-Control-Allow-Origin" = "*"; // "内容长度" = 8090; // “内容类型” = “图像/png”; // 日期 = "2016 年 9 月 24 日星期六 21:34:25 GMT"; //
    服务器 = nginx; // "访问控制允许凭据" = true; // } } // [临时网址]: /private/var/mobile/Containers/Data/Application/25612024-9A05-4ED5-AF3B-A98E22DEAD7A/tmp/CFNetworkDownload_fD9sXf.tmp // [目标网址]: /var/mobile/Containers/Data/Application/25612024-9A05-4ED5-AF3B-A98E22DEAD7A/Documents/image.png // [ResumeData]: 0 bytes // [Result]: SUCCESS: 8090 bytes // [时间线]:时间线:{“请求开始时间”:496445664.792,“初始 响应时间”:496445665.651,“请求完成时间”: 496445665.655,“序列化完成时间”:496445665.655,“延迟”:0.860 秒,“请求持续时间”:0.863 秒,“序列化 持续时间”:0.000 秒,“总持续时间”:0.864 秒 } // Optional(, {100, 100}) 你必须使用 如果您需要将文件下载到磁盘,则目标关闭。这 临时文件只能在委托回调中访问 在 Alamofire 内部处理。如果您不指定 iOS 上的目标关闭,temporaryURL 将始终指向 临时文件之前存储的位置,但已被清理。

    总结

    总而言之,如果您不需要将数据下载到磁盘,那么 你想要选项 1。如果你确实想将文件保存在磁盘上,那么你 想要选项 2。

    干杯。 ?

    【讨论】:

    • 我遇到了同样的问题。感谢您的回答!
    猜你喜欢
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多