Section 2/181 menit
2. Masalah yang Dipecahkan di Level Lanjutan
2. Masalah yang Dipecahkan di Level Lanjutan
Data Duplikat saat CloudKit Sync
swift
// ❌ TANPA @Attribute(.unique): import berulang membuat duplikat
@Model
class Article {
var remoteID: String // ID dari server — tidak di-enforce unik
var title: String
init(remoteID: String, title: String) {
self.remoteID = remoteID
self.title = title
}
}
// Kalau sync berjalan 2x, ada 2 Article dengan remoteID sama
func importArticles(_ articles: [ArticleDTO]) {
for dto in articles {
let article = Article(remoteID: dto.id, title: dto.title)
modelContext.insert(article) // Duplikat jika sudah ada!
}
}
swift
// ✓ DENGAN @Attribute(.unique): SwiftData enforce uniqueness + upsert otomatis
@Model
class Article {
@Attribute(.unique) var remoteID: String // Jika ada duplikat → update, tidak insert baru
var title: String
var body: String
init(remoteID: String, title: String, body: String) {
self.remoteID = remoteID
self.title = title
self.body = body
}
}
// Insert dengan unique attribute = upsert otomatis
func importArticles(_ articles: [ArticleDTO]) {
for dto in articles {
let article = Article(remoteID: dto.id, title: dto.title, body: dto.body)
modelContext.insert(article) // Jika remoteID sudah ada → update propertinya
}
try? modelContext.save()
}
Predicate Gagal Compile untuk Query Kompleks
swift
// ❌ TANPA pemahaman predicate lanjutan: runtime crash atau compile error
@Query(filter: #Predicate<Task> { task in
// Ini crash saat runtime karena SwiftData tidak bisa translate ke SQL
task.tags.contains { $0.name.hasPrefix("important") }
})
var importantTasks: [Task]
swift
// ✓ DENGAN subquery predicate yang benar
@Query(filter: #Predicate<Task> { task in
task.tags.contains { tag in
tag.name == "important" || tag.name == "urgent"
}
})
var importantTasks: [Task]
Migration Gagal karena Tidak Ada Schema Versioning
swift
// ❌ TANPA VersionedSchema: mengganti nama property langsung = crash
@Model
class User {
// Awalnya: var name: String
var fullName: String // Rename tanpa migration → data hilang atau crash!
}
swift
// ✓ DENGAN VersionedSchema + SchemaMigrationPlan: migration aman dan terdokumentasi
enum AppSchemaV1: VersionedSchema {
static var versionIdentifier = Schema.Version(1, 0, 0)
static var models: [any PersistentModel.Type] { [UserV1.self] }
@Model final class UserV1 {
var name: String
init(name: String) { self.name = name }
}
}
enum AppSchemaV2: VersionedSchema {
static var versionIdentifier = Schema.Version(2, 0, 0)
static var models: [any PersistentModel.Type] { [UserV2.self] }
@Model final class UserV2 {
var fullName: String
init(fullName: String) { self.fullName = fullName }
}
}