1

I use a collection view to display images stored in CoreData, only a few (around 15) but when I scroll down it lags, It seams to be because I am not fetching my data asyncrhronously, is it possible with only 15 UIImages?

So here is my problem I cannot find a descent tutorial on asynchronous fetching in swift anywhere ,3 days I am looking. Sorry if I didn't search well.

This is what arrived to do with some bits from tutorials

    let entity = NSEntityDescription.entityForName("Dreams", inManagedObjectContext: contxt)

    let fetchRequest = NSFetchRequest()
    fetchRequest.entity = entity

    let asyncFetch = NSAsynchronousFetchRequest(fetchRequest: fetchRequest) {
        (result:NSAsynchronousFetchResult!) -> Void in

        if result.finalResult!.count > 0 {
            self.dreams = result.finalResult! as [Dream]
        }
        NSLog("Done.")
    }

Dreams is an array of type [Dream] but when I display the collection view nothing appears This is how I did it previously

    let fetchRequest = NSFetchRequest(entityName: "Dreams")

    if let fetchResults = contxt.executeFetchRequest(fetchRequest, error: nil) as? [Dream] {
        dreams = fetchResults
    }

It worked very well,

Thank you very much for your help

  • Async fetching might help, but maybe not. It depends how your code is structured, so going async might be key or might be a waste of time. For example, where are you performing these fetches? Are you doing individual fetches for each image, or fetching in batches? And are the images actually stored in the persistent store or in external files? – Tom Harrington Jan 16 '15 at 17:50
  • Don't store images in core data if possible, just store names of images and/or file paths – Ian Jan 16 '15 at 17:54
  • For now I stored the images in CoreData as NSData, I fetched the images in view did load, and no I am not using Batches I will try out what you propose (the file path) – Gauthier de Chezelles Jan 16 '15 at 18:13
  • I too facing the same issue , u found any solution for this asynchronous fetching,coredat . @GauthierdeChezelles – Sanju Jun 07 '16 at 06:48

1 Answers1

2

Unfortunately, I don't have time to offer specific code in this instance. I did want to present a basic strategy, however. Fetching on the main thread is exceedingly unlikely to be your problem here, but fetching everything at once definitely could be, particularly with large binary data involved. This should be sped up significantly if:

  1. You start using an NSFetchedResultsController with a good batch size rather than a raw fetch request. NSFetchedResultsController is a little finicky about updates with collection views, in ways which are beyond the specific scope of this question, but they work very well once set up correctly.
  2. You store the images as files instead of in Core Data itself, and store the path to the file instead. Then that image data won't get loaded into memory every time you fault in the object, and you can simply load and display the images as the cells come on screen using that file URL.

People who insist on storing binary data in Core Data usually find that storing the data as the only attribute in a separate "Image" entity with a relationship to the entity you are displaying helps. The image object (along with its binary image data) can then be kept a fault, and thus not in memory, even when the object you fetch for the collection view is in memory. I, however, prefer not to store them in Core Data, and simply handle the resulting atomicity gotchas and the possibility the file Core Data points to got deleted somehow.

Andy Riordan
  • 1,154
  • 1
  • 8
  • 13