0

When I am trying to fetch an 10 images from my gallery it takes very long until I get it.

  1. Why is the image fetching async?
  2. If I change the requestOptions.deliveryMode to .fastFormat it gets fast but I lose a looooot of quality

What is the best that I can do?

func fetchPhotos() {
    let fetchOptions = PHFetchOptions()
    fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    fetchOptions.fetchLimit = 10

    let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: PHAssetMediaType.image, options: fetchOptions)

    if fetchResult.count > 0 {
        let totalImageCountNeeded = 10 // <-- The number of images to fetch
        fetchPhotoAtIndex(0, totalImageCountNeeded, fetchResult)
    }
}

func fetchPhotoAtIndex(_ index:Int, _ totalImageCountNeeded: Int, _ fetchResult: PHFetchResult<PHAsset>) {

    let requestOptions = PHImageRequestOptions()
    requestOptions.deliveryMode = .highQualityFormat

    PHImageManager.default().requestImage(for: fetchResult.object(at: index) as PHAsset, targetSize: view.frame.size, contentMode: PHImageContentMode.aspectFill, options: requestOptions, resultHandler: { (image, _) in
        if let image = image {
            // Add the returned image to your array
            self.images += [image]
        }

        if index + 1 < fetchResult.count && self.images.count < totalImageCountNeeded {
            self.fetchPhotoAtIndex(index + 1, totalImageCountNeeded, fetchResult)
        } else {
            print("Completed array: \(self.images)")
            self.collectionView.reloadData()
        }
    })
}
SwiftiSwift
  • 7,528
  • 9
  • 56
  • 96

2 Answers2

1

I just tested your code and it took about a second to load 50 images, check if there something else in your code that could be slowing downs this process. If your intentions is to have all the images loaded as soon as you present the View Controller consider loading the images on the previous screen.

Ludyem
  • 1,709
  • 1
  • 18
  • 33
  • I don't understand why these are async. I mean for example on Twitter when you have no internet connection you can still access camera roll in their app – SwiftiSwift May 24 '19 at 19:03
  • async doesn't mean that is using the network, "an asynchronous function simply doesn't block the current thread of execution from proceeding on to the next function" – Ludyem May 24 '19 at 19:53
0
  1. The request is async because it needs to use the network. Async just means it takes time to perform, outside of the syncronous execution of the application's threads. Synchronous would be it executes the code in sync with the application thread the code is running on. Here, the thread must wait for the network request to finish.

  2. You'll have a tradeoff between quality and speed. Obviously, the better quality the image, the larger it is, and therefore it takes longer to download.

I'd suggest you download smaller chunks of photos, or rethink your UI such that less images are shown at any one time. You could instead of 10 show 3 images, and preload the next 3 with pagination.

COSMO BAKER
  • 337
  • 4
  • 16