Как загрузить изображение в быстром использовании Alamofire
У меня есть контроллер представления коллекции, который загружает изображение Async по URL-адресу.
(Что-то вроде Instegram)
Я ищу лучший способ реализовать часть загружаемого изображения.
скажите, пожалуйста, что вы думаете
Первый способ - без внешней библиотеки:
let downloadQueue = dispatch_queue_create("com.pro.asyncImages",nil)
dispatch_async(downloadQueue){
var data = NSData(contentsOfURL: NSURL(string: pictureUrl!)!)
var image: UIImage?
if (data != nil){
image = UIImage(data: data!)
}
dispatch_async(dispatch_get_main_queue()){
uiImageView.image = image
}
}
Второй способ - использование Alamofire (запрос принадлежит Alamofire)
if let mediaUrl = info.mediaUrl {
request(.GET,mediaUrl).response(){
(_, _, data, _) in
let image = UIImage(data: data! as NSData)
imageView.image = image
}
}
И, наконец, я прочитал, что AFNetworking отлично справляется с загрузкой url async в urlImage, что я и хочу делать.
Итак, AFNetworking лучше для этой задачи? (тогда Аламофир)
а если нет, я не понял, как добавить AFNetworking в мой быстрый проект, помимо добавления #import "AFNetworking.h", какие файлы мне нужно добавить?
Пожалуйста, объясните, какой метод является лучшим, мои потребности - это производительность, обвинение, кеширование.
контроллер коллекции представлений действует как Instegram и загружает изображения при прокрутке вниз.
Надеюсь, я был достаточно ясен о том, что мне нужно,
спасибо
Ответы
Ответ 1
Как упоминают авторы в Alamofire README.md:
Когда следует использовать AFNetworking?
- Расширения UIKit, такие как асинхронная загрузка изображений в UIImageView
Итак, ответьте на свой вопрос:
Так лучше ли AFNetworking для этой задачи?
Да!
Но если вы все еще хотите использовать проект vanilla Alamofire
, вы можете получить изображение таким образом:
Alamofire.request(.GET, "https://robohash.org/123.png").response { (request, response, data, error) in
self.myImageView.image = UIImage(data: data, scale:1)
}
P.S.
Но если вы просто хотите загрузить изображение (конечно, асинхронно) - вам не нужно использовать Alamofire
или AFNetworking
вообще.
Просто добавьте это небольшое расширение в свой код:
extension UIImageView {
public func imageFromUrl(urlString: String) {
if let url = NSURL(string: urlString) {
let request = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
self.image = UIImage(data: data)
}
}
}
}
И используйте его:
myImageView.imageFromUrl("https://robohash.org/123.png")
Ответ 2
Я создал Swift версию UIImageView + AFNetworking здесь: Github.
Вам не нужно использовать AFNetworking (и заголовок моста) или Alamofire в вашем проекте. Просто добавьте файл в свой проект и используйте его.
Пример использования:
myImageView.setImageWithUrl(imageUrl, placeHolderImage: somePlaceHolderImage)
Ответ 3
Взято из Alamofire/README.md
"Чтобы Alamofire уделял особое внимание основным сетевым реализациям, разработчики Alamofire Software Foundation создали дополнительные библиотеки компонентов для обеспечения дополнительных функциональных возможностей экосистемы Alamofire.
AlamofireImage - библиотека изображений, включающая сериализаторы ответов на изображения, расширения UIImage и UIImageView, настраиваемые фильтры изображений, кеш-память в автоматическом режиме и система загрузки изображений на основе приоритетов.
https://github.com/Alamofire/AlamofireImage
Ответ 4
Если вы хотите использовать инфраструктуру AFNetworking UImageView, вы должны сделать #import "UIImageView+AFNetworking.h"
в своем файле заголовка моста.
AFNetworking имеет общий кэш, поэтому вам не нужно вручную кэшировать или отменять ваши запросы. setImageWithURL
из AFNetworking может легко конвертировать URL-адрес изображения в ImageView.
Пример кода с помощью UIImage+AFNetworking
:
cell.imageView.setImageWithURL(NSURL(string:imageSource), placeholderImage: UIImage(named:"placeholder"))
Если вы используете Alamofire, вам необходимо вручную преобразовать NSData в UIImage. Для Alamofire вы можете создать объект NSCache()
для кэширования ваших изображений. Производительность обеих библиотек должна быть одинаковой. Вы можете использовать Alamofire для вызовов API сервера, а затем использовать AFNetworking для отображения изображений асинхронно.
Пример кода с использованием Alamofire для кэша изображений:
let imageCache = NSCache()
if let image = self.imageCache.objectForKey(imageURL) as? UIImage {
cell.imageView.image = image
} else {
// 3
cell.imageView.image = nil
// 4
cell.request = Alamofire.request(.GET, imageURL).validate(contentType: ["image/*"]).responseImage() {
(request, _, image, error) in
if error == nil && image != nil {
// 5
self.imageCache.setObject(image!, forKey: request.URLString)
// 6
if request.URLString == cell.request?.request.URLString {
cell.imageView.image = image
}
} else {
/*
If the cell went off-screen before the image was downloaded, we cancel it and
an NSURLErrorDomain (-999: cancelled) is returned. This is a normal behavior.
*/
}
}
}
Вы можете прочитать этот учебник для более подробной информации об использовании Alamofire.
Ответ 5
Здесь подход с использованием RxAlamofire:
import Alamofire
import RxAlamofire
extension UIImageView {
public func imageFromUrl(urlString: String) {
requestData(.GET, urlString)
.observeOn(MainScheduler.instance)
.subscribeNext { self.image = UIImage(data: $0.1) }
}
}
Ответ 6
На самом деле существует несколько способов загрузки изображения из URL с помощью Alamofire.
и это способ, который я разработал, и я использую его уже в одном из моих проектов Swift. Таким образом, я загружаю изображения Asyncrounsly и отображаю их в UITableView, а по производительности - это хорошо, и при прокрутке UITableView нет блокировки, потому что он заботится об обналичивании загруженных изображений.
Сначала вам нужно создать запрос GET, используя Alamofire, чтобы загрузить изображение, и вы должны использовать Request + AlamofireImage из библиотеки AlamofireImage, чтобы вы могли
import AlamofireImage
И затем в
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
}
вы должны вызвать запрос на загрузку изображения следующим образом:
//Download image
// We should perform this in a background thread
Alamofire.request(.GET, deshItem.dish_imageUrl!)
.responseImage { response in
debugPrint(response)
print(response.request)
print(response.response)
debugPrint(response.result)
if let image = response.result.value {
print("image downloaded: \(image)")
// Store the commit date in to our cache
self.ImageCache[dishName!] = image
// Update the cell
dispatch_async(dispatch_get_main_queue(), {
if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
let dishImageView:UIImageView = cellToUpdate.viewWithTag(104) as! UIImageView
dishImageView.image = image
}
})
}
}
Для кэширования изображений я создал словарь, который будет содержать изображение для каждой ячейки или элемента (String). Таким образом, этот способ кэширования изображений позволит избежать блокировки, появляющейся при прокрутке.
Полный код:
import AlamofireImage
class MainFeedTableViewController: UITableViewController, FloatRatingViewDelegate {
var ImageCache = [String:UIImage]()
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("MainFeedCellID", forIndexPath: indexPath)
// Configure the cell...
let dishName = deshItem.dish_name
//This is a workaround to cash the image and improve the performance while user scrolling UITableView.
// If this image is already cached, don't re-download
if let dishImage = ImageCache[dishName!] {
let dishImageView:UIImageView = cell.viewWithTag(104) as! UIImageView
dishImageView.image = dishImage
}
else {
//Download image
// We should perform this in a background thread
Alamofire.request(.GET, deshItem.dish_imageUrl!)
.responseImage { response in
debugPrint(response)
print(response.request)
print(response.response)
debugPrint(response.result)
if let image = response.result.value {
print("image downloaded: \(image)")
// Store the commit date in to our cache
self.ImageCache[dishName!] = image
// Update the cell
dispatch_async(dispatch_get_main_queue(), {
if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
let dishImageView:UIImageView = cellToUpdate.viewWithTag(104) as! UIImageView
dishImageView.image = image
}
})
}
}
}
return cell
}
Ответ 7
Я разработал небольшую и простую библиотеку CocoaPods для работы с Alamofire и Images.
CocoaPods - отличный способ удовлетворения потребностей в библиотечных зависимостях. Его легко установить один раз и легко добавить и обновить зависимости к вашим проектам.
Библиотека имеет открытый исходный код и находится в https://github.com/gchiacchio/AlamoImage
У него отличная документация с примерами, поэтому вы будете наслаждаться ею в считанные минуты.
Я работаю над этим проектом, включая просмотр коллекции и прокрутку.