Core Data without Master Detail Template - objective-c

I want to create an iphone application which uses Core Data.
As i understood, only master-detail application template gives me an option to use Core Data. But it creates table view.
What i want to use is view controller not table view controller.
I couldnt use core data with single view application template..
Which way should I follow to overcome this issue?
Thanks.

You should realize that CoreData is a framework that is not bound to any UIKit components like UITableView. You can freely use it in any sort of an application. All you have to do is to create your singleton class that manages CoreData operations and add CoreData.framework to your project.
Here is my DataAccessLayer template:
DataAccessLayer.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface DataAccessLayer : NSObject
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (strong, nonatomic) NSManagedObjectModel *managedObjectModel;
#property (strong, nonatomic) NSPersistentStoreCoordinator *storeCoordinator;
+ (DataAccessLayer *)sharedInstance;
- (void)saveContext;
#end
DataAccessLayer.m
#import "DataAccessLayer.h"
#interface DataAccessLayer ()
- (NSURL *)applicationDocumentsDirectory;
#end
#implementation DataAccessLayer
#synthesize storeCoordinator;
#synthesize managedObjectModel;
#synthesize managedObjectContext;
+ (DataAccessLayer *)sharedInstance {
__strong static DataAccessLayer *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[DataAccessLayer alloc] init];
sharedInstance.storeCoordinator = [sharedInstance persistentStoreCoordinator];
sharedInstance.managedObjectContext = [sharedInstance managedObjectContext];
});
return sharedInstance;
}
#pragma mark - Core Data
- (void)saveContext {
#synchronized(self) {
NSError *error = nil;
if (managedObjectContext != nil)
{
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
{
NSLog(#"error: %#", error.userInfo);
/*
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.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Oops!"
message:#"Something has gone terribly wrong! You need to reinstall the app in order for it to work properly."
delegate:nil
cancelButtonTitle:#"Close."
otherButtonTitles:nil, nil];
[alert show];
}
}
}
}
#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;
}
if (storeCoordinator != nil)
{
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:storeCoordinator];
}
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:#"DataModel" 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 (storeCoordinator != nil)
{
return storeCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"words_db.sqlite"];
NSError *error = nil;
storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![storeCoordinator 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.
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]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Oops!"
message:#"Something has gone terribly wrong! You need to reinstall the app in order for it to work properly."
delegate:nil
cancelButtonTitle:#"Close."
otherButtonTitles:nil, nil];
[alert show];
}
return storeCoordinator;
}
#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];
}
#end
You will also have to create an .xcdatamodeld file in order to create your Data Model objects. And replace the name here with appropriate
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"DataModel" withExtension:#"momd"];

Related

CoreData NSManagedObjectContext not found

New to iOS development. I am trying to use the core data stack in a sample app, which fetches data over network and simply updates the UI. Whilst creating the project, the "Use Core Data" checkbox was ticked which generates bunch of boilerplate code. However, on XCode 8.2.1, the I only see the NSPersistentContainer implementation within the AppDelegate.m file.
- (NSPersistentContainer *)persistentContainer {
// The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it.
#synchronized (self) {
if (_persistentContainer == nil) {
_persistentContainer = [[NSPersistentContainer alloc] initWithName:#"ergast_coredata_objc"];
[_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
if (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 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.
*/
NSLog(#"Unresolved error %#, %#", error, error.userInfo);
abort();
}
}];
}
}
return _persistentContainer;
}
There is no boilerplate code for the NSManagedObjectContext as most of the tutorials would have you believe.
Hence, the following block within the ViewController.m class fails with a Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AppDelegate managedObjectContext]: unrecognized selector sent to instance
-(NSArray *)getSeasonsList{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"SeasonData"];
NSError *error = nil;
NSArray *results = [[self getManagedObjectContext] executeFetchRequest:request error:&error];
if (!results) {
NSLog(#"Error fetching objects: %#\n%#", [error localizedDescription], [error userInfo]);
abort();
}
return results;
}
- (NSManagedObjectContext *)getManagedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
context = [delegate managedObjectContext];
return context;
}
Tried looking online but most of the tutorials are Swift based it seems. What am i missing here? Is the developer supposed to provide the implementation for the NSManagedObjectContext? Would be much appreciated if someone can provide with an Objective-c based sample code.
Thanks!
See in saveContext method
pragma mark - Core Data Saving support
- (void)saveContext {
// OBSERVE HERE
NSManagedObjectContext *context = self.persistentContainer.viewContext;
NSError *error = nil;
if ([context hasChanges] && ![context 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();
}
}
Whenever you need NSManagedObjectContext instance, access like this
NSManagedObjectContext *context = self.persistentContainer.viewContext;
self.persistentContainer OR classObject.persistentContainer
Modify the "getManagedObjectContext" method as below
- (NSManagedObjectContext *)getManagedObjectContext {
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [[delegate persistentContainer] viewContext];
return context;
}
I didn't tested this, but hope this will work
I have a category for appdelegate that was included in one of the old Stanford CS193P that uses objective-c. Some of it might be deprecated, though. Also check out https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/InitializingtheCoreDataStack.html#//apple_ref/doc/uid/TP40001075-CH4-SW1 has objective-c sample. Post back if that helps.
//
// PhotomaniaAppDelegate+MOC.m
// Photomania
//
// This code comes from the Xcode template for Master-Detail application.
#import "PhotomaniaAppDelegate+MOC.h"
#import <CoreData/CoreData.h>
#implementation PhotomaniaAppDelegate (MOC)
#pragma mark - Core Data
- (void)saveContext:(NSManagedObjectContext *)managedObjectContext
{
NSError *error = nil;
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();
}
}
}
// 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 *)createMainQueueManagedObjectContext
{
NSManagedObjectContext *managedObjectContext = nil;
NSPersistentStoreCoordinator *coordinator = [self createPersistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[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 *)createManagedObjectModel
{
NSManagedObjectModel *managedObjectModel = nil;
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"Photomania" 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 *)createPersistentStoreCoordinator
{
NSPersistentStoreCoordinator *persistentStoreCoordinator = nil;
NSManagedObjectModel *managedObjectModel = [self createManagedObjectModel];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"MOC.sqlite"];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: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:
#{NSMigratePersistentStoresAutomaticallyOption:#YES, NSInferMappingModelAutomaticallyOption:#YES}
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;
}
// Returns the URL to the application's Documents directory
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
#end
Also, check out this project https://github.com/m2mtech/photomania-2013-14/tree/master/Photomania/CoreDataTableViewController/MOC More info how Core Data was used with this implementation.

Could not delete core data PersistentStore

I want to remove the app PersistentStore completely. I read the following question completely and none of them worked:
Delete/Reset all entries in Core Data?
I have a Model Helper and do the delete task inside it:
#import <CoreData/CoreData.h>
#interface GeneralModel : NSFetchedResultsController
#property (nonatomic, strong) NSManagedObjectContext *context;
#property (nonatomic, strong) NSManagedObjectModel *model;
- (NSString *)storagePath;
- (void)removeStorage;
- (void)removeStorage2;
#end
#implementation GeneralModel
- (instancetype)init
{
self = [super init];
if (self) {
// Read in Model.xcdatamodeld
_model = [NSManagedObjectModel mergedModelFromBundles:nil];
NSPersistentStoreCoordinator *psc =
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model];
// Where does the SQLite file go?
NSString *path = self.storagePath;
NSURL *storeURL = [NSURL fileURLWithPath:path];
NSError *error = nil;
if (![psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:nil
error:&error]) {
#throw [NSException exceptionWithName:#"OpenFailure"
reason:[error localizedDescription]
userInfo:nil];
}
// Create the managed object context
_context = [[NSManagedObjectContext alloc] init];
_context.persistentStoreCoordinator = psc;
}
return self;
}
- (NSString *)storagePath
{
NSArray *documentDirectories =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
// Get one and only document directory from that list
NSString *documentDirectory = [documentDirectories firstObject];
return [documentDirectory stringByAppendingPathComponent:#"model.sqlite"];
}
- (void)removeStorage {
NSPersistentStore *store = [self.context.persistentStoreCoordinator.persistentStores lastObject];
NSError *error = nil;
NSURL *storeURL = store.URL;
BOOL isRemovePersistentStore = [self.context.persistentStoreCoordinator removePersistentStore:store error:&error];
if (isRemovePersistentStore == NO) {
NSLog(#"NO RemovePersistentStore. Reason: %#", error.localizedFailureReason);
}
BOOL isRemoveItemAtURL = [[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
if (isRemoveItemAtURL == NO) {
NSLog(#"NO RemoveItemAtURL. Reason: %#", error.localizedFailureReason);
}
}
- (void)removeStorage2 {
NSError *error;
NSString *storagePath = [self storagePath];
NSDictionary *options = #{NSPersistentStoreUbiquitousContentNameKey: #"model"};
bool removeResult = [NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:[NSURL URLWithString:storagePath] options:options error:&error];
if (removeResult == NO) {
NSLog(#"Could not remove Storage. Reason: %#", error.localizedFailureReason);
}
}
#end
When I call the "removeStorage" method by the following code:
GeneralModel *model = [[GeneralModel alloc] init];
[model removeStorage];
Result is that No error apear in the console, but it just removed the main storage file: "model.sqlite" and 2 other related files: "model.sqlite-shm" and "model.sqlite-wal" remained.
When I call the "removeStorage2" method by the same code, I see the following text on the console and none of the files deleted:
Could not remove Storage. Reason: (null)
How could I solve this problem?
Check out the video "Straight outta Moscone Center West" for the official introduction of how you should be doing this, and/or consult NSPersistentStoreCoordinator.h from which the following snippet was extracted.
/* delete or truncate the target persistent store in accordance with the store
class's requirements. It is important to pass similar options as
addPersistentStoreWithType: ... SQLite stores will honor file locks, journal
files, journaling modes, and other intricacies. It is not possible to unlink
a database file safely out from underneath another thread or process, so this
API performs a truncation. Other stores will default to using NSFileManager.
*/
- (BOOL)destroyPersistentStoreAtURL:(NSURL *)url
withType:(NSString *)storeType
options:(nullable NSDictionary *)options
error:(NSError**)error NS_AVAILABLE(10_11, 9_0);
/* copy or overwrite the target persistent store in accordance with the store
class's requirements. It is important to pass similar options as
addPersistentStoreWithType: ... SQLite stores will honor file locks, journal
files, journaling modes, and other intricacies. Other stores will default
to using NSFileManager.
*/
- (BOOL)replacePersistentStoreAtURL:(NSURL *)destinationURL
destinationOptions:(nullable NSDictionary *)destinationOptions
withPersistentStoreFromURL:(NSURL *)sourceURL
sourceOptions:(nullable NSDictionary *)sourceOptions
storeType:(NSString *)storeType
error:(NSError**)error NS_AVAILABLE(10_11, 9_0);

NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext

i am having a problem since days, i tryed all the solutions here in stackoverflow but anyone gives me a solution.
i am using core data and tableviewcontroller.
My CoreDataTableViewController its correct, i downloaded it from timroadnley and u use it in another projects.
Im getting an error : 'An instance of NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext'
The application loads correctly but when i press to go to the marksTableviewcontroller, it fails.
THE ERROR IS ON THIS LINE:
- (void)setupFetchedResultsController{
// 1 - Decide what Entity you want
NSString *entityName = #"Marks"; // Put your entity name here
NSLog(#"Setting up a Fetched Results Controller for the Entity named %#", entityName);
// 2 - Request that Entity
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
// 4 - Sort it if you want
request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"subject"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)]];
// 5 - Fetch it
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil]; //IN THIS LILE IS THE ERROR, IN "REQUEST"
[self performFetch];
}
THIS IS MY APPDELEGATE:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
marksTVCon.managedObjectContext = self.managedObjectContext;
NSDictionary *defaultsDict = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:YES], #"FirstLaunch", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsDict];
NSUserDefaults *sharedDefaults = [NSUserDefaults standardUserDefaults];
if([sharedDefaults boolForKey:#"FirstLaunch"]) {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"MYAPP" message:#"Thanks for downloading, hope you love our app" delegate:nil cancelButtonTitle:#"Go app" otherButtonTitles:nil, nil];
[message show];
[sharedDefaults setBool:NO forKey:#"FirstLaunch"];
[sharedDefaults synchronize];
}
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Saves changes in the application's managed object context before the application terminates.
[self saveContext];
}
- (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:#"MYAPP" 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:#"MYAPP.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:
#{NSMigratePersistentStoresAutomaticallyOption:#YES, NSInferMappingModelAutomaticallyOption:#YES}
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];
}
#end
If you need to ask for anyother peace of code pliz ask for it, I think the problem is in there, but im not pretty Sure.

How to add CoreData to exisiting Tab Based IOS project

I have tried a lot of different answers, but I just can't seem to get this to work. I am trying to add Core Data to an existing Tab Based Project that I have. I added the core data framework through the targets, I set up the DataModel and entities correctly, but I can't seem to access it. I have gotten many different errors, but the most recent is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'
I set up a new utility based project using the preset Core Data and copied the code as directly. I simply changed the File URL name to what current project is and it doesn't work. Here is my code:
appDelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
BOOL isNotFirstTime;
NSMutableArray *teamMembers;
NSMutableArray *projects;
NSMutableArray *tasks;
}
#property(readwrite, retain) NSMutableArray *teamMembers;
#property(readwrite, retain) NSMutableArray *projects;
#property(nonatomic, retain) NSMutableArray *tasks;
#property(nonatomic)BOOL isNotFirstTime;
#property (strong, nonatomic) UIWindow *window;
#property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
#property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
- (NSURL *)applicationDocumentsDirectory;
- (void)saveContext;
#end
AppDelegate.m
For some reason when I create the File URL it remains null.....I have no idea why..
#import "AppDelegate.h"
#import "Task.h"
#import "Project.h"
#import "TeamMember.h"
#import "newTeamMemberWindow.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize tasks;
#synthesize teamMembers;
#synthesize projects;
#synthesize isNotFirstTime;
#synthesize managedObjectContext = __managedObjectContext;
#synthesize managedObjectModel = __managedObjectModel;
#synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
NSLog(#"No Context on App Load");
}
newTeamMemberWindow *newTeamMemberWindowObject = [[newTeamMemberWindow alloc]init];
newTeamMemberWindowObject.managedObjectContext = context;
return YES;
}
//Removed all normal methods to consolidate code on stack overflow
#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;
}
This part the modelURL remains Null.....
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"TimeLines" withExtension:#"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSLog(#"Created managedObjectModel with Url: %#", 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:#"TimeLines.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];
}
#end
If I understood you have a separate project utility for coredata, if yes take a look at this question of mine. It made me crazy time ago !!!
How to include a bundle in main project xcode 4.1

