坦率地说,您没有在项目创建时选中Use CoreData 框,这是正确的想法。我觉得这只是用一堆更容易(也更有洞察力)手动完成的东西使项目膨胀。
简而言之,无论您在项目创建时选择什么选项,都可以相同地实现 CoreData。
当我想(手动/以编程方式)向项目添加 CoreData 支持时,我通常会执行以下步骤:
定义数据模型
这些只是NSManagedObjects,代表您的应用程序的数据结构。比如User、Message、BlogPost等。我也为我的用户设置做了一个。
例子:
import CoreData
class User : NSManagedObject
{
// @NSManaged is the replacement for @dynamic when using CoreData in Swift
@NSManaged var identifier : String
@NSManaged var firstName : String?
@NSManaged var lastName : String?
// This is called when a new User object is inserted to CoreData
override func awakeFromInsert()
{
super.awakeFromInsert()
self.identifier = NSUUID().UUIDString // generate a random unique ID
}
}
添加核心数据模型
这是您通过以下方式添加到项目中的另一个文件:File -> New-> iOS-> CoreData -> Data Model。我通常将相同的xcmodeldata 文件存储在我的Models 项目文件夹中(连同我的实际模型类)。
选择这个新文件后,您将看到 CoreData 模型编辑器。您将希望看到右侧检查器窗格可见(热键是⌥⌘1)。对于核心数据编辑器,您还将主要使用第三个选项卡(数据模型检查器),该选项卡可通过 ⌥⌘3 进行切换。
现在您可以向这个数据模型添加一个实体对象(通过底部的Add Entity)。假设上面的例子,添加一个User 实体。选中User 实体后,添加上述类中定义的三个属性:identifier、firstName 和lastName。它们应该匹配类定义,使用String 类型。
下一步是告诉CoreData 这里定义的User 实体映射到我们实际的类文件。选中 User 并打开数据模型检查器窗格,将 Name 设置为 User 并将 Class 设置为 YourAppName.User。
这是 Swift 和 CoreData 的“陷阱”,您的类以模块名称为前缀,以便为它们命名(避免名称冲突)。好的部分是您不再需要为您的对象添加“XYZ”类前缀。
初始化核心数据栈
定义好数据模型后,您需要初始化 CoreData 堆栈本身(数据库存储和上下文)。最基本的例子是你的NSManagedObjectContext 的全局单例,它会在需要时延迟加载。
你可以把它放在它自己的 Swift 文件中 (CoreDataStack.swift):
import CoreData
let managedObjectContext : NSManagedObjectContext =
{
// This is your xcdatamodeld file
let modelURL = NSBundle.mainBundle().URLForResource("MyApp", withExtension: "momd")
let dataModel = NSManagedObjectModel(contentsOfURL: modelURL!)
// This is where you are storing your SQLite database file
let documentsDirectory : NSURL! = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last as? NSURL
let storeURL = documentsDirectory.URLByAppendingPathComponent("MyApp.sqlite")
let psc = NSPersistentStoreCoordinator(managedObjectModel: dataModel!)
var error : NSError?
let store = psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error)
if let error = error
{
println("Uhoh, something happened! \(error), \(error.userInfo)")
}
let context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
context.persistentStoreCoordinator = psc
context.undoManager = nil
return context
}()
使用核心数据
现在您已经有了一个工作的 Core Data 堆栈,定义和映射了一些数据模型……接下来呢?
让我们获取一些对象!
func getUsersByFirstName(firstName: String) -> [User]
{
let fetchRequest = NSFetchRequest(entityName: "User")
// The [c] part indicates case-insensitive, "Bob" == "bob"
fetchRequest.predicate = NSPredicate(format: "firstName ==[c] %@", firstName)
var error : NSError?
let results = context.executeFetchRequest(fetchRequest, error: &error) as [User]
// Handle errors here
return results
}
哦,对了,我们没什么可取的。您还可以插入对象...
func insertNewUser() -> User
{
return NSEntityDescription.insertNewObjectForEntityForName("User", inManagedObjectContext: context) as User
}
当然你也可以删除对象...
func deleteUser(user: User)
{
context.deleteObject(user)
}
关键是要记住 CoreData 上下文 (NSManagedObjectContext) 会跟踪内存中的变化。虽然您可以在上下文中执行这些 CRUD 操作并立即查看更改(在同一上下文中),但在您保存更改之前它们不会保留在数据库中:
func saveContext() -> Bool
{
var error : NSError?
if context.hasChanges && !context.save(&error)
{
println("Something happened when saving! \(error!), \(error!.userInfo)")
return false
}
return true
}
您还可以使用 context.rollback() 回滚上次保存的更改。
随意探索 CoreData 并尝试更高级的功能,例如谓词 (NSPredicate)、排序描述符 (NSSortDescriptor) 和设置对象关系。