2016-09-14 10 views
14

Próbuję pobrać this picture w moim kodzie za pomocą Alamofire 4.0.0 z Xcode 8.0 i Swift 3.0.Problem pobierania Alamofire

Oto moja prośba:

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

uzyskać następujące odpowiedź z serwera:

BŁĄD: responseSerializationFailed (Alamofire.AFError.ResponseSerializationFailureReason.inputFileReadFailed (file: /// prywatne /var/mobile/Containers/Data/Application/50400F41-47FD-4276-8903-F48D942D064A/tmp/CFNetworkDownload_D1Aqkh.tmp))

Nie mam pojęcia, jak to naprawić ... Czy nowa wersja Alamofire ma jakieś problemy, czy może ja gdzieś zapomniałem?

Dzięki!

Odpowiedz

18

Official answer from cnoon (Alamofire member):

Hi @Tulleb,

Przepraszamy za nie wracając do ciebie wcześniej. Przykład @katopz to nie ten sam typ żądania. Ten przykład pokazuje, jak używać zadania danych, a nie pobierania. Jeśli nie chcesz, aby pobrać plik , można zamiast wykonać następujące czynności:

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

Jednak, aby odpowiedzieć jesteś oryginalne pytanie, używasz do wydania uprawnień piaskownicy. Umożliwiamy korzystanie z interfejsów API pobierania bez określania zamknięcia docelowego do obsługi systemów , takich jak system MacOS, gdzie można uzyskać dostęp do plików spoza własnej piaskownicy . Jednak w systemie iOS nie można uzyskać bezpośredniego dostępu do danych pliku spoza piaskownicy. Właśnie dlatego pojawia się błąd .inputFileReadFailed.

Istnieje kilka sposobów rozwiązania tego problemu.

Wariant 1

można pobrać dane za pomocą interfejsu API żądania, jak pokazano powyżej której pobiera dane obrazu do pamięci, a nie na dysku.

Opcja 2

Można przenieść plik do piaskownicy przed uzyskaniem dostępu do danych za pomocą zamknięcie docelowy.Oto przykład jak to zrobić:

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

// Wyjścia:

// [Request]: https://httpbin.org/image/png // [Odpowiedź]: {URL: https://httpbin.org/image/png } {kod stanu: 200, nagłówki {// "Access-Control-Allow-Origin" = "*"; // "Długość treści" = 8090; // "Content-Type" = "image/png"; // Date = "So, 24 września 2016 21:34:25 GMT"; //
Serwer = 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 bajtów // [Wynik]: SUKCES: 8090 bajtów // [Oś czasu]: Oś czasu: {"Czas rozpoczęcia żądania": 496445664.792, "Początkowy Czas odpowiedzi": 496445665.651, "Żądanie czasu zakończenia": 496445665.655, "Czas ukończenia serializacji": 496445665.655, "Opóźnienie": 0,860 s, "Czas trwania żądania": 0,863 secs, "Serialization Duration": 0,000 s, "Total Duration": 0,864 s}} Opcjonalnie (, {100, 100}) MUSISZ użyć zamknięcie celu, jeśli chcesz pobrać plik na dysk. Do pliku tymczasowego można uzyskać dostęp tylko wewnątrz wywołania zwrotnego, który jest obsługiwany wewnętrznie w Alamofire . Jeśli nie określisz docelowego zamknięcia w systemie iOS, wskaźnik tymczasowy będzie zawsze wskazywał na , gdzie plik tymczasowy był wcześniej zapisany, ale został wyczyszczony.

Podsumowanie

Tak w skrócie, jeśli nie trzeba pobierać dane na dysku, a następnie chcesz wariant 1. Jeżeli chcesz zapisać plik na dysku, a następnie chcą Opcja 2

Pozdrawiam.

+0

Bardzo jasna odpowiedź, bardzo dziękuję. – Adagio

+0

Wystąpiłem w tej samej sprawie. Dziękuję za odpowiedź! – user30646

Powiązane problemy