зациклить и добавить данные json в UIImage [] в фоновом режиме Swift

В настоящее время я использую Alamofire для получения данных/URL-изображений Json с сервера.

Все работает нормально, и я могу загрузить все URL-изображения с сервера в UIImageView. Затем пользователь может провести пальцем слева направо, чтобы просмотреть каждое изображение как фотогалерею.

В настоящее время, когда я извлекаю данные, я перебираю свой NSArray, преобразовываю каждый URL-адрес в изображение, а затем добавляю каждое изображение в UIImage[].

Зацикливание NSArray действительно замедляет мое приложение при первом запуске, есть ли способ ускорить этот процесс? Или лучший / более быстрый способ скрыть URL-адреса в изображения в фоновом режиме?

var pages = NSArray()

var mutable_pages = NSMutableArray()
var pageImages: [UIImage] = []

override func viewDidLoad() {
    super.viewDidLoad()

    self.fetchPages()

}

func fetchPages() {
    Alamofire.request(.GET, "http://www.myurl.com/api/pages.json").responseJSON() {
        (_, _, data, _) in

        self.pages = data!.valueForKey("page_url") as NSArray!

        self.mutable_pages = NSMutableArray(array: self.pages)

        ###THIS IS REALLY SLOW, IS THERE A FASTER SOLUTION
        for var i = 0; i < self.mutable_pages.count; i++ {

            ###Construct the imgUrl to get an image URL for the pages
            let urlString: NSString = self.mutable_pages[i] as NSString
            var imgURL: NSURL = NSURL(string: urlString)!
            var imgData: NSData = NSData(contentsOfURL: imgURL)!

            ###append each image into UIImage
            self.pageImages.append(UIImage(data: imgData)!)

        }

    }
}

person Serge Pedroza    schedule 17.12.2014    source источник
comment
Если вы профилируете свой проект, я думаю, вы обнаружите, что var imgData: NSData = NSData(contentsOfURL: imgURL)! — это то, что действительно занимает больше всего времени. Я также не думаю, что это можно обойти; получение изображений является интенсивной задачей.   -  person 67cherries    schedule 17.12.2014
comment
Убедитесь, что выборка/декодирование изображения выполняется вне основного потока. Вам также придется спроектировать свое приложение так, чтобы оно обрабатывало любые случаи, когда изображения недоступны, потому что они все еще загружаются.   -  person nielsbot    schedule 17.12.2014
comment
Вы также можете лениво извлекать изображения. Получить, скажем, первые 3 изображения (изображение 0, изображение 1 и изображение n), а затем каждый раз, когда пользователь проводит пальцем по экрану, извлекать следующее изображение (изображение 2, если он проводит пальцем вправо, изображение n-1, если он проводит пальцем влево).   -  person Paulw11    schedule 17.12.2014
comment
@Paulw11 Paulw11 Мне нравится твоя идея, у тебя есть пример кода. Я совсем новичок в iOS.   -  person Serge Pedroza    schedule 17.12.2014
comment
Проще всего использовать что-то вроде SDWebImage github.com/rs/SDWebImage   -  person Paulw11    schedule 17.12.2014


Ответы (1)


Итак, я нашел решение. По сути, я создал собственный сериализатор ответов, используя этот учебник.

Таким образом, вместо получения NSData, который затем необходимо преобразовать в UIImage, вы можете написать пользовательский сериализатор ответа, чтобы преобразовать его непосредственно в UIImage для вас.

ПОЛЬЗОВАТЕЛЬСКИЙ ОТВЕТ

extension Alamofire.Request {
  class func imageResponseSerializer() -> Serializer {
    return { request, response, data in
      if data == nil {
        return (nil, nil)
      }

      let image = UIImage(data: data!, scale: UIScreen.mainScreen().scale)

      return (image, nil)
  }
}

  func responseImage(completionHandler: (NSURLRequest, NSHTTPURLResponse?, UIImage?, NSError?) -> Void) -> Self {
    return response(serializer: Request.imageResponseSerializer(), completionHandler: { (request, response, image, error) in
      completionHandler(request, response, image as? UIImage, error)
    })
  }
}

Затем я использовал responseImage, найденный в запросе Alamofire внутри cellForIndexAtIndexPath.

var request: Alamofire.Request?

cell.request = Alamofire.request(.GET, imageURL).responseImage() {
  (request, _, image, error) in
  if error == nil && image != nil {
    if request.URLString == cell.request?.request.URLString {
      cell.imageView.image = image
    }
  }
}
person Serge Pedroza    schedule 19.12.2014