CoreData作为Apple的儿子,在App需要存储结构化数据的过程中,仍然扮演着重要的角色。CoreData已经存在了十多年,并且得到了积极的维护。看海外主流招聘网站如Monster、Indeed等iOS职位,基本上都是大写的写着能熟练使用CoreData。然而,这样一个成熟且经过验证的代码库在中国使用得并不多。FMDB、Realm等应用广泛。我经常在面试的时候问iOSer是否了解数据库,答案是肯定的。再问,很多人只用FMDB,对CoreData了解不多。想了想,可能是因为CoreData的入门成本有点高,相关的中文资料比较少。为了写这个系列,我还特地买了objc.io的CoreData这本书。读后受益匪浅。这个系列我还没有想好要写多少篇,大概是从基础到高级的过渡吧。第一篇通过通讯录读取数据库。第二个将存储更多类型的数据。最终实现结果:CoreDataDemo.gif1。核心数据架构一个基本的核心数据栈由四个主要部分组成:托管对象(NSManagedObject)、托管对象上下文(NSManagedObjectContext)、持久存储协调器(NSPersistentStoreCoordinator)和持久存储(NSPersistentStore)。NSManagedObject是我们的数据模型,也就是我们存储的对象。这些对象存储在NSManagedObjectContext中,每个存储对象都知道它对应于哪个上下文。NSManagedObjectContext:这是我们每天都要打交道的。其他三个只有在迁移数据时才会看到。NSPersistenStoreCoordinator:是模型和store数据库之间的桥梁,负责两者之间最复杂的细节隐藏。我想多说一下Context,因为我每天都和它打交道。它实际上是内存中的一块区域,所有对对象的操作都需要一个上下文。保存之前是在内存中,不会对数据库中的内容产生任何影响。每个托管对象对应一个Context,一个对象只会和特定的Context打交道。直到生命周期结束。2.CoreData的基本读操作2.1获取CoreData存储数据的五步获取总代理和管理对象管理器从Entity获取一个fetchRequest根据fetchRequest,从managedContext中查询数据保存。保存过程中可能出现错误,需要处理。添加到数组2.2基本存储获取总代理和管理对象管理器创建实体保存内容保存实体到管理对象。保存失败,处理,保存到数组中,更新UI3.更新通讯录列表页面Demo需求:完成一个通讯录列表页面。要求:从本地数据库中读取姓名列表。单击添加以添加名称。添加的名称可以保存到本地数据库。好了,下面一步步实现这个需求。为了突出重点,让我们从最简单的开始,使用带有数据库的默认项目。3.1Xcode创建一个带有数据库的默认项目。Xcode在创建项目时,提供了创建CoreData的模板。我们只需要在创建项目时勾选CoreData选项,Xcode就会自动创建一个数据模型文件。这个Demo就是以此制作的,纯粹是为了简单明了,开门见山。不然一开始还要分享很多其他的内容,看的人会觉得累。但是实际开发中不推荐使用这种方式。通常,我们会删除生成的模板代码。3.2创建本地数据库模板勾选后会看到一个后缀为“xcdatamodeld”的文件,这就是我们的数据库模板。当然现在里面不能存数据,需要设置字段名。第一步是添加一个Entity,相当于数据库中的一张表。第二步是命名新创建的实体。第三步是设计Entity中的属性。我们在这个demo的需求中只需要一个name,所以我们只设置了一个属性name,类型为String。其他更多的属性类型,我们会在下一篇分享。3.3查询本地数据咦?你一开始不是说一个基本的CoreData栈由四个主要部分组成吗?为什么没看到?得了吧,这就是我们一开始用Xcode创建一个带数据库的默认项目的原因。使用这个选项会自动在AppDelegate中生成相应的代码。确实简化了我们第一次学习的成本,但是就像没有人会把所有的代码都写在Controller里面一样,他们也不会把这些东西写在APPDelegate里面。overridefuncviewDidAppear(_animated:Bool){super.viewDidAppear(animated)//第一步:获取总代理和管理对象管理器letappDelegate=UIApplication.shared.delegateas!AppDelegateletmanagedObectContext=appDelegate.persistentContainer.viewContext//第二步:创建一个获取请求letfetchRequest=NSFetchRequest(entityName:"Person")//第三步:执行请求do{letfetchedResults=trymanagedObectContext.fetch(fetchRequest)as?[NSManagedObject]ifletresults=fetchedResults{people=resultstableView.reloadData()}}catch{fatalError("retrievalfailed")}}3.4插入并保存数据到本地数据库privatefuncsaveName(text:String){//第一步:获取通用代理和托管对象管理器让appDelegate=UIApplication.shared.delegateas!AppDelegate让managedObectContext=appDelegate.persistentContainer.viewContext//Step2:创建实体letentity=NSEntityDescription.entity(forEntityName:"Person",in:managedObectContext)letperson=NSManagedObject(entity:entity!,insertInto:managedObjectContext)//Step3:保存将文本框中的值传递给personperson.setValue(text,forKey:"name")//Step4:将entity保存到managedobject中。如果保存失败,则进行处理。do{trymanagedObectContext.save()}catch{fatalError("Unabletosave")}//第5步:保存到数组并更新UIpeople.append(person)}所有源代码都在这里:https://github.com/Stanbai/CoreDataDemo.gitSwift的CoreData系列之一:基础存储作者:非典型技术宅链接:http://www.jianshu.com/p/3e793fca6a13来源:简书版权归作者所有。商业转载请联系作者授权,非商业转载请注明出处。
