我正在尝试使用CoreData
,但我已经完成了项目的设置,忘了勾选方框来使用它。
在设置过程中未检查CoreData
框时,是否有办法实现核心数据的使用?
如果我开始一个新项目将需要传输大量信息,这将是非常耗时的,所以我想留在同一个项目而不是创建一个新项目。
答案 0 :(得分:5)
坦率地说,你没有检查项目创建的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
}
}
这是您通过以下方式添加到项目中的另一个文件:文件 - >新建 - > iOS-> CoreData - >数据模型。我通常将这个xcmodeldata
文件存储在我的Models
项目文件夹中(以及我的实际模型类)。
选择此新文件后,您将看到CoreData模型编辑器。您将希望看到右侧检查器窗格可见(热键是⌥⌘1)。对于核心数据编辑器,您还将主要使用可与⌥⌘3一起切换的第三个选项卡(数据模型检查器)。
现在,您可以将实体对象添加到此数据模型中(通过底部的添加实体)。假设上面的示例,添加一个User
实体。选中User
实体后,添加上述类中定义的三个属性:identifier
,firstName
和lastName
。它们应该使用String
类型匹配类定义。
下一步是告诉CoreData这里定义的这个User
实体映射到我们的实际类文件。选中User
并打开数据模型检查器窗格后,将名称设置为User
,将类设置为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
}()
现在您已经拥有了一个可用的核心数据堆栈,一些数据模型被定义并映射......下一步是什么?
让我们取一些东西!
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
)和设置对象关系。
答案 1 :(得分:2)
基本上,Core Data的所有复选框都是将核心数据框架(CoreData.framework)添加到您的项目中,并使用核心数据堆栈设置AppDelegate.m,添加数据文件并可能为您提供示例视图控制器(取决于您开始的项目类型)。
如果您希望设置现有项目,就像模板设置一样,那么最快捷的方法是创建一个新项目作为示例并选择Core Data复选框。打开新项目并查看AppDelegate.m文件并获取用于初始化核心数据堆栈的代码。它大约有80行,并有一条评论呼叫核心数据栈。
将其转移到现有项目并将其放入AppDelegate文件中。同样在您现有的项目中,添加CoreData.framework,然后在Core Data下添加一个新文件(File-> New File-> CoreData),称为" Data Model"文件。此文件用于定义数据模式的等效项。您选择它以使用图形控件。
然后使用您的示例项目通过查看示例ViewController来查看如何访问核心数据堆栈。
注意:有些人不喜欢Apple如何在AppDelegate.m中设置核心数据堆栈,如果你搜索它,你会发现很多关于它的评论以及如何做得更好(我觉得被迫做出免责声明)。 GitHub上还有一些第三方库也可以在这方面为您提供帮助。 (MagicalRecord,SLCoreDataStack等)。
希望有所帮助! 好吧!