I am getting some crashes that I have never experienced myself during test, development or usage.
I can see them on Fabric Dashboard, and it concerns the NSManagedObjectContext.
Here is the first call on StackTrace :
CDFavori* fav = [CDFavori favoriWithIndicatif:homeFavoriteIndicatif context:[MyAppDelegate mainContext]];
CDFavori is a class representing the CoreData object, which is extended in order to implement some methods (in order to fetch) :
+(CDFavori *)favoriWithIndicatif:(NSString*)indicatif context:(NSManagedObjectContext*)context
{
if (nil == indicatif || nil == context)
return nil;
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"CDFavori"];
[request setPredicate:[NSPredicate predicateWithFormat:#"indicatif LIKE %#", indicatif]];
NSError *error = nil;
NSArray *favoris = [context executeFetchRequest:request error:&error];
CDFavori *fav = nil;
if (nil != error) {
DDLogError(#"Error = %# (%#)", indicatif, error);
} else if (0 < [favoris count])
{
fav = [favoris objectAtIndex:0];
if (1 < [favoris count]) {
DDLogWarn(#"More than one object present in DB : %#", indicatif);
}
}
return favori;
}
The Crashes don't come from this method, it is just to give you some context.
The issue comes from the AppDelegate and the NSManagedObjectContext.
Here are my code for the Core Data methods :
+(NSManagedObjectContext*)mainContext
{
return ((MyAppDelegate*)[UIApplication sharedApplication].delegate).managedObjectContext;
}
The crashes are here :
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
EDIT - Just to mention the declarations :
in header :
#property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
#property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
in .m file:
#pragma mark - Core Data stack
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
EDIT After Answer :
Do you think something like this would be better ?
Remove this declaration :
#pragma mark - Core Data stack
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
And replace it with :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
_managedObjectModel = [[NSManagedObjectModel alloc] init];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] init];
}
This would be better ? With the same .h file.
But I have to change all my variables, and change the readonly properties ?
I believe that you have 3 separate issues:
ARC is conspiring against you
try replacing:
CDFavori* fav = [CDFavori favoriWithIndicatif:homeFavoriteIndicatif context:[MyAppDelegate mainContext]];
with
NSManagedObjectContext* context = [MyAppDelegate mainContext];
CDFavori* fav = [CDFavori favoriWithIndicatif:homeFavoriteIndicatif context:context];
I had a similar issue and this fixed it. The reason is that when the context is created and then pass directly as a parameter ARC release the context on the next line. Then the managedObject has no context and it crashes. If you first assign it to a local variable then ARC will keep the context around for the entire scope. This cannot happen in a debug environment because ARC behaves differently there.
You are not doing multithreading correctly
The next question is why is the context being release. While you haven't shown any wrong code, I suspect that this is happening very early in the application lifecycle and that there are multiple threads creating a the main context at the same time. So the first call creates a context and assigns it to _managedObjectContext and then a second context gets assigned and the first context gets release. (And it is not retained in the local scope so there is a crash).
In your core data setup you should ONLY access the _managedObjectContext variable on the main thread. I suggest adding a check at the beginning of the managedObjectContext method
if (![NSThread mainThread]) {
// log error to fabric
//[[Crashlytics sharedInstance] recordError:...];
return nil;
}
Lazily creating core-data can lead to errors
Also I would create the _managedObjectContext explicitly on launch in application:didFinishLaunchingWithOptions: and not create it lazily. When it is created lazily you don't know when exactly it will be created. And if it is created from a background thread your entire stack will be messed up. You have little to gain from doing it lazily as you are certainly going to create it in order to show anything to the user.
You could leave your code as is and simply add
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self managedObjectContext]; //force loading of context
Related
I would like to save the NSMutableArray to Core-Data when my application terminates/goes into background and I would like to load the NSMutableArray when my application launches/becomes active.
I don't have a very good understanding of Core-Data yet. This is my first time working with it. I've looked at a bunch of videos, tutorials, previous Stackoverflow questions and Apple's documentation. I think what I am trying to do falls under the Non-Standard Persistent Attributes chapter in Apple's Core-Data documentation.
I have set up an Entity called TableViewList and I have given it an attribute called List of type transformable.
Here is my AppDelegate.h and .m code. All advice would be wonderful.
AppDelegate.h
#import <UIKit/UIKit.h>
#import "TableViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property(nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
#property(nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property(nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
-(NSString *) applicationDocumentsDirectory;
#end
AppDelegate.m
#import <CoreData/CoreData.h>
#import "AppDelegate.h"
#import <UIKit/UIKit.h>
#interface AppDelegate ()
#end
#implementation AppDelegate
#synthesize managedObjectModel;
#synthesize managedObjectContext;
#synthesize persistentStoreCoordinator;
- (void)applicationDidEnterBackground:(UIApplication *)application {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *newContact;
newContact = [NSEntityDescription insertNewObjectForEntityForName:#"TableViewList" inManagedObjectContext:context];
NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:ListArray];
[newContact setValue:arrayData forKey:#"list"];
NSError *error = nil;
[context save:&error];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:[NSBundle allBundles]];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
NSURL *url = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent: #"App1.sqlite"];
[coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil];
managedObjectContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
managedObjectContext.persistentStoreCoordinator = coordinator;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"TableViewList" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *result = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(#"unable to execute fetch request");
NSLog(#"%#, %#", error, error.localizedDescription);
}
else
NSLog(#"%#",result);
}
The result array returns an empty array. I don't think I'm saving and fetching the array correctly. Thanks in advance for your help!
I used this link to implement NSCoding in my object.
OK there are several things to mention here:
In applicationDidEnterBackground, the first half of the method configures a new managed object context that you never use. Since you then get a different managed object context from the app delegate, you don't the one you create here, so the code that creates a new context can be deleted. You probably also want to use the app delegate's context in applicationDidBecomeActive, though what you have isn't necessarily wrong.
You don't ever save changes. You need to call save: on the managed object context to save data to the persistent store file.
In order to use a transformable property, the data you're saving must conform to NSCoding (because Core Data doesn't know how to transform arbitrary classes, and NSCoding is how you tell it what to do). NSArray does, but it's also important that everything in the array also conforms. If your custom class does that, you're OK. If not, you'll need to fix that to save the array or find a different way to save your data.
I don't believe that you're going to get a mutable array back, no matter what you do. Once you get saving and fetching working, you'll get an immutable array as the value of the list property. So you'll need to call mutableCopy if you need the array to be mutable.
I have a random bug that has plagued me for months that I simply can't figure out. I would say that it fails fewer than 1 in a 1000 times. I must have CoreData configured incorrectly but I can't figure out or recreate it. The basic gist is that I receive some information from the server and I am then updating a CoreData object in a background thread. The CoreData object is not immediately needed for the UI.
All of this is performed in DataService which has a reference to the NSManagedObjectContext that was originally created in the AppDelegate. Note: Anything that references [DataService sharedService] uses the AppDelegate.NSManagedObjectContext:
#interface DataService : NSObject {}
#property (nonatomic,strong) NSManagedObjectContext* managedObjectContext;
#end
When the server returns with data the updateProduct method is called:
#implementation DataService
+ (NSManagedObjectContext*) newObjectContext
{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; //step 1
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[context setPersistentStoreCoordinator:appDelegate.persistentStoreCoordinator];
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[appDelegate.managedObjectContext observeContext:context];
return context;
}
+(void) saveContext:(NSManagedObjectContext*) context
{
NSError *error = nil;
if (context != nil) {
if ([context hasChanges] && ![context save:&error]) {
// Handle Error
}
}
}
+(void) updateProduct: (Product*) product
{
if(product == nil)
return;
//run in background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void){
//create private managed object
NSManagedObjectContext *context = [DataService newObjectContext];
CoreDataProduct* coreProduct = [DataService product:product.productId withObjectContext:context];
if(product != nil)
{
//copy data over from product
coreProduct.text = product.text;
//ERROR HAPPENS HERE on save changes
[DataService saveContext:context];
}
//remove background context listening from main thread
[DataService.managedObjectContext stopObservingContext:context];
});
}
#end
I use the general NSManagedObjectContext+Helper.h category file that is floating around GitHub and my EXC_BAD_ACCESS KERN_INVALID_ADDRESS error happens in the [DataService.managedObjectContext mergeChangesFromNotification:(NSNotification *)notification] method which calls this
#implementation NSManagedObjectContext (Helper)
- (void) mergeChangesFromNotification:(NSNotification *)notification
{
//ERROR HAPPENS HERE
[self mergeChangesFromContextDidSaveNotification:notification];
}
#end
I cannot figure out why the mergeChangesFromContextDidSaveNotification method fails randomly. I think that the error is due to losing reference to the original shared managedObjectContext. Although if that were true, I guess I would expect the error to be in the updateProduct method and not in the category class.
I suppose that both the newObjectContext and the stopObservingContext methods reference the managedObjectContext on the background thread from the main thread. Since I'm creating a private managedObjectContext, do I even need to make the main thread shared context aware of the private context? If so, am I doing it incorrectly?
Thanks in advance for the help.
It appears because the new NSManagedObjectContext was being created on the background thread, the original/parent NSManagedObjectContext needed to be observed on the main thread. Once I changed observeContext to observeContextOnMainThread, this CoreData problem seems to have gone away. I hope this helps someone.
Here's my updated method:
+ (NSManagedObjectContext*) newObjectContext
{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; //step 1
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[context setPersistentStoreCoordinator:appDelegate.persistentStoreCoordinator];
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[appDelegate.managedObjectContext observeContextOnMainThread:context];
return context;
}
I know that the error occurs on this line as the app works just fine with this line commented out:
controller.managedObjectContext = self.managedObjectContext;
the error is:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewController setManagedObjectContext:]: unrecognized selector sent to instance 0x7490da0'
the fibroMappAppDelegate.h
//
// fibroMappAppDelegate.h
// fibromapp
//
// Created by jamie mcallister on 09/08/2013.
// Copyright (c) 2013 Jamie McAllister. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface fibroMappAppDelegate : UIResponder <UIApplicationDelegate>
#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;
#end
and the fibroMappAppDelegate.m
//
// fibroMappAppDelegate.m
// fibromapp
//
// Created by jamie mcallister on 09/08/2013.
// Copyright (c) 2013 Jamie McAllister. All rights reserved.
//
#import "fibroMappAppDelegate.h"
#import "fibroMappMasterViewController.h"
#implementation fibroMappAppDelegate
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
fibroMappMasterViewController *controller = (fibroMappMasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
return YES;
}
- (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:#"fibromapp" 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:#"fibromapp.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
What that means is that when you do this:
controller.managedObjectContext = self.managedObjectContext;
The controller does not have a managedObjectContext attribute, so it's impossible to assign anything to it. You didn't post the code of controller, so I don't know exactly what it looks like, but the error message says that it's a UITableViewController. If you want to fix this problem the right way, you'll need to give controller a managedObjectContext property so that you can make this assignment work.
All you have to do is remove this line:
controller.managedObjectContext = self.managedObjectContext;
And whenever you need the managed object context in a view use:
[(fibroMappAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
The error indicates that you are using a non-subclassed UITableViewController and think you are using a subclass that has a property called managedObjectContext. Check your storyboard, xib or code and see where this is happening.
Since you are trying to use dependency injection (a very good thing btw) then I would suggest checking where you are creating the controller and change it so that it is using a subclass of UITableViewController that has the correct property.
hi i have this error while loading my app, the simulator dont gives a fail lounch, but this hapen when loading app.
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
MY appdelagte.h:
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#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;
#end
And appdelegate.m is:
#import "AppDelegate.h"
#import "RolesTVC.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize managedObjectContext = __managedObjectContext;
#synthesize managedObjectModel = __managedObjectModel;
#synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
RolesTVC *controller = (RolesTVC *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
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:#"Model" 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:#"StaffManager.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
im using tabviews and in 1 view i have coredata implemented
EDIT:
this apeares in the Debug:
2013-05-25 12:08:57.933 Staff[3151:17603] -[UITabBarController topViewController]: unrecognized selector sent to instance 0xd118160
2013-05-25 12:08:57.935 Staff[3151:17603] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITabBarController topViewController]: unrecognized selector sent to instance 0xd118160'
*** First throw call stack:
(0x1a5a012 0x1717e7e 0x1ae54bd 0x1a49bbc 0x1a4994e 0x1f18 0x659157 0x659747 0x65a94b 0x66bcb5 0x66cbeb 0x65e698 0x2146df9 0x2146ad0 0x19cfbf5 0x19cf962 0x1a00bb6 0x19fff44 0x19ffe1b 0x65a17a 0x65bffc 0x1e3d 0x1d65)
libc++abi.dylib: terminate called throwing an exception
(lldb)
The window's root view controller is a UITabBarController. Perhaps, you want to do something with the selectedViewController of the tab bar controller.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = (UINavigationController *)tabBarController.selectedViewController;
RolesTVC *controller = (RolesTVC *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
return YES;
}
I created an iOS project and a managed object model (Model.xcdatamodeld) with one entity. In application:didFinishLaunchingWithOptions: I want to test if the managed object model exists, however I am getting nil. Do I have to do something special to create the managed object context after I create the managed object model?
Any suggestions on what I may be doing wrong?
This is the interface
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
}
#property (nonatomic, strong, readonly) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, strong, readonly) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, strong, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#end
This is the implementation file
#import "AppDelegate.h"
#import "RootViewController.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
#synthesize navigationController = _navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (![self managedObjectContext])
{
NSLog(#"Does not exist");
}
return YES;
}
Old Xcode generated appropriate code for CoreData by itself. Posting it below:
#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:#"iDocs" 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:#"iDocs.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.
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;
}