2016-09-14 5 views
14

私のコードでAlamofire 4.0.0とXcode 8.0とSwift 3.0を使用してthis pictureをダウンロードしようとしています。ここでAlamofireダウンロードの問題

は私の要求です:

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

私は、サーバーから、次の答えを得る:

FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.inputFileReadFailed(ファイル:///プライベート/var/mobile/Containers/Data/Application/50400F41-47FD-4276-8903-F48D942D064A/tmp/CFNetworkDownload_D1Aqkh.tmp))

私はこれを修正する方法を知りません...いくつかの問題を抱えているAlamofireの新しいバージョンですか、それとも私はどこかの何かを忘れていますか?

ありがとうございます!

答えて

18

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

しかし、あなたは元の質問だ答えるために、あなたはサンドボックスのアクセス許可の問題に実行しています。 サンドボックスの外部にあるファイルにアクセスできる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"; // Date = "Sat、2020年9月24日21:34:25 GMT"; //
サーバー= nginx; // "access-control-allow-credentials" =真; //} } // [TemporaryURL]: /private/var/mobile/Containers/Data/Application/25612024-9A05-4ED5-AF3B-A98E22DEAD7A/tmp/CFNetworkDownload_fD9sXf.tmp // [DestinationURL]: /VAR/[結果]:SUCCESS:8090 bytes // [タイムライン]:[完了]をクリックします。タイムライン:{"Request Start Time":496445664.792、 "Initial Response Time":496445665.651、 "Request Completed Time": 496445665.655、 "Serialization Completed Time":496445665.655、 "Latency":0.860 secs、 "Request Duration":0.863秒、「シリアル化 継続時間」:0.000秒、「合計継続時間」:0.864秒)// オプション(、{100,100})012を使用する必要がありますファイルをディスクにダウンロードする必要がある場合は、宛先クロージャ。 テンポラリファイルは、 がAlamofireで内部的に処理されるデリゲートコールバック内でのみアクセスできます。 iOS上で デスティネーションクロージャを指定しない場合、temporaryURLは常に を指します。この一時ファイルは以前に保存されていたものの、クリーンアップされています。

概要

あなたがデータをディスクにダウンロードする必要はありません場合は、ディスク上のファイルを保存したい場合は、オプション1をしたい ので要約すると、その後、あなたはオプション2をしたい 。

乾杯。

+0

非常に明確な答えです、ありがとうございます。 – Adagio

+0

私は同じ問題を抱えていました。答えをありがとう! – user30646

関連する問題