Section 12/181 menit

12. History Tracking: Perubahan Data Lintas Session

12. History Tracking: Perubahan Data Lintas Session

SwiftData (via Core Data) mendukung Persistent History Tracking — log semua perubahan yang terjadi di store, bahkan dari proses lain (extension, background sync, dll).

swift
// Setup: aktifkan history tracking di ModelConfiguration
let config = ModelConfiguration(
    schema: Schema([Task.self]),
    isStoredInMemoryOnly: false,
    allowsSave: true
)

// History tracking otomatis aktif saat CloudKit sync digunakan
// Untuk setup manual via Core Data:
// NSPersistentStoreDescription.setOption(true as NSNumber,
//     forKey: NSPersistentHistoryTrackingKey)

// Monitoring perubahan dari proses lain (misal: share extension)
class RemoteChangeProcessor {
    private var lastHistoryToken: NSPersistentHistoryToken?
    
    func processRemoteChanges(container: NSPersistentContainer) {
        let context = container.newBackgroundContext()
        context.perform {
            let fetchHistoryRequest = NSPersistentHistoryChangeRequest.fetchHistory(
                after: self.lastHistoryToken
            )
            
            guard let result = try? context.execute(fetchHistoryRequest) as? NSPersistentHistoryResult,
                  let transactions = result.result as? [NSPersistentHistoryTransaction] else {
                return
            }
            
            for transaction in transactions {
                for change in transaction.changes ?? [] {
                    switch change.changeType {
                    case .insert:
                        print("Inserted: \(change.changedObjectID)")
                    case .update:
                        print("Updated: \(change.changedObjectID)")
                        print("Changed keys: \(change.updatedProperties?.map(\.name) ?? [])")
                    case .delete:
                        print("Deleted: \(change.changedObjectID)")
                    @unknown default:
                        break
                    }
                }
            }
            
            // Update token
            self.lastHistoryToken = transactions.last?.token
            
            // Purge old history
            if let token = self.lastHistoryToken {
                let purgeRequest = NSPersistentHistoryChangeRequest.deleteHistory(before: token)
                try? context.execute(purgeRequest)
            }
        }
    }
}