Reading Local Data with Core Data

Learn how to fetch and read data from Core Data in your Swift application. This guide covers creating fetch requests and processing the results.

Reading Local Data with Core Data

Note:

This tutorial builds on the previous one, showing you how to read the data that you've saved locally using Core Data.

Overview

In our previous article, we saw how to save collections and values to the on-device database using Core Data.

In this article, we will see how to read the saved data. As always, let's start by accessing the viewContext from the AppDelegate in the relevant UIViewController. It's a good practice to put this data-fetching logic inside a function so we can easily call it from different places, like viewDidLoad or viewWillAppear.

Accessing the AppDelegate Context

func fetchData() {
    // 1. Get a reference to the AppDelegate and the context
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
    let context = appDelegate.persistentContainer.viewContext
    
    // ... fetching logic will go here
}

Step 1: Creating a Fetch Request

To read data, you need to create an NSFetchRequest. This object describes the search criteria used to retrieve data from a persistent store.

Let's define a request to fetch all objects from our "Shopping" entity.

// Inside the fetchData() function
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Shopping")

You can optionally set returnsObjectsAsFaults to false. This tells Core Data to fully fetch the object data right away, which can sometimes prevent issues where related data isn't immediately available.

fetchRequest.returnsObjectsAsFaults = false

Step 2: Executing the Fetch Request and Processing Results

Now, we'll execute the fetch request. This is also a "throwing" operation, so it must be done inside a do-try-catch block. If successful, it returns an array of NSManagedObject instances that match the request.

We can then loop through this array and extract the values for each attribute using value(forKey:).

Let's create an array to hold the names from our shopping list and then populate it from the fetch results.

// In your UIViewController, at the class level
var nameArray = [String]()
var idArray = [UUID]()


// Inside the fetchData() function, after creating the fetchRequest
do {
    let results = try context.fetch(fetchRequest)
    
    // Clear arrays before populating to avoid duplicates
    self.nameArray.removeAll(keepingCapacity: false)
    self.idArray.removeAll(keepingCapacity: false)
    
    for result in results as! [NSManagedObject] {
        if let name = result.value(forKey: "name") as? String {
            self.nameArray.append(name)
        }
        if let id = result.value(forKey: "id") as? UUID {
            self.idArray.append(id)
        }
    }
    
    // Don't forget to reload your TableView to show the new data!
    // self.tableView.reloadData()
    
} catch {
    print("Error fetching data: \(error)")
}
Fetch and Process Data

Complete fetchData() Function

Here is the full function for fetching and processing the data.

func fetchData() {
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
    let context = appDelegate.persistentContainer.viewContext
    
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Shopping")
    fetchRequest.returnsObjectsAsFaults = false
    
    do {
        let results = try context.fetch(fetchRequest)
        
        self.nameArray.removeAll(keepingCapacity: false)
        self.idArray.removeAll(keepingCapacity: false)
        
        if results.count > 0 {
            for result in results as! [NSManagedObject] {
                if let name = result.value(forKey: "name") as? String {
                    self.nameArray.append(name)
                }
                
                if let id = result.value(forKey: "id") as? UUID {
                    self.idArray.append(id)
                }
            }
            // self.tableView.reloadData()
        }
    } catch {
        print("Error fetching data: \(error)")
    }
}

Note:

Reading data from Core Data is a fundamental skill. Once you fetch the data, you can populate UITableViews, update your UI, and perform other application logic.