Apple CoreData持久化框架
Apple CoreData持久化框架

Apple CoreData持久化框架

Core Data 是苹果提供的持久化框架,用于在 iOS、macOS、watchOS 和 tvOS 应用中管理数据模型。它允许应用程序的数据保存在磁盘上,并支持数据的创建、读取、更新和删除(CRUD)操作。

核心功能

1、数据持久化

将数据存储在本地 SQLite 数据库中,也可以存储为内存、XML 或二进制文件。

2、对象管理

将数据库的数据转换为 Swift/Objective-C 对象,支持对象关系模型(ORM)。

3、数据查询

使用 NSFetchRequest 来查询数据,可进行复杂的条件过滤、排序。

4、数据变更跟踪

监听数据变化,并自动更新 UI(例如在 UITableView 中)。

5、关系建模

可以建立一对一、一对多或多对多的关系,类似于关系型数据库。

关键组件

1、Managed Object Model (NSManagedObjectModel)

定义数据结构,包括实体、属性和关系。通常通过 .xcdatamodeld 文件进行创建和编辑。

2、Persistent Store Coordinator (NSPersistentStoreCoordinator)

负责连接数据模型和底层的持久化存储(例如 SQLite 文件)。

3、Managed Object Context (NSManagedObjectContext)

负责管理内存中的对象,跟踪数据的修改状态,并在需要时将更改保存到持久存储中。

4、Managed Object (NSManagedObject)

实体数据的具体实例,允许你像使用普通对象一样操作 Core Data 数据。

工作流程

1、创建 NSManagedObjectModel,定义实体和关系。

2、初始化 NSPersistentStoreCoordinator 并连接数据库。

3、通过 NSManagedObjectContext 进行数据的创建、读取、更新和删除。

4、在数据修改后,调用 save() 方法将更改保存到持久存储中。

Xcode创建Core Data文件

添加Core Data文件

1、打开 Xcode 项目,右击项目导航栏,选择“New File…”。

2、选择 Data Model,然后点击 Next。

创建的 .xcdatamodeld 文件内容。

点击“Add Entity”添加一个新的实体。

解析.xcdatamodeld 文件

创建实体后,可以看到3个重要的部分,分别是Attributes(属性)、Relationships(关系)和Fetched Properties(获取属性)。

1、Attributes(属性)

Attributes(属性)是与实体关联的数据字段,类似于数据库表的列。

属性定义了实体的数据内容,包括名称、数据类型和其他约束。

常见属性类型

String → 字符串

Integer 16/32/64 → 整数

Decimal → 十进制数

Double → 双精度浮点数

Float → 单精度浮点数

Boolean → 布尔值(true/false)

Date → 日期和时间

Binary Data → 二进制数据(如图片或文件)

配置属性

Attribute(名称):属性的名字,例如 title、createdAt。

Type(属性类型):定义属性的数据类型。

注意:属性名称必须以小写字母开头,名称只能包含字母、数字或下划线,不能有空格,否则会报:Name must begin with lower case letter类似的错误。

2、Relationships(关系)

定义

Relationships(关系) 连接两个实体,类似于数据库的外键。

关系可以描述一个实体与另一个实体之间的联系。

常见关系类型

1、One-to-One(1:1)

一个 User 只有一个 Profile。

2、One-to-Many(1:N)

一个 User关联多个 MobileNumber。

3、Many-to-Many(M:N)

一个 Student 可以选择多门 Course,每门 Course 也可以有多个 Student。

配置关系

Relationship(关系): 关系的名称,例如 tasks 或 category。

Destination(目标): 目标实体,表示关系连接的另一方。

Inverse(反向关系): 反向关系,建立双向关联。

3、Fetched Properties(获取属性)

Fetched Properties(获取属性) 是一种动态属性,类似于虚拟关系,通过查询(fetch request) 动态获取数据。

与 Relationships 不同,Fetched Properties 不会存储目标数据,只在需要时进行检索。

使用场景

如果想要获取与某个实体相关的对象,但又不希望建立直接关系时。

例如:在 Department 中获取某些符合条件的 Employee。

配置 Fetch Properties

Fetch Property(获取属性): 获取属性的名称。

Predicate(谓词): 筛选目标实体的条件。

添加.xcdatamodeld测试实体

创建一个名为Eurofxrefhist的实体,给属性添加三个字段。

生成Eurofxrefhist+CoreDataClass.swift 和Eurofxrefhist+CoreDataProperties.swift

在 .xcdatamodeld 文件中,选择 Eurofxrefhist实体 → Editor → Create NSManagedObject Subclass。

