Chapters

Hide chapters

Core Data by Tutorials

Eighth Edition · iOS 14 · Swift 5.3 · Xcode 12

Core Data by Tutorials

Section 1: 11 chapters
Show chapters Hide chapters

4. Intermediate Fetching
Written by Pietro Rea

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the first three chapters of this book, you began to explore the foundations of Core Data, including very basic methods of saving and fetching data within the Core Data persistent store.

To this point, you’ve mostly performed simple, unrefined fetches such as “fetch all BowTie entities.” Sometimes this is all you need to do. Often, you’ll want to exert more control over how you retrieve information from Core Data.

Building on what you’ve learned so far, this chapter dives deep into the topic of fetching. Fetching is a large topic in Core Data, and you have many tools at your disposal. By the end of this chapter, you’ll know how to:

  • Fetch only what you need to
  • Refine your fetched results using predicates
  • Fetch in the background to avoid blocking the UI
  • Avoid unnecessary fetching by updating objects directly in the persistent store

This chapter is a toolbox sampler; its aim is to expose you to many fetching techniques, so when the time comes, you’ll know what tool to use.

NSFetchRequest: the star of the show

As you’ve learned in previous chapters, you fetch records from Core Data by creating an instance of NSFetchRequest, configuring it as you like and handing it over to NSManagedObjectContext to do the heavy lifting.

Seems simple enough, but there are actually five different ways to get hold of a fetch request. Some are more popular than others, but you’ll likely encounter all of them at some point as a Core Data developer.

Before jumping to the starter project for this chapter, here are the five different ways to set up a fetch request so you’re not caught by surprise:

// 1
let fetchRequest1 = NSFetchRequest<Venue>()
let entity = 
  NSEntityDescription.entity(forEntityName: "Venue",
                             in: managedContext)!
fetchRequest1.entity = entity

// 2
let fetchRequest2 = NSFetchRequest<Venue>(entityName: "Venue")

// 3
let fetchRequest3: NSFetchRequest<Venue> = Venue.fetchRequest()

// 4
let fetchRequest4 = 
  managedObjectModel.fetchRequestTemplate(forName: "venueFR")

// 5
let fetchRequest5 =
  managedObjectModel.fetchRequestFromTemplate(
    withName: "venueFR",
    substitutionVariables: ["NAME" : "Vivi Bubble Tea"])

Going through each in turn:

  1. You initialize an instance of NSFetchRequest as generic type: NSFetchRequest<Venue>. At a minimum, you must specify a NSEntityDescription for the fetch request. In this case, the entity is Venue. You initialize an instance of NSEntityDescription and use it to set the fetch request’s entity property.

  2. Here you use NSFetchRequest’s convenience initializer. It initializes a new fetch request and sets its entity property in one step. You simply need to provide a string for the entity name rather than a full-fledged NSEntityDescription.

  3. Just as the second example was a contraction of the first, the third is a contraction of the second. When you generate an NSManagedObject subclass, this step also generates a class method that returns an NSFetchRequest already set up to fetch corresponding entity types. This is where Venue.fetchRequest() comes from. This code lives in Venue+CoreDataProperties.swift.

  4. In the fourth example, you retrieve your fetch request from your NSManagedObjectModel. You can configure and store commonly used fetch requests in Xcode’s data model editor. You’ll learn how to do this later in the chapter.

  5. The last case is similar to the fourth. Retrieve a fetch request from your managed object model, but this time, you pass in some extra variables. These “substitution” variables are used in a predicate to refine your fetched results.

The first three examples are the simple cases you’ve already seen. You’ll see even more of these simple cases in the rest of this chapter, in addition to stored fetch requests and other tricks of NSFetchRequest!

Note: If you’re not already familiar with it, NSFetchRequest is a generic type. If you inspect NSFetchRequest‘s initializer, you’ll notice it takes in type as a parameter <ResultType : NSFetchRequestResult>.

ResultType specifies the type of objects you expect as a result of the fetch request. For example, if you’re expecting an array of Venue objects, the result of the fetch request is now going to be [Venue] instead of [Any]. This is helpful because you don’t have to cast down to [Venue] anymore.

Introducing the BubbleTea app

This chapter’s sample project is a bubble tea app. For those of you who don’t know about bubble tea (also known as “boba tea”), it’s a Taiwanese tea-based drink containing large tapioca pearls. It’s very yummy!

Stored fetch requests

As previously mentioned, you can store frequently used fetch requests right in the data model. Not only does this make them easier to access, but you also get the benefit of using a GUI-based tool to set up the fetch request parameters.

Fetching different result types

All this time, you’ve probably been thinking of NSFetchRequest as a fairly simple tool. You give it some instructions and you get some objects in return. What else is there to it?

Returning a count

Open FilterViewController.swift and add the following below import UIKit:

An alternate way to fetch a count

Now that you’re familiar with .countResultType, it’s a good time to mention that there’s an alternate API for fetching a count directly from Core Data.

Performing calculations with fetch requests

All three price category labels are populated with the number of venues that fall into each category. The next step is to populate the label under “Offering a deal.” It currently says “0 total deals.” That can’t be right!

Sorting fetched results

Another powerful feature of NSFetchRequest is its ability to sort fetched results for you. It does this by using yet another handy Foundation class, NSSortDescriptor. These sorts happen at the SQLite level, not in memory. This makes sorting in Core Data fast and efficient.

Asynchronous fetching

If you’ve reached this point, there’s both good news and bad news (and then more good news). The good news is you’ve learned a lot about what you can do with a plain NSFetchRequest. The bad news is that every fetch request you’ve executed so far has blocked the main thread while you waited for the results to come back.

Batch updates: no fetching required

Sometimes the only reason you fetch objects from Core Data is to change a single attribute. Then, after you make your changes, you have to commit the Core Data objects back to the persistent store and call it a day. This is the normal process you’ve been following all along.

Key points

  • NSFetchRequest is a generic type. It takes a type parameter that specifies the type of objects you expect to get as the result of the fetch request.
  • If you expect to reuse the same type of fetch in different parts of your app, consider using the Data Model Editor to store an immutable fetch request directly in your data model.
  • Use NSFetchRequest’s count result type to efficiently compute and return counts from SQLite.
  • Use NSFetchRequest’s dictionary result type to efficiently compute and return averages, sums and other common calculations from SQLite.
  • A fetch request uses different techniques such as using batch sizes, batch limits and faulting to limit the amount of information returned.
  • Add a sort description to your fetch request to efficiently sort your fetched results.
  • Fetching large amounts of information can block the main thread. Use NSAsynchronousFetchRequest to offload some of this work to a background thread.
  • NSBatchUpdateRequest and NSBatchDeleteRequest reduce the amount of time and memory required to update or delete a large number of records in Core Data.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now