top of page
  • Writer's pictureVaughn Geber

🔧Simplifying Core Data Management🚀

Github: https://github.com/vGebs/CoreDataWrapperiOS


Core Data is a powerful framework provided by Apple for data persistence in iOS, macOS, watchOS, and tvOS applications. It enables developers to easily create, fetch, update, and delete data objects within their applications. However, working with Core Data can sometimes be complex and cumbersome. In this blog post, we will discuss a Core Data abstraction called CoreDataWrapper, which simplifies the process of managing Core Data objects in your application.

Core Data Abstraction

The CoreDataWrapper is a custom class that encapsulates the essential components required to interact with the Core Data framework. It provides methods for creating, fetching, saving, and deleting objects, abstracting away the complexity of the Core Data stack.

import Foundation
import CoreData

public class CoreDataWrapper {
    private let modelName: String
    private let storeURL: URL
    
    private lazy var managedObjectModel: NSManagedObjectModel = {
        guard let modelURL = Bundle.main.url(forResource: self.modelName, withExtension: "momd") else {
            fatalError("CoreDataWrapper: Unable to find Data Model: \(self.modelName)")
        }
        guard let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL) else {
            fatalError("CoreDataWrapper: Unable to load Data Model: \(self.modelName)")
        }
        return managedObjectModel
    }()
    
    private lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
        let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
        do {
            try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: self.storeURL, options: nil)
        } catch {
            fatalError("CoreDataWrapper: Unable to add Persistent Store for: \(self.modelName)")
        }
        return persistentStoreCoordinator
    }()
    
    private lazy var managedObjectContext: NSManagedObjectContext = {
        let managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
        return managedObjectContext
    }()
    
    public init(modelName: String, storeURL: URL) {
        self.modelName = modelName
        self.storeURL = storeURL
    }
    
    public func create<T: NSManagedObject>(objectType: T.Type) -> T {
        let newObject = NSEntityDescription.insertNewObject(forEntityName: String(describing: objectType), into: managedObjectContext) as! T
        return newObject
    }
    
    public func fetch<T: NSManagedObject>(fetchRequest: NSFetchRequest<T>) throws -> [T] {
        let results = try managedObjectContext.fetch(fetchRequest)
        return results
    }
    
    public func saveContext() throws {
        guard managedObjectContext.hasChanges else { return }
        try managedObjectContext.save()
    }
    
    public func delete<T: NSManagedObject>(object: T) throws {
        managedObjectContext.delete(object)
        try saveContext()
    }
}

Initialization

The CoreDataWrapper is initialized with the modelName and storeURL parameters, representing the name of the data model and the location where the persistent store will be saved, respectively.


Core Components

The CoreDataWrapper class consists of three core components:

  1. managedObjectModel: An instance of NSManagedObjectModel representing the data model.

  2. persistentStoreCoordinator: An instance of NSPersistentStoreCoordinator, which manages the persistent store and coordinates access to the data.

  3. managedObjectContext: An instance of NSManagedObjectContext that manages a group of model objects and is used for creating, fetching, and saving objects.

These components are initialized using the lazy keyword, meaning that they will be created when they are first accessed.


CRUD Operations

The CoreDataWrapper provides the following methods for performing CRUD operations:

  1. create(objectType:): This method creates a new instance of the specified NSManagedObject subclass.

  2. fetch(fetchRequest:): This method fetches an array of objects matching the provided NSFetchRequest.

  3. saveContext(): This method saves the changes made to the managedObjectContext.

  4. delete(object:): This method deletes the specified object and saves the changes.

Sample Usage: TaskService

To demonstrate the usage of CoreDataWrapper, let's consider a simple TaskService class that manages tasks:

import Foundation
import CoreData

class TaskService {
    private let coreDataStack: CoreDataWrapper

    init() {
        let storeURL = try! FileManager.default
            .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            .appendingPathComponent("TaskModel.sqlite")
        
        self.coreDataStack = CoreDataWrapper(modelName: "TaskModel", storeURL: storeURL)
    }

    func fetchTasks() throws -> [Task] {
        let fetchRequest = NSFetchRequest<Task>(entityName: "Task")
        return try coreDataStack.fetch(fetchRequest: fetchRequest)
    }
    
    func createTask() -> Task {
        return coreDataStack.create(objectType: Task.self)
    }
    
    func delete(_ task: Task) throws {
        try coreDataStack.delete(object: task)
    }
    
    func save() throws {
        try coreDataStack.saveContext()
    }
}   

TaskService is initialized with an instance of CoreDataWrapper and provides methods to fetch, create, delete, and save tasks. The CoreDataWrapper instance handles the underlying Core Data operations, making it easy to work with Core Data objects in your application.


Conclusion

In conclusion, CoreDataWrapper is a handy abstraction that simplifies the process of working with Core Data in your applications. By encapsulating the Core Data stack and providing straightforward methods for CRUD operations, you can focus on implementing the core functionality of your app without worrying about the complexities of Core Data management.


Github: https://github.com/vGebs/CoreDataWrapperiOS


13 views0 comments

Comentários


bottom of page