import CoreData
class CoreDataStack {
static let shared = CoreDataStack()
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "MyApp")
container.loadPersistentStores { description, error in
if let error = error {
fatalError("Unable to load persistent stores: \(error)")
}
}
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return container
}()
var viewContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
func newBackgroundContext() -> NSManagedObjectContext {
return persistentContainer.newBackgroundContext()
}
func saveContext() {
let context = viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
print("Error saving context: \(nserror), \(nserror.userInfo)")
}
}
}
}
import CoreData
import Combine
class PostRepository {
private let context: NSManagedObjectContext
init(context: NSManagedObjectContext = CoreDataStack.shared.viewContext) {
self.context = context
}
func fetchPosts() -> [PostEntity] {
let request: NSFetchRequest<PostEntity> = PostEntity.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: false)]
do {
return try context.fetch(request)
} catch {
print("Error fetching posts: \(error)")
return []
}
}
func savePost(id: Int, title: String, body: String, authorId: Int) {
let post = PostEntity(context: context)
post.id = Int64(id)
post.title = title
post.body = body
post.authorId = Int64(authorId)
post.createdAt = Date()
CoreDataStack.shared.saveContext()
}
func syncPosts(from apiPosts: [Post]) {
let backgroundContext = CoreDataStack.shared.newBackgroundContext()
backgroundContext.perform {
// Delete old posts
let deleteRequest = NSBatchDeleteRequest(
fetchRequest: PostEntity.fetchRequest()
)
do {
try backgroundContext.execute(deleteRequest)
// Insert new posts
for apiPost in apiPosts {
let post = PostEntity(context: backgroundContext)
post.id = Int64(apiPost.id)
post.title = apiPost.title
post.body = apiPost.body
post.authorId = Int64(apiPost.authorId)
post.createdAt = Date()
}
try backgroundContext.save()
} catch {
print("Error syncing posts: \(error)")
}
}
}
func searchPosts(query: String) -> [PostEntity] {
let request: NSFetchRequest<PostEntity> = PostEntity.fetchRequest()
request.predicate = NSPredicate(format: "title CONTAINS[cd] %@ OR body CONTAINS[cd] %@", query, query)
request.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: false)]
do {
return try context.fetch(request)
} catch {
print("Error searching posts: \(error)")
return []
}
}
}
Core Data is Apple's object graph and persistence framework, essential for complex data models and offline support. I define entities and relationships in the .xcdatamodeld file, then generate NSManagedObject subclasses. The NSPersistentContainer encapsulates the stack—model, store coordinator, and contexts. I perform all operations on the main context for UI updates and background contexts for imports. Fetch requests with predicates and sort descriptors query data efficiently. Core Data provides automatic change tracking, undo/redo, and iCloud sync. For simple persistence, I use UserDefaults or Codable with FileManager, but Core Data excels with relationships and large datasets.