首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >向现有iPhone项目添加核心数据

向现有iPhone项目添加核心数据
EN

Stack Overflow用户
提问于 2010-01-09 16:30:18
回答 12查看 86.3K关注 0票数 140

我想将核心数据添加到现有的iPhone项目中,但我仍然收到许多编译错误:

代码语言:javascript
复制
- NSManagedObjectContext undeclared

 - Expected specifier-qualifier-list before 'NSManagedObjectModel'

 - ...

我已经将核心数据框架添加到了目标中(右键单击"Targets","Add“- "Existing Frameworks",”CoreData.framework“下面的项目)。

我的头文件:

代码语言:javascript
复制
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;       
NSPersistentStoreCoordinator *persistentStoreCoordinator;

[...]

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

我遗漏了什么?启动一个新项目不是一个选项...

非常感谢!

编辑对不起,我确实有这些实现...但是图书馆好像不见了..。实现方法充满了编译错误,比如"managedObjectContext undeclared","NSPersistentStoreCoordinator undeclared",但在NSManagedObjectContext之前也有"Expected ')‘“(尽管看起来括号是正确的)……

代码语言:javascript
复制
#pragma mark -
#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 by merging all of the models found in    
 application bundle.
 */
- (NSManagedObjectModel *)managedObjectModel {

    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    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 = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] 
        stringByAppendingPathComponent: @"Core_Data.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. If it is not possible to recover from the error, display an alert panel that 
    instructs the user to quit the application by pressing the Home button.

     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.
     */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}    

return persistentStoreCoordinator;
}
EN

回答 12

Stack Overflow用户

发布于 2014-04-22 02:45:26

只需详细说明将核心数据添加到以前没有核心数据的项目时实际需要执行的所有步骤:

步骤1:添加框架

单击您的应用程序目标(在左侧窗格的顶部图标上有您的应用程序名称),然后转到“构建阶段”选项卡,然后单击“将二进制文件与库链接”,单击底部的小'+‘,然后找到'CoreData.framework’并将其添加到您的项目中

然后使用以下命令在所有需要的对象上导入coredata (非性感方式):

Swift

代码语言:javascript
复制
import CoreData

Objective C

代码语言:javascript
复制
#import <CoreData/CoreData.h>

或者像这样将导入添加到您的.pch文件中的通用导入下面(更吸引人):

代码语言:javascript
复制
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import <CoreData/CoreData.h>
#endif

步骤2:添加数据模型

要添加.xcdatamodel文件,请在右窗格中右击/按住Control键并单击您的文件(如为了安全起见,在资源文件夹中)并选择添加一个新文件,在选择您的文件类型时单击核心数据选项卡,然后单击“数据模型”,给它一个名称,然后单击下一步并完成,它将添加到您的项目中。当您单击此Model对象时,您将看到用于将实体添加到您的项目中的界面,其中包含您想要的任何关系。

第三步:更新App Delegate

在AppDelegate.swift上的Swift

代码语言:javascript
复制
//replace the previous version of applicationWillTerminate with this
func applicationWillTerminate(application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    // Saves changes in the application's managed object context before the application terminates.
    self.saveContext()
}

func saveContext () {
    var error: NSError? = nil
    let 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.
            //println("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.
var managedObjectContext: NSManagedObjectContext {
    if !_managedObjectContext {
        let coordinator = self.persistentStoreCoordinator
        if coordinator != nil {
            _managedObjectContext = NSManagedObjectContext()
            _managedObjectContext!.persistentStoreCoordinator = coordinator
        }
    }
    return _managedObjectContext!
}
var _managedObjectContext: NSManagedObjectContext? = nil

// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
var managedObjectModel: NSManagedObjectModel {
    if !_managedObjectModel {
        let modelURL = NSBundle.mainBundle().URLForResource("iOSSwiftOpenGLCamera", withExtension: "momd")
        _managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)
    }
    return _managedObjectModel!
}
var _managedObjectModel: NSManagedObjectModel? = nil

// 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.
var persistentStoreCoordinator: NSPersistentStoreCoordinator {
    if !_persistentStoreCoordinator {
        let storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("iOSSwiftOpenGLCamera.sqlite")
        var error: NSError? = nil
        _persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
        if _persistentStoreCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil, error: &error) == nil {
            /*
            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:
            [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true}
            Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
            */
            //println("Unresolved error \(error), \(error.userInfo)")
            abort()
        }
    }
    return _persistentStoreCoordinator!
}
var _persistentStoreCoordinator: NSPersistentStoreCoordinator? = nil

// #pragma mark - Application's Documents directory

// Returns the URL to the application's Documents directory.
var applicationDocumentsDirectory: NSURL {
    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    return urls[urls.endIndex-1] as NSURL
}

Objective C中,确保将这些对象添加到AppDelegate.h

