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:
managedObjectModel: An instance of NSManagedObjectModel representing the data model.
persistentStoreCoordinator: An instance of NSPersistentStoreCoordinator, which manages the persistent store and coordinates access to the data.
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:
create(objectType:): This method creates a new instance of the specified NSManagedObject subclass.
fetch(fetchRequest:): This method fetches an array of objects matching the provided NSFetchRequest.
saveContext(): This method saves the changes made to the managedObjectContext.
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
Comentários