Swift Custom Response Serializer is returning imag

2019-06-04 18:33发布

问题:

I am currently using Alamofire to Fetch Json data/url-images from a Server. I also created a custom response serializer using this tutorial to convert url images into UIImages upon request.

Everything works fine, and I am able to load all of the Images from the server into a UIImageView. The user can then swipe from left to right in order to View each image like a Photo Gallery.

The Problem I am having is that my custom response returns the images in a different order.

Therefore, every image being displayed is not in the correct order it initially started in. Would anyone know how I can fix this...?

The only way I've been able to make it work is if I loop through 0...4. But i need to loop through the entire NSMutableArray.

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)

        ###fetch json images and convert nsdata to image
        ###for some odd reason the order doesn't change if i do. (i < 4)
        for var i = 0; i < self.mutable_pages.count; i++ {
            let urlString: NSString = self.mutable_pages[i] as NSString
            var imgURL: NSURL = NSURL(string: urlString)!

            ###So far the images are in the order that I want
            Alamofire.request(.GET, imgURL).responseImage() {
                (request, _, image, error) in

                if error == nil && image != nil {
                    dispatch_async(dispatch_get_main_queue(), {

                        ###Somehow the images get appended at a random order, why?
                        self.pageImages.append(image!)
                    })
                }
            }

        }
    }
}

CUSTOM RESPONSE

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

###This returns the images in a different order...
  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)
    })
  }
}

回答1:

Somehow the images get appended at a random order, why?

Because order is not guaranteed for asynchronous requests or blocks dispatched asynchronously.

Instead of appending images into an array, you should key them into a dictionary according to their corresponding page (e.g. pages[i] = image) (by the way, it's easier and more conventional to use for i in 0..<pages.count { ... }).

Or even better, only request the images on demand using AFNetworking's UIImageView category.