本系列文章将讲述如何使用swift+coredata构建一个简易的记账软件,第一版本将要满足以下功能
- 自定义账本
- 账本名称自定义
- 账本汇率自定义
- 新建流水
- 流水金额自定义
- 流水时间自定义
- 流水分类自定义
- 流水注释自定义
- 显示账本列表
- 显示流水列表
作为本系列的第一篇文章,本文主要关注点在于
- storyboard的绘制
- coredata模型的建立
注:
- 作者目前是一名学生,很多代码可能并不是swift中的最佳实现,欢迎各位在评论区探讨
- 本文面向对象并不是从零开始的初学者,虽然作者在讲解的时候力争做到尽可能详细,还是希望阅读者可以有一定的XCode的基础和编程基础
推荐的视频教材:
斯坦福iOS公开课,去官网看最新版效果最佳
新建项目
使用coredata的iOS项目,为了避免后期配置的繁琐,在新建项目的时候就简易勾选使用coredata复选框,如下图所示
新建项目
界面规划
从最简单的意义上来讲,界面可以做成如下图所示,具体每个页面的实现我们放到后续的文章中去考虑
简单的界面实现(太丑了能看就行)
主要是四个viewcontroller
- MainViewController: 内置一个tableViewController作为流水列表,以及一个添加流水的按钮
- AddCostViewController: 添加一个流水
- AccountListViewController: 显示目前所有的账户
- AddAccountListViewController: 添加一个账户
其中Main和Accountlist两个控制器通过tab bar链接,后续文章将继续按照这个最基本的界面模型来进行搭建,技术为主,没有美工
CoreData详解
从iOS 10版本开始,苹果提供了一个新的类来处理和coredata有关的类,他就是NSPersistentContainer,根据官方文档:
NSPersistentContainer simplifies the creation and management of the Core Data stack by handling the creation of the managed object model (NSManagedObjectModel), persistent store coordinator (NSPersistentStoreCoordinator), and the managed object context (NSManagedObjectContext).
所以我们不必使用繁琐的流程来初始化coredata栈,在appdelegate.m中你们应该可以找到以下代码来声明persistentContainer和saveContext ()函数 (注释全部略去)
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "RapidTallyBook")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
以及在项目目录中应该可以找到以项目名称命名的xcdatamodeld文件
在CoreData中创建表
coredata中表的创建十分容易,点击xcdatamodeld文件,点击左下方的Add Entity按钮创建三个Entity,分别是
- Account: 账目
- Category: 类别
-
Cost: 流水
效果应该如图所示
值得注意的是,每当创建一个新的entity的时候,请选择这个entity,到左边的属性编辑器中,将codegen选项变为Manual/None,这是为了之后生成coredata class文件的时候避免出错
如图所示,Codegen属性已经设置为Manual/None
然后就可以对每一个entity添加attribute - Account
- currency:string
- name:string
- Category
- name:string
- isHidden: bool
- Cost
- amount:Double
- comment:string
-
createDate: Date
之后构建每个entity之间的关联
如图所示,在Cost下建立了两个外键
值得注意的是,所有的relationship默认都是To One的type,在建立这两个外键的反射关联的时候,请在左边的属性选项卡中把Type设置为ToMany
如果一切都没有问题的话,现在你的表格结构应该如下
- Account
- currency:string
- name:string
- costs :to many field to Cost
- Category
- name:string
- isHidden: bool
- costs: to many field to Cost
- Cost
- amount:Double
- comment:string
- createDate: Date
- account: to one field to Account
- category: to one field to category
选择顶部工具栏Editor - CreateNsmanagedObjectSubClass 选择三个entity,然后选择一个适当的地方存储这些文件,一共会产生六个文件,这时候请cmd+B build一下你的工程,如果没有问题,那么coredata的自动生成的文件就没问题,如果有error,请检查
-
是否将codegen设置为manual or None, 这是一个已知的swift的bug,设置为这个选项可以暂时解决这个问题,修改设置后请全部删除原来生成的六个文件再重新生成
六个文件应该类似于这样
注:不建议手动修改这六个文件的任何一个,任何修改都建议放在一个新的swift文件中extend原有的类
下篇文章展望:
这篇文章的难点在于coredata在自动生成类文件,会有或大或小很多坑,希望读者在遇到问题时可以在评论区与我探讨,swift对coredata的支持并没有像objc那么完善,遇到问题是十分正常的
下一篇文章将会着眼于与coredata的交互,包括
- 在表中新建数据
- 修改表中的数据
- 在表中查询
具体到业务逻辑上讲,在于
- 新建一个新的account
- 展示已有的account
本人尚才疏学浅,有任何问题和建议欢迎指教
水母程序员
2018.08.12
网友评论