代码语言:javascript
复制
 @property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
 @property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
 @property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

 - (NSURL *)applicationDocumentsDirectory; // nice to have to reference files for core data

像这样合成AppDelegate.m中之前的对象:

代码语言:javascript
复制
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

然后将这些方法添加到AppDelegate.m (请确保将您添加的模型的名称放在显示的点中):

代码语言:javascript
复制
- (void)saveContext{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

- (NSManagedObjectContext *)managedObjectContext{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

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

- (NSManagedObjectModel *)managedObjectModel{
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAMEOFYOURMODELHERE" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

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

    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {

        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];
}

步骤4:将数据对象放到需要数据的ViewControllers中

选项1.使用VC (首选且更简单)中的应用代理的ManagedObjectContext

根据@brass-kazoo的建议-通过以下方式检索对AppDelegate及其managedObjectContext的引用:

Swift

代码语言:javascript
复制
 let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
 appDelegate.managedObjectContext

Objective C

代码语言:javascript
复制
 [[[UIApplication sharedApplication] delegate] managedObjectContext];

在你的ViewController中

选项2.在您的VC中创建ManagedObjectContext,并使其与AppDelegate (原始)中的AppDelegate匹配

只显示Objective C的旧版本,因为使用首选方法要容易得多

在ViewController.h中

代码语言:javascript
复制
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

在ViewController.m中

代码语言:javascript
复制
@synthesize managedObjectContext = _managedObjectContext;

在创建ViewController的AppDelegate或类中,将managedObjectContext设置为与AppDelegate相同

代码语言:javascript
复制
ViewController.managedObjectContext = self.managedObjectContext;

如果您希望使用核心数据的视图控制器是一个FetchedResultsController,那么您需要确保这些内容在您的ViewController.h中

代码语言:javascript
复制
@interface ViewController : UIViewController <NSFetchedResultsControllerDelegate> {
  NSFetchedResultsController *fetchedResultsController;
  NSManagedObjectContext *managedObjectContext;
}

 @property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;

这是在ViewController.m中

代码语言:javascript
复制
@synthesize fetchedResultsController, managedObjectContext;

在这之后,您现在可以使用这个managedObjectContext来运行CoreData所需的所有常用fetchRequests了!尽情享受

票数 130
EN

Stack Overflow用户

发布于 2017-08-04 16:54:09

Swift 3的:包括保存和检索数据

第1步:添加框架

第2步:添加数据模型

文件>新建>文件>核心数据>数据模型

  • 将文件命名为SampleData,生成的文件将为SampleData

Step 3:将以下功能添加到您的应用代理中,并将“导入CoreData”添加到顶部

代码语言:javascript
复制
func applicationWillTerminate(_ application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    // Saves changes in the application's managed object context before the application terminates.
    self.saveContext()
}


// MARK: - Core Data stack

lazy var persistentContainer: NSPersistentContainer = {
    /*
     The persistent container for the application. This implementation
     creates and returns a container, having loaded 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.
     */


    // SEE BELOW LINE OF CODE WHERE THE 'name' IS SET AS THE FILE NAME (SampleData) FOR THE CONTAINER

    let container = NSPersistentContainer(name: "SampleData")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() 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 parent directory does not exist, cannot be created, or disallows writing.
             * The persistent store is not accessible, due to permissions or data protection when the device is locked.
             * The device is out of space.
             * The store could not be migrated to the current model version.
             Check the error message to determine what the actual problem was.
             */
            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 {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() 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.
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

步骤4:向模型添加实体和属性

a)添加实体

b)添加属性

步骤5:保存数据

代码语言:javascript
复制
func saveItem(itemToSave: String){
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

//**Note:** Here we are providing the entityName **`Entity`** that we have added in the model
    let entity = NSEntityDescription.entity(forEntityName: "Entity", in: context)
    let myItem = NSManagedObject(entity: entity!, insertInto: context)

    myItem.setValue(itemToSave, forKey: "item")
    do {
        try context.save()
    }
    catch{
        print("There was an error in saving data")
    }
}

步骤5:检索数据

代码语言:javascript
复制
override func viewWillAppear(_ animated: Bool) {
    // Obtaining data from model
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Entity")

    do {
        let results = try context.fetch(fetchRequest)
        let obtainedResults = results as! [NSManagedObject]
        let firstResult = obtainedResults[0]
        let myValue = firstResult.value(forKey: "item")

        print("myValue: \(myValue)")
    } catch {
        print("Error")
    }
}
票数 20
EN

Stack Overflow用户

发布于 2010-01-09 16:48:55

尝试创建核心数据支持的Cocoa应用程序,然后看看AppDelegate。您将在那里看到核心数据堆栈实现方法,以及用于定义实体和其他核心数据相关内容的托管对象模型文件。

您只向我们展示了头部(即声明),但没有显示核心数据堆栈的实现(即定义)。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2032818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档