当前位置: > > > Swift - 使用Core Data进行数据持久化存储

Swift - 使用Core Data进行数据持久化存储

(本文代码已升级至Swfit3)

一,Core Data介绍
1,Core Data是iOS5之后才出现的一个数据持久化存储框架,它提供了对象-关系映射(ORM)的功能,即能够将对象转化成数据,也能够将保存在数据库中的数据还原成对象。
2,虽然其底层也是由类似于SQL的技术来实现,但我们不需要编写任何SQL语句,有点像Java开发中的Hibernate持久化框架
3,Core Data数据最终的存储类型可以是:SQLite数据库,XML,二进制,内存里,或自定义数据类型。
4,与SQLite区别:只能取出整个实体记录,然后分解,之后才能得到实体的某个属性。 

二,Core Data的使用准备 - 数据模型和实体类的创建
1,创建项目的时候,勾选“Use Core Data”。完毕后在 AppDelegate 中,会生成相关代码。


2,打开项目中的 xcdatamodeld 文件,在右边的数据模型编辑器的底部工具栏点击 Add Entity 添加实体。
同时在属性栏中对实体命名进行修改,并在 Attribute 栏目中添加 idusernamepassword 三个属性。


3,点击下方的 Editor Style 按钮可以查看实体的关系图。

4,自 iOS10swift3 之后,访问 CoreData 的方法简洁了许多,我们不再需要手动新建对应于 entityclass

三,Core Data的使用
1,首先在代码中引入CoreData库
import CoreData

2,插入(保存)数据操作
//获取管理的数据上下文 对象
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext

//创建User对象
let user = NSEntityDescription.insertNewObject(forEntityName: "User",
                                               into: context) as! User

//对象赋值
user.id = 1
user.username = "hangge"
user.password = "1234"

//保存
do {
    try context.save()
    print("保存成功!")
} catch {
    fatalError("不能保存:\(error)")
}

3,查询数据操作
//获取管理的数据上下文 对象
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext

//声明数据的请求
let fetchRequest = NSFetchRequest<User>(entityName:"User")
fetchRequest.fetchLimit = 10 //限定查询结果的数量
fetchRequest.fetchOffset = 0 //查询的偏移量

//设置查询条件
let predicate = NSPredicate(format: "id= '1' ", "")
fetchRequest.predicate = predicate

//查询操作
do {
    let fetchedObjects = try context.fetch(fetchRequest)
    
    //遍历查询的结果
    for info in fetchedObjects{
        print("id=\(info.id)")
        print("username=\(info.username)")
        print("password=\(info.password)")
    }
}
catch {
    fatalError("不能保存:\(error)")
}

4,修改数据操作
即将查询出来的对象进行重新赋值,然后再使用context.save方法重新保存即可  
//遍历查询的结果
for info in fetchedObjects{
    //修改密码
    info.password = "abcd"
    //重新保存
    try context.save()
}

5,删除数据操作
删除操作使用context.delete方法,删除某个对象。然后使用context.save方法保存更新到数据库  
//遍历查询的结果
for info in fetchedObjects{
    //删除对象
    context.delete(info)
}

//重新保存-更新到数据库
try! context.save()

四,数据的存放位置 
默认Core Data生成的是sqlite文件,保存在Documents文件夹下

评论12
  • 12楼
    2017-11-10 16:51
    xiaosi

    你好航哥 在使用coredate时,插入保存没问题,但是无法查询, 断点显示fetchedObjects为0,请问如何解决

    站长回复

    不应该呀。你如果运行我文章里的代码可以查询到吗(当然事先也要先插入数据)?

  • 11楼
    2017-03-21 00:17
    KyleBing

    现在不需要再生成一下了吧?我是Command+B Build 一下 之后就可以直接用Entity了

    站长回复

    确实是这样的,多谢你的提醒,文章现已更新。

  • 10楼
    2017-02-09 14:16
    韩航宇

    楼主你没有swift 3.0用到的各种控件的封装

    站长回复

    有的话我都会在网站上发布出来的,你可查阅下以前文章,或者关注我后续的文章。

  • 9楼
    2016-12-01 17:04
    dim

    O(∩_∩)O谢谢楼主

    站长回复

    不客气。欢迎常来看看。

  • 8楼
    2016-11-02 09:00
    swift菜鸟

    站长,有swift3.0的用法吗?或者相关推荐的文章也可以!

    站长回复

    我把文章代码更新成Swift3的了,你可以再看下。

  • 7楼
    2016-07-22 11:09
    aaaa

    请问为什么获取不到APPdelegate的上下文方法

    站长回复

    我又测试了下是没问题的。你确定创建项目的时候,勾选“Use Core Data”了吗(文章第一步)。

  • 6楼
    2016-06-23 15:49
    xiaobai

    请问数据的存放的位置 ,为什么我的mac 里面怎么找不到文件的位置啊,

    站长回复

    这个保存在对应App下的Documents目录下,类似于:/Users/hangge/Library/Developer/CoreSimulator/Devices/ABE5BD0C-755A-48DA-894E-D19D484BB62E/data/Containers/Data/Application/863959D5-D492-49CB-A1C6-FDD4BDEE955D/Documents

    。你再看看,是不是找错文件夹了。

  • 5楼
    2016-05-19 11:22
    SungJoe

    请问对每个实体生成的子类文件需要在里面添加代码吗?如果想要单独在实体中插入数据,让这些数据不可编辑,应该怎么做?

    站长回复

    子类的话还是一样的,xcdatamodeld 文件中添加一个子实体,并设置父子关系。代码中再生成个子类实体类即可。

    只能插入不能编辑,这个实现不了吧(可能我还不知道方法)

  • 4楼
    2016-04-22 10:18
    starter

    ViewController.swift:203:27: Use of unresolved identifier 'fetchedObjects'

    楼主,我照你的代码写的,但是报这个错怎么解决

    站长回复

    报的是fetchedObjects没定义,你检查下前面有定义了fetchedObjects吗

  • 3楼
    2016-03-19 12:55
    wuyizi

    の,讲的有点不是很细致.那个代码往哪里写啊

    站长回复

    哪个类中需要使用Core Data,代码就往哪里写

  • 2楼
    2016-01-18 15:21
    yy

    在写插入的时候 if !context.save(&error)编译器提示不能用&符号,但是删除了又报错,不知道怎么回事

    站长回复

    因为这个写的比较早,到了Swift2.0语法有改变。现已修正,你再看下。

  • 1楼
    2015-07-24 01:04
    Izumi

    要把.xcdatamodeld的class设置成User才能跑,作者辛苦了

    站长回复

    不客气。