2016-09-14 5 views
14

Я пытаюсь загрузить this picture в своем коде, используя Alamofire 4.0.0 с Xcode 8.0 и Swift 3.0.Alamofire download issue

Вот мой запрос:

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

Однако, чтобы ответить вы оригинальный вопрос, вы бежите в вопрос разрешений песочницы. Мы разрешаем вам использовать 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 // [ответ]: {URL: https://httpbin.org/image/png } {код состояния: 200, заголовки {// "Access-Control-Allow-Origin" = "*"; // «Content-Length» = 8090; // «Content-Type» = «image/png»; // Дата = "Сб, 24 сен 2016 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]: /вар /mobile/Containers/Data/Application/25612024-9A05-4ED5-AF3B-A98E22DEAD7A/Documents/image.png // [ResumeData]: 0 байт // [Результат]: УСПЕХ: 8090 байт // [Хронология]: Сроки: {«Время начала запроса»: 496445664.792, «Начальное Время отклика»: 496445665.651, «Время выполнения запроса»: 496445665.655, «Время завершения сериализации»: 496445665.655, «Задержка»: 0,860 с, «Длительность запроса»: 0,863 secs, «Сериализация Продолжительность»: 0,000 с, «Общая продолжительность»: 0,864 сек} // Необязательно (, {100, 100}) Вы ДОЛЖНЫ использовать закрытие адресата, если вам нужно загрузить файл на диск. Временной файл доступен только в обратном вызове делегата, который обрабатывается внутри Alamofire. Если вы не укажете закрытие адресата на iOS, временноеURL всегда будет указывать на , где временный файл ранее был сохранен, но был очищен.

Резюме

Таким образом, в общем, если вам не нужно загружать данные на диск, то вы хотите Вариант 1. Если вы хотите, чтобы сохранить файл на диске, то вы хотите Вариант 2 .

Cheers.

+0

Очень четкий ответ, большое спасибо. – Adagio

+0

Я столкнулся с тем же вопросом. Спасибо за ответ! – user30646