初探 iOS Core Data

前言

Core Data 是 Apple 官方推出的数据持久化框架。如果我们的应用程序需要缓存数据以便在我们的程序没有网络的时候也可以使用,我们就可以采用 Core Data 来存储我们需要的数据。

并且它可以通过 CloudKit,在单个 iCloud 账户中的多个设备自动同步缓存的数据。

通过 XCode 中的 Data Model 编辑器,我们可以自定义数据的类型和关系,并生成相应的类文件。Core Data 提供以下几项特性:

  • 数据持久化:Core Data抽象了将对象映射到磁盘的细节,使得保存数据变得容易,开发者无需直接管理数据库。
  • 支持单个或批量的撤销、重做操作:Core Data的撤销管理器可以跟踪更改,并可以单独回滚,分组回滚,或者一次全部回滚,这使得在应用程序中添加撤销和重做支持变得很容易。
  • 保持数据与视图同步:Core Data还通过为表和集合视图提供数据源来帮助保持视图和数据同步。
  • 支持版本控制和迁移。

创建 Core Data 的数据模型

我们可以在创建项目的时候,在 Storage 这一项勾选 Core Data。这样,XCode 会自动帮我们创建好一个以项目名命名的 Core Data 文件:

  • 勾选位置:
  • 以项目名命名的 Core Data 文件:

如果想在已存在的项目中添加 Core Data ,可以 command + N 新建文件,选择 iOS 平台,然后搜索框输入 data model 检索:

创建好 Core Data 文件,我们就可以使用 XCode 添加 Entity 了。选中创建的文件进入编辑界面,点击左下角的 Add Entity

双击创建好的 Entity 可以重命名,点击右侧的 Attributes 下面的➕添加字段:

准备工作完成,下面介绍一下它的基本使用。

基本使用

如果要使用 Core Data,我们需要以下几个类的协同合作来完成:

  • NSManagedObjectModel 的实例代表了你的应用的模型文件,它描述了你的应用的类型、属性和关系。
  • NSManagedObjectContext 的实例跟踪应用程序类型实例的变化。
  • NSPersistentStoreCoordinator 的实例保存并从 store 中获取应用类型的实例。
  • NSPersistentContainer 的实例一次设置了模型、上下文和存储协调器。

初始化 Core Data 示例代码如下:

swift 复制代码
lazy var persistentContainer: NSPersistentCloudKitContainer = {
        let container = NSPersistentCloudKitContainer(name: "FamilyMedicalRecords")
        // Load any persistent stores, which creates a store if none exists.
        container.loadPersistentStores { _, error in
            if let error {
                // Handle the error appropriately. However, it's useful to use
                // `fatalError(_:file:line:)` during development.
                fatalError("Failed to load persistent stores: \(error.localizedDescription)")
            }
        }
        return container
}()

func save() {
    let context = persistentContainer.viewContext
    if context.hasChanges {
        do {
            try context.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

下面就以 User(只包含一个 String 类型的 name 属性) 举例来看一下 Core Data 的增删改查操作。首先,我们先生成一下 NSManagedObject Subclass,选中 Core Data 文件 -> 选中 Entity ---> 选择 Editor -> 选择 Create NSManagedObject Subclass 即可 :

然后将 Entity 的 Codegen 改为 Manual/None

Insert 操作

添加数据的示例代码:

swift 复制代码
func insertUser(name: String) {
    do {
        let context = persistentContainer.viewContext
        let entity = NSEntityDescription.entity(forEntityName: userEntityName, in: context)
        
        let user = User(entity: entity!, insertInto: context)
        user.name = name
        save()
    } catch {
        fatalError("Failed to fetch Users: \(error)")
    }
}

首先我们需要获取当前 Core Data 的上下文:context。然后使用 NSEntityDescription 初始化 entity。接着创建 user,最后调用 save() 保存即可。

Delete 操作

删除操作的示例代码:

scss 复制代码
func deleteUsers(user: User) {
    let context = persistentContainer.viewContext
    context.delete(user)
    save()
}

直接调用 context 的 delete() 函数,然后调用 save() 函数即可。

Select 操作

获取全部用户的示例代码:

swift 复制代码
func fetchUsers() -> [User] {
    let context = persistentContainer.viewContext
    var users = [User]()
    do {
        users = try context.fetch(User.fetchRequest())
    } catch {
        fatalError("Failed to fetch users: \(error)")
    }
    return users
}

获取上下文,context 调用 fetch 函数即可。

Tips:fetchRequest() 是在进行 NSManagedObject Subclass 时系统自动生成的代码。

Update 操作

修改示例代码:

scss 复制代码
func updateUsers(user: User) {
    user.name = "hello, world"
    save()
}

修改 name 的值,然后调用 save() 函数即可。

相关推荐
502胶水2052 小时前
腾讯地图异步调用
开发语言·ios·swift
1024小神4 小时前
SwiftUI中List的liststyle样式及使用详解添加、移动、删除、自定义滑动
ios·swiftui·swift
勤劳兔码农7 小时前
iOS开发新手教程:Swift语言与Xcode工具链
ios·xcode·swift
依旧风轻16 小时前
Witness Table 的由来
ios·swift·witness table
依旧风轻17 小时前
Swift 中的方法调用机制
ios·swift·func·v-table·witness table
君陌笑2 天前
iOS-小说阅读器功能拆分之笔记划线
ios·swift
FreeCultureBoy3 天前
Swift 与 SwiftUI 学习系列:变量与常量篇 🚀
swiftui·xcode·swift
FreeCultureBoy3 天前
Swift 与 SwiftUI 学习系列: print 函数详解 🚀
swiftui·xcode·swift
依旧风轻3 天前
使用AES加密数据传输的iOS客户端实现方案
ios·swift·aes·network
依旧风轻3 天前
精确计算应用的冷启动耗时
ios·swift·cold start