Q:

Fetch Images From ICloud Will Freeze The UI

I'm using BSImagePicker lib for choosing multiple images in my App, when user select Images stored on ICloud only the UI will freeze up on the images picker controller until the images are downloaded I tried to fix it but with no results 
Here is my code :
Choosing the images and show them in slider
 @IBAction func choose_images(_ sender: Any) {

        bs_presentImagePickerController(vc, animated: true,
                                        select: { (asset: PHAsset) -> Void in
                                            // User selected an asset.
                                            // Do something with it, start upload perhaps?
        }, deselect: { (asset: PHAsset) -> Void in
            // User deselected an assets.
            // Do something, cancel upload?
        }, cancel: { (assets: [PHAsset]) -> Void in

        }, finish: { (assets: [PHAsset]) -> Void in
            // User finished with these assets

            // print(assets.count)

            DispatchQueue.main.async{
                self.imagesource.removeAll()
                self.imagesdata.removeAll()
                for img in assets{

                    self.imagesource.append(ImageSource(image:  self.getUIImage(asset: img)!))
                    self.imagesdata.append(self.getUIImage(asset: img)!)
                }

                self.slider.setImageInputs(self.imagesource)
                self.slider.contentScaleMode = UIViewContentMode.scaleAspectFill
                self.slider.slideshowInterval = 2
                self.slider.zoomEnabled = true
                self.slider.backgroundColor = UIColor.black
                self.slider.pageControlPosition = PageControlPosition.insideScrollView
                let recognizer = UITapGestureRecognizer(target: self, action: #selector(self.didTap))
                self.slider.addGestureRecognizer(recognizer)
            }
        }, completion: nil)

    }

Function to return the image for chosen assets 
func getUIImage(asset: PHAsset) -> UIImage? {

        var img: UIImage?
        let manager = PHImageManager.default()
        let options = PHImageRequestOptions()
        options.version = .original
        options.isNetworkAccessAllowed = true
        options.isSynchronous = true
        options.progressHandler = { (progress, error, stop, info) in
            if(progress == 1.0){
                SVProgressHUD.dismiss()
            } else {

                SVProgressHUD.showProgress(Float(progress), status: "Downloading from iCloud")

            }
        }
        manager.requestImage(for: asset, targetSize:PHImageManagerMaximumSize, contentMode: PHImageContentMode.aspectFit, options: options) { (image, info) in

            img = image
        }

        return img
    }

Any Help will be much appreciated 

A:

Your primary issue is that you are synchronously accessing the remote images on the main queue. You need to perform your loop in the background.
You need to update the code in your finish block as follows:
}, finish: { (assets: [PHAsset]) -> Void in
    DispatchQueue.global().async {
        self.imagesource.removeAll()
        self.imagesdata.removeAll()
        for img in assets {
            if let res = getUIImage(asset: img) {
                self.imagesource.append(ImageSource(image: res))
                self.imagesdata.append(res)
            }
        }

        DispatchQueue.main.async {
            self.slider.setImageInputs(self.imagesource)
            self.slider.contentScaleMode = UIViewContentMode.scaleAspectFill
            self.slider.slideshowInterval = 2
            self.slider.zoomEnabled = true
            self.slider.backgroundColor = UIColor.black
            self.slider.pageControlPosition = PageControlPosition.insideScrollView
            let recognizer = UITapGestureRecognizer(target: self, action: #selector(self.didTap))
            self.slider.addGestureRecognizer(recognizer)
        }
    }

You may also have to update the progress handler inside getUIImage to update the SVProgressHUD on the main queue.
Note that with the above code you should keep your getUIImage as-is except for the one change I just mentioned.

