John John - 6 months ago 27
Swift Question

Is it possible to fill two arrays simultaneously?

I have two arrays:

var originalImagesArray = [UIImage]()
var croppedImagesArray = [UIImage]()


and I fill them as:

for i in from..<to {
let asset: PHAsset = self.images[i] as! PHAsset
let imageFetchOptions = PHImageRequestOptions()

self.imageManager.requestImageForAsset(asset, targetSize: CGSize(width: 50, height: 50), contentMode: .AspectFit, options: imageFetchOptions, resultHandler: { (image: UIImage?, info: [NSObject : AnyObject]?) in
if (image != nil) {
print("Little: \(image!.description)")
self.croppedImagesArray.append(image!)
}
})

self.imageManager.requestImageForAsset(asset, targetSize: CGSize(width: 600, height: 600), contentMode: .AspectFit, options: imageFetchOptions, resultHandler: { (image: UIImage?, info: [NSObject : AnyObject]?) in
if (image != nil) {
print("Big: \(image!.description)")
self.originalImagesArray.append(image!)
}
})
}


so, in one array I save images in 50x50, but in another one by 600x600.

The problem is, when I later show images in
didSelect
, I get 2 different images.

For example in
cropped
array in index 5 I get one image, but in
original
on index 5 I get another image.

I want that were 2 same images. How can I achieve this?

1 solution is ordering images in 2 arrays the same way
2 solution is I do all that in wrong way. What I need in that case?

Answer

From the docs for PHImageManager.requestImageForAsset:

By default, this method executes asynchronously. If you call it from a background thread you may change the synchronous property of the options parameter to YES to block the calling thread until either the requested image is ready or an error occurs, at which time Photos calls your result handler.

The issue is that you're invoking the requestImageForAsset in the order you want them, but they are completing asynchronously, which may populate the array in different orders depending on which size completes first.

If you want them in the same order, I'd recommend changing croppedImagesArray and originalImagesArray to dictionaries keyed by something that you can share between them. For example, if the actual order of the assets doesn't matter, as long as they are the same between the two collections, you could key by the asset's localIdentifier, then sort the dictionaries by that identifier when you enumerate the collections. If the actual order matters, pass some other sequence key (perhaps the current timestamp) and share it between the two completion handlers.