生成的两个文件会包含 Eurofxrefhist的 Core Data 属性和方法。

关于NSManagedObject Subclass的相关知识,可以进一步阅读《Core Data使用NSManagedObject Subclass管理数据》,这里不做过多的赘述。

SwiftUI配置Core Data

1、配置入口文件
import SwiftUI
import CoreData

@main
struct MyApp: App {
    // 创建 NSPersistentContainer
    let container: NSPersistentContainer

    init() {
        // 加载 xcdatamodeld 文件,确保名字匹配
        container = NSPersistentContainer(name: "YourProjectName")

        // 加载持久化存储
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, container.viewContext)
        }
    }
}

NSPersistentContainer(name:) → 通过 xcdatamodeld 文件名来加载数据模型。

container.loadPersistentStores → 加载存储并检查错误。

.environment(\.managedObjectContext, container.viewContext) → 将 viewContext 注入 SwiftUI 环境。

此处涉及NSPersistentContainer的知识,可以进一步阅读《Core Data管理数据模型的NSPersistentContainer》。

2、在 SwiftUI 视图中使用 viewContext
import SwiftUI
import CoreData

struct ContentView: View {
    // 通过 @Environment 读取 viewContext
    @Environment(\.managedObjectContext) private var viewContext

    // 使用 @FetchRequest 获取数据
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Task.title, ascending: true)],
        animation: .default)
    private var tasks: FetchedResults<Task>

    var body: some View {
        NavigationView {
            List {
                ForEach(tasks) { task in
                    Text(task.title ?? "No Title")
                }
                .onDelete(perform: deleteItems)
            }
            .navigationTitle("Tasks")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: addItem) {
                        Label("Add Task", systemImage: "plus")
                    }
                }
            }
        }
    }

    // 添加新任务
    private func addItem() {
        let newTask = Task(context: viewContext)
        newTask.title = "New Task"
        newTask.createdAt = Date()

        saveContext()
    }

    // 删除任务
    private func deleteItems(offsets: IndexSet) {
        offsets.map { tasks[$0] }.forEach(viewContext.delete)
        saveContext()
    }

    // 保存数据
    private func saveContext() {
        do {
            try viewContext.save()
        } catch {
            let nsError = error as NSError
            print("Unresolved error \(nsError), \(nsError.userInfo)")
        }
    }
}

@Environment(\.managedObjectContext) → 从 SwiftUI 环境中读取 viewContext。

@FetchRequest → 直接在 SwiftUI 中通过 FetchRequest 读取数据。

addItem() → 创建新任务并保存到 Core Data。

deleteItems() → 删除数据并保存。

运行项目,测试 Core Data

1、添加任务:点击 + 按钮添加任务。

2、删除任务:左滑删除任务。

3、数据持久化:关闭并重新打开应用,数据会被保留。

此处涉及@FetchRequest的知识,请进一步阅读《SwiftUI获取Core Data数据的@FetchRequest

可选优化

添加 NSFetchedResultsController 来优化数据更新。

处理 Core Data 数据迁移,防止模型变化时崩溃。

实现多线程 Core Data 操作,提升性能。

相关文章

1、Core Data:https://developer.apple.com/documentation/coredata

2、SwiftData数据持久化框架:https://fangjunyu.com/2024/11/06/swiftdata%e6%95%b0%e6%8d%ae%e6%8c%81%e4%b9%85%e5%8c%96%e6%a1%86%e6%9e%b6/

3、Core Data使用NSManagedObject Subclass管理数据:https://fangjunyu.com/2025/03/27/core-data%e4%bd%bf%e7%94%a8nsmanagedobject-subclass%e7%ae%a1%e7%90%86%e6%95%b0%e6%8d%ae/

4、Core Data管理数据模型的NSPersistentContainer:https://fangjunyu.com/2025/03/29/core-data%e7%ae%a1%e7%90%86%e6%95%b0%e6%8d%ae%e6%a8%a1%e5%9e%8b%e7%9a%84nspersistentcontainer/

5、SwiftUI获取Core Data数据的@FetchRequest:https://fangjunyu.com/2025/03/30/swiftui%e8%8e%b7%e5%8f%96core-data%e6%95%b0%e6%8d%ae%e7%9a%84fetchrequest/

6、Core Data预览报错问题:https://fangjunyu.com/2025/03/30/core-data%e9%a2%84%e8%a7%88%e6%8a%a5%e9%94%99%e9%97%ae%e9%a2%98/

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注