How to unit test my models now that I am using Core Data?

I have been developing an iphone application using a domain model, and have put off the persistence aspect of the app until now. Core Data looks like a really good solution since I already have a well defined model but I am running into a snag with my existing unit tests.
Here is simple example of what I have now:
- (void)test_full_name_returns_correct_string {
Patient *patient = [[Patient alloc] init];
patient.firstName = #"charlie";
patient.lastName = #"chaplin";
STAssertTrue([[patient fullName] isEqualToString:#"charlie chaplin"], #"should have matched full name");
}
How can I make this work once my Patient object extends from NSManagedObject and uses #dynamic for the firstName and lastName properties?
Has anyone else run into this type of this with Core Data? Thanks.
You need to build a Core Data stack, either within each method or in -setUp and then tear it down. Using an NSInMemoryPersistentStore will keep things fast and in-memory for your unit tests. Add a #property (nonatomic,retain) NSManagedObjectContext *moc to your TestCase subclass. Then:
- (void)setUp {
NSManagedObjectModel *mom = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundleContainingXCDataModel]];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
STAssertTrue([psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:NULL] ? YES : NO, #"Should be able to add in-memory store");
self.moc = [[NSManagedObjectContext alloc] init];
self.moc.persistentStoreCoordinator = psc;
[mom release];
[psc release];
}
- (void)tearDown {
self.moc = nil;
}
Your test method then looks like:
- (void)test_full_name_returns_correct_string {
Patient *patient = [NSEntityDescription insertNewObjectForEntityForName:#"Person" inManagedObjectContext:self.moc];
patient.firstName = #"charlie";
patient.lastName = #"chaplin";
STAssertTrue([[patient fullName] isEqualToString:#"charlie chaplin"], #"should have matched full name");
}
assuming your entity is named Person. There was a memory leak in your version of the method, by the way; patient should be -release'd in the non-Core Data version (insertNewObjectForEntityForName:managedObjectContext: returns an autoreleased instance).
I used the answer above by Barry Wark, but I had to do some modifications to make it work with the current projects Xcode 5, iOS 7.
The property stayed the same:
#interface SIDataTest : XCTestCase
#property (nonatomic, retain) NSManagedObjectContext *moc;
#end
The setup had to actually had to change first of all to not release and secondly to provide a model URL.
- (void)setUp
{
[super setUp];
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"SimpleInvoice" withExtension:#"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
XCTAssertTrue([psc addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:nil options:nil error:NULL] ? YES : NO, #"Should be able to add in-memory store");
self.moc = [[NSManagedObjectContext alloc] init];
self.moc.persistentStoreCoordinator = psc;
}
Here is the example test case:
- (void)testCreateNew
{
Invoice *newInvoice = [NSEntityDescription insertNewObjectForEntityForName:#"Invoice" inManagedObjectContext:self.moc];
newInvoice.dueDate = [NSDate date];
NSString* title = [[NSString alloc] initWithFormat:#"Invoice %#", #112];
newInvoice.title = title;
// Save the context.
NSError *error = nil;
if (![self.moc 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.
XCTFail(#"Error saving in \"%s\" : %#, %#", __PRETTY_FUNCTION__, error, [error userInfo]);
}
XCTAssertFalse(self.moc.hasChanges,"All the changes should be saved");
}