SwiftData
问题
SwiftData 是什么?与 Core Data 有什么区别?
答案
SwiftData = Core Data 的现代化
SwiftData 是 iOS 17+ 推出的纯 Swift 数据持久化框架,底层仍基于 Core Data,但 API 完全重新设计:
| Core Data | SwiftData | |
|---|---|---|
| 模型定义 | .xcdatamodeld 文件 | Swift 代码 + @Model |
| 上下文 | NSManagedObjectContext | ModelContext |
| 查询 | NSFetchRequest + NSPredicate | @Query + #Predicate |
| SwiftUI | @FetchRequest | @Query |
| 最低版本 | iOS 3 | iOS 17 |
定义模型
import SwiftData
@Model
class User {
var name: String
var age: Int
var createdAt: Date
@Relationship(deleteRule: .cascade)
var posts: [Post]
init(name: String, age: Int) {
self.name = name
self.age = age
self.createdAt = Date()
self.posts = []
}
}
@Model
class Post {
var title: String
var user: User?
init(title: String) {
self.title = title
}
}
SwiftUI 集成
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(for: [User.self, Post.self])
}
}
struct UserListView: View {
@Query(sort: \User.name) private var users: [User]
@Environment(\.modelContext) private var context
var body: some View {
List(users) { user in
Text(user.name)
}
}
func addUser() {
let user = User(name: "Alice", age: 25)
context.insert(user)
// 自动保存,无需手动 save
}
}
#Predicate
// 类型安全的查询条件(替代 NSPredicate 字符串)
let minAge = 18
let predicate = #Predicate<User> { user in
user.age >= minAge && user.name.contains("A")
}
@Query(filter: #Predicate<User> { $0.age > 18 }, sort: \User.name)
private var adults: [User]
常见面试问题
Q1: SwiftData 可以和 Core Data 共存吗?
答案:可以。SwiftData 底层就是 Core Data,可以共享同一个 SQLite 文件。但需要确保模型定义一致。Apple 提供了迁移路径。
Q2: SwiftData 适合现在使用吗?
答案:iOS 17+ 的新项目推荐使用 SwiftData(API 更简洁、类型安全)。但如果需要支持更低版本或有复杂的 Core Data 历史数据,暂时使用 Core Data 更稳妥。