将 Core Data 添加到现有 iPhone 项目
我想将核心数据添加到现有的 iPhone 项目中,但仍然遇到很多编译错误:
- NSManagedObjectContext undeclared
- Expected specifier-qualifier-list before 'NSManagedObjectModel'
- ...
我已经将核心数据框架添加到目标中(右键单击“目标”下的我的项目,“添加”-“现有框架”、“CoreData.framework”)。
我的头文件:
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 未声明
”、“NSPersistentStoreCoordinator 未声明”,但也在
NSManagedObjectContext
之前加上“Expected ')'”(尽管括号似乎是正确的)...
#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;
}
I'd like to add core data to an existing iPhone project, but I still get a lot of compile errors:
- NSManagedObjectContext undeclared
- Expected specifier-qualifier-list before 'NSManagedObjectModel'
- ...
I already added the Core Data Framework to the target (right click on my project under "Targets", "Add" - "Existing Frameworks", "CoreData.framework").
My header-file:
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
[...]
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
What am I missing? Starting a new project is not an option...
Thanks a lot!
edit
sorry, I do have those implementations... but it seems like the Library is missing... the implementation methods are full with compile error like "managedObjectContext undeclared
", "NSPersistentStoreCoordinator undeclared
", but also with "Expected ')' before NSManagedObjectContext
" (although it seems like the parenthesis are correct)...
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
所有 CoreData 头文件都导入到
App_Prefix.pch
中,因此 CoreData 类将在整个项目中可用,因此您不必在需要它们的文件中手动导入头文件。因此,打开 Xcode 并查找像
App_Prefix.pch
这样的文件,默认情况下它位于Other Sources
组中。在UIKit
import 语句之后,添加以下行:您应该准备好了。
Xcode 4
对于在 Xcode 4 中创建的项目,可以在项目导航器的
Supporting Files
组中找到前缀文件。默认情况下,其名称为“项目名称-Prefix.pch”。Xcode 6+
从 Xcode 6 开始,默认情况下不再包含预编译头文件。这是因为引入了模块,它消除了使用预编译头的需要。虽然仍然可以手动添加 PCH 文件以全局包含 CoreData 标头,请考虑在每个使用 CoreData 的文件中使用
@import CoreData;
* 指定 CoreData 依赖项。这使得依赖关系变得明确,更重要的是将来可以避免这个问题的问题。* 模块需要启用才能正常工作。
All the CoreData header files are imported in
App_Prefix.pch
, so the CoreData classes will be available throughout your Project, so you don't have to manually import the header in the files you need them.So open up Xcode and look for some file like
App_Prefix.pch
, by default it's in theOther Sources
group. After theUIKit
import statement, add the following line:And you should be ready to go.
Xcode 4
For projects created in Xcode 4, the prefix file can be found in the
Supporting Files
group in the Project navigator. It's called 'projectname-Prefix.pch' by default.Xcode 6+
Starting with Xcode 6, the precompiled header file is no longer included by default. This is because of the introduction of Modules, which take away the need to use precompiled headers. While it is still possible to manually add a PCH file to globally include the CoreData headers, consider specifying the CoreData dependency using
@import CoreData;
* in every file that uses CoreData. This makes dependencies explicit and more importantly will avoid this question's problem in the future.* Modules need to be enabled for this to work.
只是为了阐述将核心数据添加到以前没有的项目中实际需要执行的所有步骤:
步骤 1:添加框架
单击您的应用程序目标(在左侧窗格中,其顶部图标的名称为你的应用程序)然后转到“Build Phases”选项卡,然后在“Link Binary With Libraries”上,单击底部的小“+”,然后找到“CoreData.framework”并将其添加到您的项目中
然后在所有您需要它的对象(非性感的方式)使用:
Swift
Objective C
或在 .pch 文件中的常见导入下方添加导入(更性感),如下所示:
第 2 步:添加数据模型
要添加 .xcdatamodel 文件,请右键单击/按住 Control 单击右侧窗格中的文件(如在资源文件夹中以便安全保存),然后选择“添加新文件”,单击“核心数据”选项卡选择文件类型时,单击“数据模型”,为其命名,然后单击“下一步”和“完成”,它将把它添加到您的项目中。当您单击此模型对象时,您将看到将实体添加到项目中并具有您想要的任何关系的界面。
App Delegate
步骤 3:在 AppDelegate.swift 上更新 Swift 中的
在 Objective C 中,确保将这些对象添加到 AppDelegate.h 中,
像这样综合 AppDelegate.m 中以前的对象:
然后将这些方法添加到 AppDelegate.m(确保将您添加的模型的名称放在显示的位置):
步骤 4:将数据对象获取到需要数据的 ViewController
选项 1. 使用来自 VC 的应用程序委托的 ManagedObjectContext(首选且更简单)
正如 @brass-kazoo 所建议的 - 通过以下方式检索对 AppDelegate 及其 ManagedObjectContext 的引用:
Swift
Objective C
你的 ViewController
选项 2. 在你的 VC 中创建 ManagedObjectContext 并让它与 AppDelegate 中的 AppDelegate 匹配(原始)
仅显示 Objective C 的旧版本,因为更容易使用首选方法
在 ViewController.h 中
在 ViewController.m 中
在 AppDelegate 中,或者创建 ViewController 的类中,将 ManagedObjectContext 设置为与 AppDelegate 相同
如果您希望使用 Core Data 的视图控制器成为 FetchedResultsController 那么您需要确保这些东西在你的 ViewController.h 中
这在 ViewController.m 中
之后,你现在可以使用这个 ManagedObjectContext 来运行 CoreData 所需的所有常见 fetchRequests!享受
Just to expound on all the steps you actually need to perform to add Core Data to a project that previously did not have it:
Step 1: Add the Framework
Click on your app target (on the left pane its the top icon with the name of your app) then go to the 'Build Phases' tab then on 'Link Binary With Libraries', click the little '+' at the bottom then find 'CoreData.framework' and add it to your project
Then either import coredata on all the objects you need it (the non-sexy way) using:
Swift
Objective C
or add the import below the common imports in your .pch file (much more sexy) like this:
Step 2: Add the Data Model
To add the .xcdatamodel file right click/control-click on your files in the right pane (like in a Resources folder for safe keeping) and select to Add a New File, Click the Core Data tab when selecting your file type then Click 'Data Model', give it a name and click Next and Finish and it will add it to your project. When you click on this Model object you will see the interface to add the Entities to your project with any relationships you want.
Step 3: Update App Delegate
In Swift on AppDelegate.swift
In Objective C make sure to add these objects to AppDelegate.h
Synthesize the previous objects in AppDelegate.m like this:
Then add these methods to AppDelegate.m (make sure to put the name of the model that you added in the spots shown):
Step 4: Get the Data Objects to the ViewControllers Where You Need the Data
Option 1. Use the App Delegate's ManagedObjectContext from VC (Preferred and Easier)
As suggeted by @brass-kazoo - Retrieve a reference to AppDelegate and its managedObjectContext via:
Swift
Objective C
in your ViewController
Option 2. Create ManagedObjectContext in your VC and have it match AppDelegate's from the AppDelegate (Original)
Only showing old version for Objective C since much easier to use the preferred method
in the ViewController.h
In the ViewController.m
In the AppDelegate, or class where the ViewController is created set the managedObjectContext to be the same as the AppDelegate one
If you want the viewcontroller using Core Data to be a FetchedResultsController then you'll need to make sure this stuff is in your ViewController.h
And this is in ViewController.m
After all of that you can now use this managedObjectContext to run all the usual fetchRequests needed for CoreData goodness! Enjoy
对于 Swift 3:包括保存和检索数据
第 1 步:添加框架
第 2 步:添加数据模型
文件>新的>文件>核心数据>数据模型
SampleData
,生成的文件将为SampleData.xcdatamocelId
第 3 步: 将以下函数添加到您的 App Delegate 并添加“ import CoreData”到顶部
第 4 步: 将实体和属性添加到模型
a) 添加实体
b) 添加属性
第 5 步:保存数据
第 5 步:检索数据
For Swift 3: INCLUDES SAVING AND RETRIEVING DATA
Step 1: Add Framework
Step 2: Add Data model
File > New > File > Core Data > Data Model
SampleData
the resultant file would beSampleData.xcdatamocelId
Step 3: Add the below functions to your App Delegate and add "import CoreData" to the top
STEP 4: Adding Entity and Attribute to the Model
a) Add Entity
b) Add Attribute
STEP 5: Saving Data
STEP 5: Retrieving Data
尝试创建 Core Data 支持的 Cocoa 应用程序并查看 AppDelegate。您将在那里看到核心数据堆栈实现方法以及用于定义实体和其他核心数据相关内容的托管对象模型文件。
您只向我们展示了核心数据堆栈的标头(即声明),而不是实现(即定义)。
Try creating Core Data backed Cocoa application and look at AppDelegate. You'll see core data stack implementation methods there as well as managed object model file for defining your entities and other core-data releated stuff.
You've shown us only header (i.e. declaration), but not implementation (i.e. definition) of the Core Data stack.
如果你像我一样在 xcode 4 中遇到同样的问题。
它是不同的:我必须选择项目,然后在目标中展开“Link Binary With Libraries”,其中显示当前的库。
从那里单击 +(加号)以选择您需要的任何其他库。
我将其放置在项目的顶部,并且必须将其移动(拖放)到框架组,但仅此而已。
If you run into this same issue in xcode 4, as I did.
It is different: I had to select the project, then in targets expand "Link Binary With Libraries" which shows the current libraries.
From there click the + (plus sign) to select any additional libraries you need.
I placed it in the top of the project and had to move it (drag and drop) to the Frameworks Group, but that was it.
正如 Eimantas 所说,您缺少核心堆栈的实现,解决
方案是创建一个新的核心数据驱动程序项目并将实现复制/粘贴到您的项目中。
As Eimantas stated your missing the implementiation of the Core Stack, like
On solution would be to create a new core data driver project and copy / paste the implementation to your project.
对于 Swift 3:
File->new file->CoreData->Model 创建模型。
请参阅此链接 了解有关如何实施的更多信息。
For Swift 3:
File->new file->CoreData->Model to create a model.
Refer to this link for more information on how to implement it.
//在 Swift 2.2 中,您可以在不更改 AppDelegate 文件的情况下执行以下操作。
现在添加一个新框架(点击+)'CoreData'
将其命名为 A.xcdatamodelid
将其命名为 Bc 并在右侧检查器窗口中将其类设置为“Bc”。
将创建两个新文件 1. 一个名为 Bc.swift 的新类和一个名为 Bc+coredataproperties.swift 的扩展。
文件->新建文件->ios->cocoa Touch类->将其子类设置为NSObject->命名为DataController.swift
文件里面包含
///
导入UIKit
导入核心数据
类 DataController: NSObject {
}
//////
重要提示:在您的 viewController 中包含该语句
“导入核心数据”
一个。调用seed() -->将值插入数据库/实体
b.调用 fetch()-->从数据库/实体获取值
///////seed()-->def
//fetch() def
//in Swift 2.2 , you may do the following without changing the AppDelegate file.
Now add a new framework (click on +) 'CoreData'
name it as say A.xcdatamodelid
name it as say Bc and set its class as 'Bc' in inspector window on right.
Two new files will be created 1. a new class named Bc.swift and an extension named Bc+coredataproperties.swift.
File->new file->ios->cocoa Touch class-->set its subclass as NSObject->name it as DataController.swift
Inside the file include
///
import UIKit
import CoreData
class DataController: NSObject {
}
//////
Important : include the statement in your viewController
"import CoreData"
a. call seed() -->to insert value into db/entity
b. call fetch()--> to fetch value from db/entity
///////seed()-->def
//fetch() def
查看.h
详细信息.h
view.h
detail.h
.h
.h
示例编码视图1
示例详细视图
保存按钮
sample coding view1
sample detail view
savebutton