Section 5/181 menit

5. ModelContainer dan ModelContext

5. ModelContainer dan ModelContext

ModelContainer

ModelContainer adalah konfigurasi dan owner dari persistent store. Biasanya dibuat sekali per aplikasi.

swift
// Setup ModelContainer — paling simpel
let container = try ModelContainer(for: Book.self)

// Setup dengan konfigurasi kustom
let config = ModelConfiguration(
    schema: Schema([Book.self, Author.self, Category.self]),
    isStoredInMemoryOnly: false,     // false = simpan ke disk (default)
    allowsSave: true,
    cloudKitDatabase: .automatic     // aktifkan CloudKit sync
)
let container = try ModelContainer(for: Schema([Book.self, Author.self]), configurations: config)

// In-memory store untuk testing
let testConfig = ModelConfiguration(isStoredInMemoryOnly: true)
let testContainer = try ModelContainer(
    for: Schema([Book.self]),
    configurations: testConfig
)

ModelContext

ModelContext adalah unit kerja — tempat semua CRUD dilakukan. Setiap operasi terjadi di in-memory scratchpad context sebelum disimpan ke persistent store.

swift
// Mendapat context dari container
let context = container.mainContext  // main thread context

// INSERT: menambah model baru
let book = Book(title: "Clean Code", author: "Robert C. Martin", publishedYear: 2008)
context.insert(book)
try context.save()

// FETCH manual (bukan @Query)
let descriptor = FetchDescriptor<Book>(
    predicate: #Predicate { $0.isRead == false },
    sortBy: [SortDescriptor(\Book.title)]
)
let unreadBooks = try context.fetch(descriptor)

// UPDATE: langsung modifikasi property, lalu save
book.isRead = true
try context.save()

// DELETE
context.delete(book)
try context.save()

// Fetch by ID (PersistentIdentifier)
if let found = context.model(for: persistentID) as? Book {
    print(found.title)
}

Autosave

SwiftData mainContext memiliki autosave yang aktif secara default — ia menyimpan setiap kali run loop berakhir, mirip dengan Core Data viewContext autosave. Untuk background context, autosave tidak aktif dan harus dipanggil manual.

swift
// Menonaktifkan autosave di main context (jarang diperlukan)
container.mainContext.autosaveEnabled = false

// Untuk kontrol granular, gunakan undoManager
context.undoManager = UndoManager()
// ... lakukan perubahan ...
context.undoManager?.undo()  // revert tanpa save