将核心数据添加到现有的 iPhone 项目
Posted
技术标签:
【中文标题】将核心数据添加到现有的 iPhone 项目【英文标题】:Adding Core Data to existing iPhone project 【发布时间】:2010-01-09 08:30:17 【问题描述】:我想中,但仍然遇到很多编译错误:
- NSManagedObjectContext undeclared
- Expected specifier-qualifier-list before 'NSManagedObjectModel'
- ...
我已经将 Core Data Framework 添加到目标中(右键单击“Targets”下的我的项目,“Add”-“Existing Frameworks”,“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 undeclared
”、“NSPersistentStoreCoordinator undeclared
”,但也有“预期的')'在NSManagedObjectContext
"之前(尽管括号似乎是正确的)...
#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;
【问题讨论】:
【参考方案1】:所有 CoreData 头文件都导入到 App_Prefix.pch
中,因此 CoreData 类将在您的整个项目中可用,因此您不必在需要的文件中手动导入头文件。
所以打开 Xcode 并寻找一些像 App_Prefix.pch
这样的文件,默认情况下它在 Other Sources
组中。在UIKit
import 语句之后,添加以下行:
#import <CoreData/CoreData.h>
你应该准备好了。
Xcode 4
对于在 Xcode 4 中创建的项目,可以在项目导航器的 Supporting Files
组中找到前缀文件。默认情况下它被称为 'projectname-Prefix.pch'。
Xcode 6+
从 Xcode 6 开始,默认情况下不再包含预编译的头文件。这是因为引入了模块,take away the need to use precompiled headers. 虽然仍然可以手动添加 PCH 文件以全局包含 CoreData 标头,但请考虑在每个使用 CoreData 的文件中使用 @import CoreData;
* 指定 CoreData 依赖项。这使得依赖关系变得明确,更重要的是将在未来避免这个问题的问题。
* 模块 need to be enabled 使其工作。
【讨论】:
如果我在 xcode 6.4 和 ios 8.4 中找不到任何 App_prefix.pch 文件该怎么办。【参考方案2】:只是为了说明将 Core Data 添加到以前没有的项目中实际需要执行的所有步骤:
第 1 步:添加框架
点击您的应用程序目标(在左侧窗格中,其顶部图标带有您的应用程序名称),然后转到“构建阶段”选项卡,然后在“将二进制文件与库链接”上,单击小“+”在底部然后找到'CoreData.framework'并将其添加到您的项目中
然后使用以下方法在您需要的所有对象上导入 coredata(非性感方式):
斯威夫特
import CoreData
目标 C
#import <CoreData/CoreData.h>
或在 .pch 文件中的常见导入下方添加导入(更性感),如下所示:
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#endif
第 2 步:添加数据模型
要添加 .xcdatamodel 文件,请在右侧窗格中右键单击/控制单击您的文件(例如在资源文件夹中以确保安全)并选择添加新文件,在选择文件类型时单击核心数据选项卡然后单击“数据模型”,为其命名并单击下一步和完成,它将将其添加到您的项目中。当您单击此模型对象时,您将看到将实体添加到您的项目的界面以及您想要的任何关系。
第 3 步:更新应用委托
在 AppDelegate.swift 上的 Swift 中
//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
@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 中合成之前的对象:
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
然后将这些方法添加到 AppDelegate.m(确保将您添加的模型的名称放在显示的位置):
- (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 的 App Delegate 的 ManagedObjectContext(首选且更简单)
正如@brass-kazoo 所建议的那样——通过以下方式检索对 AppDelegate 及其 managedObjectContext 的引用:
斯威夫特
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.managedObjectContext
目标 C
[[[UIApplication sharedApplication] delegate] managedObjectContext];
在您的视图控制器中
选项 2. 在您的 VC 中创建 ManagedObjectContext 并使其与 AppDelegate 中的 AppDelegate 匹配(原始)
只显示 Objective C 的旧版本,因为更容易使用首选方法
在 ViewController.h 中
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
在 ViewController.m 中
@synthesize managedObjectContext = _managedObjectContext;
在 AppDelegate 或创建 ViewController 的类中,将 managedObjectContext 设置为与 AppDelegate 相同
ViewController.managedObjectContext = self.managedObjectContext;
如果您希望使用 Core Data 的视图控制器成为 FetchedResultsController,那么您需要确保这些内容在您的 ViewController.h 中
@interface ViewController : UIViewController <NSFetchedResultsControllerDelegate>
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
这是在 ViewController.m 中
@synthesize fetchedResultsController, managedObjectContext;
在所有这些之后,您现在可以使用这个 managedObjectContext 来运行 CoreData 所需的所有常用 fetchRequest!享受
【讨论】:
在 AppDelegate.h 中,applicationDoumentsDirectory 方法应该返回 NSURL 而不是 NSString。 这是 IMO 的最佳答案!虽然我不是通过第 4 步而是通过[[UIApplication sharedApplication] delegate]
检索对 AppDelegate 的引用,然后通过[appDelegate managedObjectContext]
检索上下文
别忘了在 AppDelegate.h 文件中导入 Coredata。【参考方案3】:
对于 Swift 3:包括保存和检索数据
第 1 步:添加框架
第 2 步:添加数据模型
文件 > 新建 > 文件 > 核心数据 > 数据模型
将文件命名为SampleData
,生成的文件将是SampleData.xcdatamocelId
第 3 步:将以下函数添加到您的 App Delegate 并在顶部添加“import CoreData”
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 步:保存数据
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 步:检索数据
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")
【讨论】:
【参考方案4】:尝试创建支持 Core Data 的 Cocoa 应用程序并查看 AppDelegate。您将在那里看到核心数据堆栈实现方法以及用于定义实体和其他核心数据相关内容的托管对象模型文件。
您只向我们展示了核心数据堆栈的标头(即声明),而不是实现(即定义)。
【讨论】:
对于 swift 3,我使用了 ColossalChris 的步骤,但在 AppDelegate 的一部分中使用了这个答案(从具有核心数据支持的新项目中复制)来获得 swift 3 兼容的代码。【参考方案5】:如果您像我一样在 xcode 4 中遇到同样的问题。 不同的是:我必须选择项目,然后在目标中展开显示当前库的 "Link Binary With Libraries"。 从那里单击 +(加号)以选择您需要的任何其他库。 我将它放在项目的顶部,不得不将它(拖放)移动到 Frameworks Group,但仅此而已。
【讨论】:
【参考方案6】:正如 Eimantas 所说,您缺少核心堆栈的实现,例如
- (NSManagedObjectContext *) managedObjectContext;
- (NSManagedObjectModel *)managedObjectMode;
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator;
解决方案是创建一个新的核心数据驱动程序项目并将实现复制/粘贴到您的项目中。
【讨论】:
那么如何管理上下文会知道模型呢?自动?【参考方案7】:对于 Swift 3:
文件->新建文件->CoreData->模型创建模型。
请参阅此link,了解有关如何实施的更多信息。
【讨论】:
【参考方案8】://在 Swift 2.2 中,您可以在不更改 AppDelegate 文件的情况下执行以下操作。
-
项目->目标-->链接的框架和库
现在添加一个新框架(点击 +)'CoreData'
文件->新文件->CoreData->DataModel
将其命名为 A.xcdatamodelid
在 A.xcdatamodelid 中创建新实体(点击实体+)
将其命名为 Bc,并在右侧的检查器窗口中将其类设置为“Bc”。
现在向实体添加属性(点击属性+),添加一个属性,例如:名称及其类型为字符串。
现在编辑器->创建NSManagedObject子类-->在弹出的窗口中单击下一步-->再次下一步-->然后单击创建。
将创建两个新文件 1. 一个名为 Bc.swift 的新类和一个名为 Bc+coredataproperties.swift 的扩展。
文件->新建文件->ios->cocoa Touch类-->设置子类为NSObject->命名为DataController.swift 文件里面包括 ///
导入 UIKit 导入核心数据 类数据控制器:NSObject
var managedObjectContext: NSManagedObjectContext
override init()
// This resource is the same name as your xcdatamodeld contained in your project.
guard let modelURL = NSBundle.mainBundle().URLForResource("A", withExtension:"momd") else
fatalError("Error loading model from bundle")
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
guard let mom = NSManagedObjectModel(contentsOfURL: modelURL) else
fatalError("Error initializing mom from: \(modelURL)")
let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
self.managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
self.managedObjectContext.persistentStoreCoordinator = psc
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
let docURL = urls[urls.endIndex-1]
/* The directory the application uses to store the Core Data store file.
This code uses a file named "A.sqlite" in the application's documents directory.
*/
let storeURL = docURL.URLByAppendingPathComponent("A.sqlite")
do
try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
catch
fatalError("Error migrating store: \(error)")
//////
-
现在在 viewcontroller 文件中,您可以使用两种方法访问您的数据库。
重要:在您的 viewController 中包含该语句
“导入核心数据”
一种。调用 seed() --> 将值插入 db/entity
湾。调用 fetch()--> 从 db/entity 获取值
///////seed()-->def
func seedPerson()
// create an instance of our managedObjectContext
let moc = DataController().managedObjectContext
// we set up our entity by selecting the entity and context that we're targeting
let entity = NSEntityDescription.insertNewObjectForEntityForName("Bc", inManagedObjectContext: moc) as! Bc
// add our data
entity.setValue("Meera", forKey: "name")
// we save our entity
do
try moc.save()
catch
fatalError("Failure to save context: \(error)")
//fetch() 定义
func fetch()
let moc = DataController().managedObjectContext
let personFetch = NSFetchRequest(entityName: "Bc")
do
let fetchedPerson = try moc.executeFetchRequest(personFetch) as! [Bc]
print(fetchedPerson.first!.name!)
catch
fatalError("Failed to fetch person: \(error)")
【讨论】:
【参考方案9】:view.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface ViewController :
UIViewController<UITableViewDataSource,UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *coreDataList;
- (IBAction)addBtnClick:(id)sender;
@property (strong, nonatomic) NSMutableArray *dataList;
@end
detail.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface DetailViewController : UIViewController<UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITextField *nameTxt;
@property (weak, nonatomic) IBOutlet UITextField *mobileTxt;
@property (weak, nonatomic) IBOutlet UITextField *emailIdTxt;
- (IBAction)saveBtnClick:(id)sender;
@property (strong,nonatomic) NSManagedObject *userData;
@end
【讨论】:
【参考方案10】: - (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
if (self.userData)
[self.nameTxt setText:[self.userData valueForKey:@"name"]];
[self.mobileTxt setText:[self.userData
valueForKey:@"mobileNumber"]];
[self.emailIdTxt setText:[self.userData valueForKey:@"email"]];
[self.imgView setImage:[UIImage imageWithData:[self.userData
valueForKey:@"imageView"]]];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
[textField resignFirstResponder];
return YES;
/*
#pragma mark - Navigation
- (IBAction)browseBtn:(id)sender
UIImagePickerController *imgpic =[[UIImagePickerController
alloc]init];
imgpic .delegate =self;
imgpic .sourceType =UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imgpic animated:YES completion:nil];
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
UIImage *choose = info[UIImagePickerControllerOriginalImage];
self.imgView.image=choose;
[picker dismissViewControllerAnimated:YES completion:nil];
- (IBAction)saveBtnClick:(id)sender
NSManagedObjectContext *context = [self managedObjectContext];
if (self.userData)
// Update existing data
[self.userData setValue:self.nameTxt.text forKey:@"name"];
[self.userData setValue:self.mobileTxt.text
forKey:@"mobileNumber"];
[self.userData setValue:self.emailIdTxt.text forKey:@"email"];
UIImage *sampleimage = _imgView.image;
NSData *dataImage = UIImageJPEGRepresentation(sampleimage, 1.0);
[self.userData setValue:dataImage forKey:@"imageView"];
else
// Create a new data
NSManagedObject *newDevice = [NSEntityDescription
insertNewObjectForEntityForName:@"Details"
inManagedObjectContext:context];
[newDevice setValue:self.nameTxt.text forKey:@"name"];
[newDevice setValue:self.mobileTxt.text forKey:@"mobileNumber"];
[newDevice setValue:self.emailIdTxt.text forKey:@"email"];
UIImage *sampleimage = _imgView.image;
NSData *dataImage = UIImageJPEGRepresentation(sampleimage, 1.0);
[newDevice setValue:dataImage forKey:@"imageView"];
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error])
NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
[self dismissViewControllerAnimated:YES completion:nil];
@end
.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface DetailViewController :
UIViewController<UITextFieldDelegate,UINavigationControllerDelegate,
UIIma
gePickerControllerDelegate>
@property (weak, nonatomic) IBOutlet UITextField *nameTxt;
@property (weak, nonatomic) IBOutlet UITextField *mobileTxt;
@property (weak, nonatomic) IBOutlet UITextField *emailIdTxt;
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
- (IBAction)browseBtn:(id)sender;
- (IBAction)saveBtnClick:(id)sender;
@property (strong,nonatomic) NSManagedObject *userData;
@end
【讨论】:
对您的解决方案的解释将不胜感激......此外,没有无关注释代码的最少代码......【参考方案11】: let alert = UIAlertController(title:"Error", message: "No Internet Connection", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: (action) in))
alert.addAction(UIAlertAction(title: "Try Again", style: .default, handler: (action) in
self.networkCall(text: self.daySelected)
))
self.present(alert, animated: false, completion: nil)
【讨论】:
【参考方案12】:+(void) insetPlusUpdate:(NSDictionary *)dataa
NSManagedObjectContext * context;
if (![[NSThread currentThread] isMainThread])
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[APP_DELEGATE persistentStoreCoordinator]];
else
context = [APP_DELEGATE managedObjectContext];
NSFetchRequest * request = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@"EntityName" inManagedObjectContext:context];
[request setEntity:entity];
NSPredicate * check = [NSPredicate predicateWithFormat:@"attribute == %@", Dict[@"key"]];
[request setPredicate:check];
NSError * error = nil;
if ([context countForFetchRequest:request error:&error] == 0)
Entity.attribute = @"";
else
NSArray * array = [context executeFetchRequest:request error:&error];
EntityName * entity = [array firstObject];
Entity.attribute = @"";
+(NSString *)fetch:(NSString *)feed_id
NSManagedObjectContext * context;
if(![[NSThread currentThread] isMainThread])
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[APP_DELEGATE persistentStoreCoordinator]];
else
context = [APP_DELEGATE managedObjectContext];
NSFetchRequest * request = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@"ENTITYNAME" inManagedObjectContext:context];
[request setEntity:entity];
NSPredicate * check = [NSPredicate predicateWithFormat:@"attribute == %@", Dict[@"key"]];
[request setPredicate:check];
NSError * error = nil;
if ([context countForFetchRequest:request error:&error] > 0)
NSArray * array = [context executeFetchRequest:request error:&error];
ENTITYNAME * fetchData = [array firstObject];
NSString * string = fetchData.attribte[@"key"];
return string;
return nil;
+(BOOL)delete
NSManagedObjectContext * context;
if (![[NSThread currentThread] isMainThread])
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[APP_DELEGATE persistentStoreCoordinator]];
else
context = [APP_DELEGATE managedObjectContext];
NSFetchRequest * request = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@"ENTITYNAME" inManagedObjectContext:context];
[request setEntity:entity];
NSError *error = nil;
NSBatchDeleteRequest *deleteRequest = [[NSBatchDeleteRequest alloc] initWithFetchRequest: request];
@try
[context executeRequest:deleteRequest error:&error];
if([context save:&error])
NSLog(@"Deleted");
return [context save:&error];
else
return [context save:&error];
@catch(NSException *exception)
NSLog(@"failed %@",exception);
return [context save:&error];
【讨论】:
【参考方案13】:示例编码视图1
#import "ViewController.h"
#import "DetailViewController.h"
@interface ViewController ()
NSInteger indexPathvalue;
@end
@implementation ViewController
- (NSManagedObjectContext *)managedObjectContext
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:@selector(managedObjectContext)])
context = [delegate managedObjectContext];
return context;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"call this one2");
- (void)viewDidAppear:(BOOL)animated
[super viewDidAppear:animated];
NSManagedObjectContext *managedObjectContext = [self
managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]
initWithEntityName:@"Details"];
self.dataList = [[managedObjectContext executeFetchRequest:fetchRequest
error:nil] mutableCopy];
[_coreDataList reloadData];
NSLog(@"call this one");
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
return self.dataList.count;
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell
alloc]initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
NSManagedObject *user = [self.dataList objectAtIndex:indexPath.row];
cell.textLabel.text = [user valueForKey:@"name"];
cell.detailTextLabel.text = [user valueForKey:@"mobileNumber"];
cell.imageView.image = [UIImage imageWithData:[user
valueForKey:@"imageView"]];
return cell;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath
indexPathvalue = indexPath.row;
[self performSegueWithIdentifier:@"detailView" sender:self];
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:
(NSIndexPath *)indexPath
return YES;
- (void)tableView:(UITableView *)tableView commitEditingStyle:
(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:
(NSIndexPath *)indexPath
NSManagedObjectContext *context = [self managedObjectContext];
if (editingStyle == UITableViewCellEditingStyleDelete)
[context deleteObject:[self.dataList objectAtIndex:indexPath.row]];
NSError *error = nil;
if (![context save:&error])
NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]);
return;
[self.dataList removeObjectAtIndex:indexPath.row];
[_coreDataList reloadData];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (IBAction)addBtnClick:(id)sender
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([segue.identifier isEqualToString:@"detailView"])
NSManagedObject *obj = [self.dataList objectAtIndex:indexPathvalue];
DetailViewController *detail = segue.destinationViewController;
detail.userData = obj;
@end
示例详细视图
#import "DetailViewController.h"
@interface DetailViewController ()
@end
@implementation DetailViewController
- (NSManagedObjectContext *)managedObjectContext
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:@selector(managedObjectContext)])
context = [delegate managedObjectContext];
return context;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
if (self.userData)
[self.nameTxt setText:[self.userData valueForKey:@"name"]];
[self.mobileTxt setText:[self.userData valueForKey:@"mobileNumber"]];
[self.emailIdTxt setText:[self.userData valueForKey:@"email"]];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
[textField resignFirstResponder];
return YES;
/*
保存按钮
- (IBAction)saveBtnClick:(id)sender
NSManagedObjectContext *context = [self managedObjectContext];
if (self.userData)
// Update existing data
[self.userData setValue:self.nameTxt.text forKey:@"name"];
[self.userData setValue:self.mobileTxt.text forKey:@"mobileNumber"];
[self.userData setValue:self.emailIdTxt.text forKey:@"email"];
UIImage *sampleimage = [UIImage imageNamed:@"icon.png"];
NSData *dataImage = UIImageJPEGRepresentation(sampleimage, 1.0);
[self.userData setValue:dataImage forKey:@"imageView"];
else
// Create a new data
NSManagedObject *newDevice = [NSEntityDescription
insertNewObjectForEntityForName:@"Details"
inManagedObjectContext:context];
[newDevice setValue:self.nameTxt.text forKey:@"name"];
[newDevice setValue:self.mobileTxt.text forKey:@"mobileNumber"];
[newDevice setValue:self.emailIdTxt.text forKey:@"email"];
UIImage *sampleimage = [UIImage imageNamed:@"icon.png"];
NSData *dataImage = UIImageJPEGRepresentation(sampleimage, 1.0);
[newDevice setValue:dataImage forKey:@"imageView"];
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error])
NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
[self dismissViewControllerAnimated:YES completion:nil];
@end
【讨论】:
以上是关于将核心数据添加到现有的 iPhone 项目的主要内容,如果未能解决你的问题,请参考以下文章
将核心数据添加到现有的选项卡式应用程序(ios swift、Xcode6)
将 ResKit 集成到现有的 Core Data 应用程序中