web-dev-qa-db-ja.com

Alamofireダウンロードの問題

私はダウンロードしようとしています この画像 Xcode 8.0およびSwift 3.0。

これが私のリクエストです:

    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の新しいバージョンに問題があるのですか、それともどこかで何かを忘れているのですか?

ありがとう!

19
Tulleb

cnoon(Alamofireメンバー)からの公式回答:

@Tulleb様

すぐに返信がないことをお詫びします。 @katopzの例は、同じタイプのリクエストではありません。この例は、ダウンロードタスクではなく、データタスクの使用方法を示しています。ファイルをダウンロードしたくない場合は、代わりに以下を実行できます。

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

ただし、元の質問に答えるために、サンドボックスの権限の問題が発生しています。独自のサンドボックスの外部にあるファイルにアクセスできるmacOSなどのオペレーティングシステムの宛先クロージャーを指定せずに、ダウンロードAPIを使用できます。ただし、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 // [レスポンス]:{URL: https://httpbin.org/image/png } {ステータスコード:200、ヘッダー{// "Access-Control-Allow-Origin" = "*"; // "Content-Length" = 8090; // "Content-Type" = "image/png"; //日付= "2016年9月24日土曜日21:34:25 GMT"; //
サーバー= nginx; // "access-control-allow-credentials" = true; //}} // [TemporaryURL]:/private/var/mobile/Containers/Data/Application/25612024-9A05-4ED5-AF3B-A98E22DEAD7A/tmp/CFNetworkDownload_fD9sXf.tmp // [DestinationURL]:/ var/mobile/Containers /Data/Application/25612024-9A05-4ED5-AF3B-A98E22DEAD7A/Documents/image.png // [ResumeData]:0 bytes // [Result]:SUCCESS:8090 bytes // [Timeline]:Timeline:{"Request Start時間」:496445664.792、「初期応答時間」:496445665.651、「リクエスト完了時間」:496445665.655、「シリアル化完了時間」:496445665.655、「待ち時間」:0.860秒、「リクエスト時間」:0.863秒、「シリアル化時間」:0.000 secs、 "Total Duration":0.864 secs} // Optional(、{100、100})ファイルをディスクにダウンロードする必要がある場合は、宛先クロージャーを使用する必要があります。一時ファイルは、Alamofireで内部的に処理されるデリゲートコールバック内でのみアクセスできます。 iOSで宛先クロージャーを指定しない場合、temporalURLは常に一時ファイルが以前に保管された場所を指しますが、クリーンアップされています。

概要

したがって、要約すると、データをディスクにダウンロードする必要がない場合は、オプション1が必要です。ファイルをディスクに保存する場合は、オプション2が必要です。

乾杯。 ????

30
Tulleb