如何将Core Data添加到现有的实用程序应用程序

9
我创建了一个实用程序应用,几乎已经完成,但现在我必须要持久化数据。由于XCode仅提供导航或基于窗口的应用程序中的核心数据模板,是否有一种简单的方法将核心数据添加到我的应用程序中?我之前从未使用过核心数据,只需要将460个字符的消息和联系人名称作为发送消息的历史记录进行持久化。还是我应该从头开始创建一个包括核心数据的基于窗口的新应用程序,并手动构建实用程序/翻转部分?有人能为我的情况提供最佳实践建议吗?
3个回答

18

由于我也在努力理解核心数据的twighlightzone,我通过比较一个空应用程序项目和一个带有核心数据的空应用程序项目,找出了将“普通”项目迁移到核心数据的以下步骤:

第一步:添加CoreData.framework

a) 在“项目目标摘要”下的“链接框架和库”中使用+按钮添加CoreData.framework
b) 选择文件/新建/文件,在“Core Data”部分添加一个新的“数据模型”(并将其命名为XXXXXXX(有关命名,请参见3.b)
c) 在文件APPLIKATION-Prefix.pch(其中APPLICATION是您的项目名称)中添加

   #import <CoreData/CoreData.h>

在另外两个include指令下面:

步骤2: 在AppDelegate.h中添加以下属性/方法声明:

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

步骤三:AppDelegate.m

a) 合成属性:

@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;

b) 在模块的末尾添加以下行:

重要提示:在 Methode 中,您需要将 managedObjectModelpersistentStoreCoordinator 中的 XXXXXXX 替换为您个人的 .xcdatamodeld 文件的名称。

- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil)
    {
        if ([managedObjectContext hasChanges] & ![managedObjectContext save:&error])
        {
            /*
             Replace this implementation 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();
        } 
    }
}

#pragma mark - Core Data stack

/**
 Returns the managed object context for the application.
 If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
 */
- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] init];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}

/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created from the application's model.
 */
- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil)
    {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"XXXXXXX" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return __managedObjectModel;
}

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"XXXXXXX.sqlite"];

    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
    {
        /*
         Replace this implementation 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. 

         Typical reasons for an error here include:
         * The persistent store is not accessible;
         * The schema for the persistent store is incompatible with current managed object model.
         Check the error message to determine what the actual problem was.


         If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.

         If you encounter schema incompatibility errors during development, you can reduce their frequency by:
         * Simply deleting the existing store:
         [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]

         * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
         [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

         Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.

         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return __persistentStoreCoordinator;
}

#pragma mark - Application's Documents directory

/**
 Returns the URL to the application's Documents directory.
 */
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

那么如何管理上下文以便了解模型?自动化的吗? - fengd
@Jun1st:将sqlite和momd文件的名称与xcdatamodel相同是此示例将上下文链接到模型的方法。 - ColdLogic

8
你需要将CoreData框架添加到你的目标中,创建数据模型,并实例化NSManagedObjectModelNSPersistentStoreCoordinatorNSManagedObjectContext对象。
在现有应用程序中添加Core Data在这篇苹果文档中简要讨论了(搜索“existing application”)。
你还应该查看苹果的教程,以了解所涉及的内容。
你也可以考虑只使用SQLite。

2
我同意使用SQLite的想法。Core Data相当重型,而且因为似乎没有大量数据或复杂的关系被保存在这里,所以使用SQLite可能是更简单、更高效的方法。 - Marc W
3
一旦理解了 Core Data 的工作原理,它就变得更加容易了——特别是对于小项目而言。 - Kendall Helmstetter Gelner
4
我建议不要直接编写针对 SQLite 的代码。所有我见过的此类代码都是重新实现 Core Data 的部分功能,而且存在漏洞并且表现得更糟糕。Core Data 是更好的选择,特别是当 Cocoa Touch 在未来添加绑定时。 - PeyloW
1
我赞同PeyloW关于编写自己的代码的说法。如果你选择SQLite,请阅读这篇文章:https://dev59.com/_EfRa4cB1Zd3GeqP-p5l - nall
我需要手动创建SQLite数据库并添加它,还是Core Data会自动创建它? - hover
CoreData现在也与iCloud无缝集成。 - cleverbit

5
在XCode中使用提供的模板创建新项目 - 找到一个带有核心数据存储选项的模板。
这会给你一个xcdatamodel文件以及一些代码/类变量,在应用程序代理中,你可以从该项目中复制到你现在的项目中。
我也强烈推荐nall提到的苹果教程。
如果你决定直接使用SQLLite,强烈考虑使用FMDB,它简化了SQL代码。它是一个你添加到项目中的文件。

如果你要使用SQLite,我强烈推荐FMDB。 - Shawn Craver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接