1.建立CoreData项目
创建项目时勾选 User Core Data
2.创建实体(Entity)
创建项目后,可以看到目录中有一个.xcdatamodeld文件。打开它,点击下方Add Entity按钮即可创建新的实体。这里,我创建了Student尸体,两个属性分别是创建时间data和名字name。完成后点击右侧Show the Data Model Inspector按钮,里面有Name和Class两个选项,分别是实体名称和要生成的类名。
完成后,选择菜单Editor–>Create NSManagedObject Subclass…即可完成创建StudentManagedObject实体。
代码如下:
import Foundation
import CoreData
@objc(StudentManagedObject)class StudentManagedObject: NSManagedObject {
@NSManaged var date: NSDate
@NSManaged var name: String
}
3.创建模型
既然有了实体,为什么还要创建模型呢?这是基于分层设计考虑的,上面一步生产的实体是NSManagedObject的子类,从层级考虑是属于持久层。持久层和业务层,展示层分离,在项目逻辑比较复杂的时候会体现出很大的优势。因此,我这里再创建一个继承NSObject的StudentModel模型,属性和StudentManagedObject完全一致。
代码如下:
import UIKit
class StudentModel: NSObject {
var name: String?
var date: NSDate?
}
4.创建BaseDao基类
CoreData项目创建的时候,在AppDelegate中会自动生成四个参数:
applicationDocumentsDirectory 这个参数是数据库文件的路径
managedObjectModel 数据库所有实体或数据结构,包含各实体的定义信息
persistentStoreCoordinator 相当于数据库的连接
managedObjectContext 被管理对象上下文,可以在上下文中实现查找,删除,插入等操作,最后需要同步
虽然看上去很复杂,用到的主要还是最后一个managedObjectContext。
默认这几个参数是在AppDelegeta中,为了构建一个统一的数据库访问接口,我们需要创建一个BaseDao类,所有然后把四个参数拷贝过去,所有数据库访问Dao都继承这个基类,这样就可以方便调用。代码如下:
//
// BaseDao.swift
// CoreDataDemo
//
// Copyright (c) 2015年 worthy.zhang. All rights reserved.
//
import UIKit
import CoreData
class BaseDao: NSObject {
// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.worthy.CoreDataDemo" in the application‘s documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1] as! NSURL
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("CoreDataDemo", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("CoreDataDemo.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application‘s saved data."
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil, error: &error) == nil {
coordinator = nil
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application‘s saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() 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.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext()
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
}
5.创建数据访问对象StudentDao
在StudentDao实现对Student的增删查改等操作,具体方法代码如下,需要注意模型StudentModel与实体StudentManagedObject之间的转换。
查询:
func findAll()-> NSMutableArray {
println(self.applicationDocumentsDirectory.description)
let cxt = self.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("Student", inManagedObjectContext:cxt!
)
let request = NSFetchRequest()
request.entity = entityDescription
var error: NSError? = nil
var listData:[AnyObject]? = cxt?.executeFetchRequest(request, error: &error)
var resListData: NSMutableArray = NSMutableArray()
for data in listData as! [StudentManagedObject] {
var entity = data
var model = StudentModel()
model.name = entity.name
model.date = entity.date
resListData.addObject(model)
}
return resListData
}
新增:
func insert(student: StudentModel){
let cxt = self.managedObjectContext
let entity = NSEntityDescription.insertNewObjectForEntityForName("Student", inManagedObjectContext: cxt!) as! StudentManagedObject
entity.name = student.name!
entity.date = NSDate()
var error: NSError? = nil
if (self.managedObjectContext?.save(&error) != nil) {
println("插入成功")
}else{
println("插入失败")
}
}
删除:
func remove(student:StudentModel){
let ctx = self.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("Student", inManagedObjectContext: ctx!)
let request = NSFetchRequest()
request.entity = entityDescription
request.predicate = NSPredicate(format: "date == %@", student.date!)
var error: NSError? = nil
let listData:[AnyObject]? = ctx?.executeFetchRequest(request, error: &error)
for data in listData as! [StudentManagedObject] {
ctx?.deleteObject(data)
var savingError: NSError? = nil
if ctx?.save(&savingError) != nil {
println("删除成功")
}else{
println("删除失败")
}
}
}
修改:
func modify(student:StudentModel){
let ctx = self.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("Student", inManagedObjectContext: ctx!)
let request = NSFetchRequest()
request.entity = entityDescription
request.predicate = NSPredicate(format: "date == %@", student.date!)
var error: NSError? = nil
let listData:[AnyObject]? = ctx?.executeFetchRequest(request, error: &error)
for data in listData as! [StudentManagedObject] {
data.name = student.name!
var savingError: NSError? = nil
if ctx?.save(&savingError) != nil {
println("修改成功")
}else{
println("修改失败")
}
}
}
最后,通过调用sharedDao返回唯一实例。
private let sharedInstance = StudentDao()
class StudentDao: BaseDao {
class var sharedDao : StudentDao {
return sharedInstance
}
......
}
6.Demo演示
Demo中通过调用StudentDao中的四个方法,演示了简单的增删查改操作。
Demo地址:https://github.com/WorthyZhang/CoreDataDemo