An instance of NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext? - iphone

I'm getting this error while trying to use Core Data:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext'
I traced the error back to this in my modal view controller which contains the Table View:
- (void)setupFetchedResultsController
{
NSString *entityName = #"Location";
NSLog(#"Setting up a Fetched Results Controller for the Entity named %#", entityName);
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
// ERROR OCCURS IN THE LINE BELOW vvv
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
[self performFetch];
}
This is what I have in my AppDelegate:
- (void)setupFetchedResultsController
{
NSString *entityName = #"Location";
NSLog(#"Setting up a Fetched Results Controller for the Entity named %#", entityName);
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
[self.fetchedResultsController performFetch:nil];
}
I get no errors there, and here's more of the App Delegate:
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
{
// Using abort() right now just for development
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
#pragma mark - Core Data stack
- (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:#"Model" withExtension:#"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil)
{
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"Forecaster.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
and in my Model.xcdatamodeid:
Any help would be great! Thanks!

Here is the Method:
- (void)setupFetchedResultsController
{
NSManagedObjectContext *moc = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:#"Location" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
// Deal with error...
}
else
{
// your data is in array
}
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"FailedBankInfo"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (FailedBankInfo *info in fetchedObjects) {
NSLog(#"Name: %#", info.name);
FailedBankDetails *details = info.details;
NSLog(#"Zip: %#", details.zip);
}

Related

Table view and Predicates

I have a table view with 40 objects. I have to filter them by gender when Click in a UISegment (male, female and both). It seems to be working, but table view does not refresh. Please any help would be appreciatte.
-(void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"People";
[self loadall];
[[NSBundle mainBundle] loadNibNamed:#"FilterSortView" owner:self options:nil];
self.filterControl.selectedSegmentIndex = -1;
[self.filterControl addTarget:self action:#selector( changeSegge ) forControlEvents:UIControlEventValueChanged];
}
#
My second method to filter by gender
- (void)changeSegge
{
NSEntityDescription *personEntity = [NSEntityDescription entityForName:#"Person"
inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:personEntity];
NSError *error = nil;
self.people = [self.managedObjectContext executeFetchRequest:request error:&error];
if (error)
{
[NSException raise:NSInternalInconsistencyException format:#"Could not fetch Core Data records: %#",error];
}
if(filterControl.selectedSegmentIndex == 0){
NSPredicate *predicatem =[NSPredicate predicateWithFormat:#"gender == %#", #"m" ];
request.predicate=predicatem;
[self.tableView reloadData];
[request release];
NSLog(#"button 1");
}
Thanks a lot.
You forgot to fill people array after predicate set to fetch request.
Here is updated changeSegge method:
- (void)changeSegge
{
NSEntityDescription *personEntity = [NSEntityDescription entityForName:#"Person"
inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:personEntity];
NSError *error = nil;
self.people = [self.managedObjectContext executeFetchRequest:request error:&error];
if (error)
{
[NSException raise:NSInternalInconsistencyException format:#"Could not fetch Core Data >records: %#",error];
}
if(filterControl.selectedSegmentIndex == 0){
NSPredicate *predicatem =[NSPredicate predicateWithFormat:#"gender == %#", #"m" ];
request.predicate=predicatem;
self.people = [self.managedObjectContext executeFetchRequest:request error:&error];
[self.tableView reloadData];
[request release];
NSLog(#"button 1");
}

Syncing Data with Parse, not downloading data

I have been following the How To Synchronize Core Data with a Web Service – Part 1 from RayWenderlinch.com I am trying to customize it to my application and have an issue with the actual downloading of the data from Parse using AFNetworking
The application should connect to parse, see the two classes "Club" and "IronSet" check and see if there are and new records (or on initial run, grab everything) and download only the newly added stuff.
Then it will save those records to core data, then delete the files from the Cache/JSONRecords/Club(or IronSet). It seems I am never actually grabbing the data from Parse, although it is connecting successfully, and does not throw an error until it goes to delete the the files from the Cache.
I am getting the "All operations completed" indicating the SyncEngine should be complete with the download in the downloadDataForRegisteredObjects
Error
2013-08-26 19:39:03.981 WGT Golf Calculator[3287:c07] All operations completed
2013-08-26 19:39:03.991 WGT Golf Calculator[3287:c07] Unable to delete JSON records at Club -- file://localhost/Users/**/Library/Application%20Support/iPhone%20Simulator/6.1/Applications/4B72F57E-264D-44F7-981D-3D921B0CC2A4/Library/Caches/JSONRecords/, reason Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn’t be completed. (Cocoa error 4.)" UserInfo=0x75610f0 {NSUnderlyingError=0x75615e0 "The operation couldn’t be completed. No such file or directory", NSFilePath=/Users/**/Library/Application Support/iPhone Simulator/6.1/Applications/4B72F57E-264D-44F7-981D-3D921B0CC2A4/Library/Caches/JSONRecords/Club, NSUserStringVariant=(
Remove
)}
MLVAppDelegate.m
#import "MLVAppDelegate.h"
#import "MLVSyncEngine.h"
#import "Club.h"
#import "IronSet.h"
#implementation MLVAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[MLVSyncEngine sharedEngine] registerNSManagedObjectClassToSync:[Club class]];
[[MLVSyncEngine sharedEngine] registerNSManagedObjectClassToSync:[IronSet class]];
return YES;
}
MLVAFParseAPIClient.h
#import "AFHTTPClient.h"
#interface MLVAFParseAPIClient : AFHTTPClient
+ (MLVAFParseAPIClient *)sharedClient;
- (NSMutableURLRequest *)GETRequestForClass:(NSMutableString *)className parameters:(NSDictionary *)parameters;
- (NSMutableURLRequest *)GETRequestForAllRecordsOfClass:(NSString *)className updatedAfterDate:(NSDate *)updatedDate;
#end
MLVAFParseAPIClient.m
#import "MLVAFParseAPIClient.h"
#import "AFJSONRequestOperation.h"
static NSString * const kSDFParseAPIBaseURLString = #"https://api.parse.com/1/";
static NSString * const kSDFParseAPIApplicationId = #"APP ID REMOVED";
static NSString * const kSDFParseAPIKey = #"API KEY REMOVED";
#implementation MLVAFParseAPIClient
+ (MLVAFParseAPIClient *)sharedClient
{
static MLVAFParseAPIClient *sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{sharedClient = [[MLVAFParseAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kSDFParseAPIBaseURLString]];
});
return sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (self) {
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setParameterEncoding:AFJSONParameterEncoding];
[self setDefaultHeader:#"X-Parse-Application-Id" value:kSDFParseAPIApplicationId];
[self setDefaultHeader:#"X-Parse-REST-API-Key" value:kSDFParseAPIKey];
}
return self;
}
- (NSMutableURLRequest *)GETRequestForClass:(NSMutableString *)className parameters:(NSDictionary *)parameters
{
NSMutableURLRequest *request = nil;
request = [self requestWithMethod:#"GET" path:[NSString stringWithFormat:#"classes/%#", className] parameters:parameters ];
return request;
}
- (NSMutableURLRequest *)GETRequestForAllRecordsOfClass:(NSString *)className updatedAfterDate:(NSDate *)updatedDate
{
NSMutableURLRequest *request = nil;
NSDictionary *parameters = nil;
if (updatedDate) {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.'999Z'"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
NSString *jsonString = [NSString stringWithFormat:#"{\"updatedAt\":{\"$gte\":{\"__type\":\"Date\",\"iso\":\"%#\"}}}", [dateFormatter stringFromDate:updatedDate]];
parameters = [NSDictionary dictionaryWithObject:jsonString forKey:#"where"];
}
request = [self GETRequestForClass:className parameters:parameters];
return request;
}
#end
MLVCoreDataController.m
#import "MLVCoreDataController.h"
#interface MLVCoreDataController ()
#property (strong, nonatomic) NSManagedObjectContext *masterManagedObjectContext;
#property (strong, nonatomic) NSManagedObjectContext *backgroundManagedObjectContext;
#property (strong, nonatomic) NSManagedObjectModel *managedObjectModel;
#property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#end
#implementation MLVCoreDataController
#synthesize masterManagedObjectContext = _masterManagedObjectContext;
#synthesize backgroundManagedObjectContext = _backgroundManagedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
+ (id)sharedInstance {
static dispatch_once_t once;
static MLVCoreDataController *sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
#pragma mark - Core Data stack
// Used to propegate saves to the persistent store (disk) without blocking the UI
- (NSManagedObjectContext *)masterManagedObjectContext {
if (_masterManagedObjectContext != nil) {
return _masterManagedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_masterManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_masterManagedObjectContext performBlockAndWait:^{
[_masterManagedObjectContext setPersistentStoreCoordinator:coordinator];
}];
}
return _masterManagedObjectContext;
}
// Return the NSManagedObjectContext to be used in the background during sync
- (NSManagedObjectContext *)backgroundManagedObjectContext {
if (_backgroundManagedObjectContext != nil) {
return _backgroundManagedObjectContext;
}
NSManagedObjectContext *masterContext = [self masterManagedObjectContext];
if (masterContext != nil) {
_backgroundManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_backgroundManagedObjectContext performBlockAndWait:^{
[_backgroundManagedObjectContext setParentContext:masterContext];
}];
}
return _backgroundManagedObjectContext;
}
// Return the NSManagedObjectContext to be used in the background during sync
- (NSManagedObjectContext *)newManagedObjectContext {
NSManagedObjectContext *newContext = nil;
NSManagedObjectContext *masterContext = [self masterManagedObjectContext];
if (masterContext != nil) {
newContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[newContext performBlockAndWait:^{
[newContext setParentContext:masterContext];
}];
}
return newContext;
}
- (void)saveMasterContext {
[self.masterManagedObjectContext performBlockAndWait:^{
NSError *error = nil;
BOOL saved = [self.masterManagedObjectContext save:&error];
if (!saved) {
// do some real error handling
NSLog(#"Could not save master context due to %#", error);
}
}];
}
- (void)saveBackgroundContext {
[self.backgroundManagedObjectContext performBlockAndWait:^{
NSError *error = nil;
BOOL saved = [self.backgroundManagedObjectContext save:&error];
if (!saved) {
// do some real error handling
NSLog(#"Could not save background context due to %#", error);
}
}];
}
// 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:#"WGTCalculator" 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:#"WGTCalcul.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];
}
#end
MLVSyncEngine.h
#import <Foundation/Foundation.h>
typedef enum {
MLVObjectSynced = 0,
MLVObjectCreated,
MLVObjectDeleted,
} MLVObjectSyncStatus;
#interface MLVSyncEngine : NSObject
#property (atomic, readonly) BOOL syncInProgress;
+ (MLVSyncEngine *)sharedEngine;
- (void)registerNSManagedObjectClassToSync:(Class)aClass;
- (void)startSync;
#end
MLVSyncEngine.m
#import "MLVSyncEngine.h"
#import "MLVCoreDataController.h"
#import "MLVAFParseAPIClient.h"
#import "AFHTTPRequestOperation.h"
#import "AFJSONRequestOperation.h"
NSString * const kMLVSyncEngineInitialCompleteKey = #"MLVSyncEngineInitialSyncCompleted";
NSString * const kMLVSyncEngineSyncCompletedNotificationName = #"MLVSyncEngineSyncCompleted";
#interface MLVSyncEngine ()
#property (nonatomic, strong) NSMutableArray *registeredClassesToSync;
#property (nonatomic, strong) NSDateFormatter *dateFormatter;
#end
#implementation MLVSyncEngine
#synthesize registeredClassesToSync = _registeredClassesToSync;
#synthesize syncInProgress = _syncInProgress;
#synthesize dateFormatter = _dateFormatter;
+ (MLVSyncEngine *)sharedEngine
{
static MLVSyncEngine *sharedEngine = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedEngine = [[MLVSyncEngine alloc] init];
});
return sharedEngine;
}
- (void)registerNSManagedObjectClassToSync:(Class)aClass
{
if (!self.registeredClassesToSync) {
self.registeredClassesToSync = [NSMutableArray array];
}
if ([aClass isSubclassOfClass:[NSManagedObject class]]) {
if (![self.registeredClassesToSync containsObject:NSStringFromClass(aClass)]) {
[self.registeredClassesToSync addObject:NSStringFromClass(aClass)];
} else {
NSLog(#"Unable to register %# as it is already registered", NSStringFromClass(aClass));
}
} else {
NSLog(#"Unable to reguster %# as it is not a subclass of NSManagedObject", NSStringFromClass(aClass));
}
}
- (BOOL)initialSyncComplete{
return [[[NSUserDefaults standardUserDefaults] valueForKey:kMLVSyncEngineInitialCompleteKey] boolValue];
}
- (void)setInitialSyncCompleted{
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:YES] forKey:kMLVSyncEngineInitialCompleteKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)executeSyncCompletedOperations {
dispatch_async(dispatch_get_main_queue(), ^{
[self setInitialSyncCompleted];
NSError *error = nil;
[[MLVCoreDataController sharedInstance] saveBackgroundContext];
if (error) {
NSLog(#"Error saving background context after creating objects on server: %#", error);
}
[[MLVCoreDataController sharedInstance] saveMasterContext];
[[NSNotificationCenter defaultCenter]
postNotificationName:kMLVSyncEngineSyncCompletedNotificationName
object:nil];
[self willChangeValueForKey:#"syncInProgress"];
_syncInProgress = NO;
[self didChangeValueForKey:#"syncInProgress"];
});
}
- (void)startSync
{
if (!self.syncInProgress) {
[self willChangeValueForKey:#"syncInProgress"];
_syncInProgress = YES;
[self didChangeValueForKey:#"syncInProgress"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{[self downloadDataForRegisteredObjects:YES];
});
}
}
- (NSDate *)mostRecentUpdatedAtDateForEntityWithName:(NSString *)entityName {
__block NSDate *date = nil;
//
// Create a new fetch request for the specified entity
//
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
//
// Set the sort descriptors on the request to sort by updatedAt in descending order
//
[request setSortDescriptors:[NSArray arrayWithObject:
[NSSortDescriptor sortDescriptorWithKey:#"updatedAt" ascending:NO]]];
//
// You are only interested in 1 result so limit the request to 1
//
[request setFetchLimit:1];
[[[MLVCoreDataController sharedInstance] backgroundManagedObjectContext] performBlockAndWait:^{
NSError *error = nil;
NSArray *results = [[[MLVCoreDataController sharedInstance] backgroundManagedObjectContext] executeFetchRequest:request error:&error];
if ([results lastObject]) {
//
// Set date to the fetched result
//
date = [[results lastObject] valueForKey:#"updatedAt"];
}
}];
return date;
}
- (void)newManagedObjectWithClassName:(NSString *)className forRecord:(NSDictionary *)record {
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:className inManagedObjectContext:[[MLVCoreDataController sharedInstance] backgroundManagedObjectContext]];
[record enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[self setValue:obj forKey:key forManagedObject:newManagedObject];
}];
[record setValue:[NSNumber numberWithInt:MLVObjectSynced] forKey:#"syncStatus"];
}
- (void)updateManagedObject:(NSManagedObject *)managedObject withRecord:(NSDictionary *)record {
[record enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[self setValue:obj forKey:key forManagedObject:managedObject];
}];
}
- (void)setValue:(id)value forKey:(NSString *)key forManagedObject:(NSManagedObject *)managedObject {
if ([key isEqualToString:#"createdAt"] || [key isEqualToString:#"updatedAt"]) {
NSDate *date = [self dateUsingStringFromAPI:value];
[managedObject setValue:date forKey:key];
} else if ([value isKindOfClass:[NSDictionary class]]) {
if ([value objectForKey:#"__type"]) {
NSString *dataType = [value objectForKey:#"__type"];
if ([dataType isEqualToString:#"Date"]) {
NSString *dateString = [value objectForKey:#"iso"];
NSDate *date = [self dateUsingStringFromAPI:dateString];
[managedObject setValue:date forKey:key];
} else if ([dataType isEqualToString:#"File"]) {
NSString *urlString = [value objectForKey:#"url"];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *dataResponse = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
[managedObject setValue:dataResponse forKey:key];
} else {
NSLog(#"Unknown Data Type Received");
[managedObject setValue:nil forKey:key];
}
}
} else {
[managedObject setValue:value forKey:key];
}
}
- (NSArray *)managedObjectsForClass:(NSString *)className withSyncStatus:(MLVObjectSyncStatus)syncStatus {
__block NSArray *results = nil;
NSManagedObjectContext *managedObjectContext = [[MLVCoreDataController sharedInstance] backgroundManagedObjectContext];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:className];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"syncStatus = %d", syncStatus];
[fetchRequest setPredicate:predicate];
[managedObjectContext performBlockAndWait:^{
NSError *error = nil;
results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
}];
return results;
}
- (NSArray *)managedObjectsForClass:(NSString *)className sortedByKey:(NSString *)key usingArrayOfIds:(NSArray *)idArray inArrayOfIds:(BOOL)inIds {
__block NSArray *results = nil;
NSManagedObjectContext *managedObjectContext = [[MLVCoreDataController sharedInstance] backgroundManagedObjectContext];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:className];
NSPredicate *predicate;
if (inIds) {
predicate = [NSPredicate predicateWithFormat:#"objectId IN %#", idArray];
} else {
predicate = [NSPredicate predicateWithFormat:#"NOT (objectId IN %#)", idArray];
}
[fetchRequest setPredicate:predicate];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:
[NSSortDescriptor sortDescriptorWithKey:#"objectId" ascending:YES]]];
[managedObjectContext performBlockAndWait:^{
NSError *error = nil;
results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
}];
return results;
}
- (void)downloadDataForRegisteredObjects:(BOOL)useUpdatedAtDate {
NSMutableArray *operations = [NSMutableArray array];
for (NSString *className in self.registeredClassesToSync) {
NSDate *mostRecentUpdatedDate = nil;
if (useUpdatedAtDate) {
mostRecentUpdatedDate = [self mostRecentUpdatedAtDateForEntityWithName:className];
}
NSMutableURLRequest *request = [[MLVAFParseAPIClient sharedClient]
GETRequestForAllRecordsOfClass:className
updatedAfterDate:mostRecentUpdatedDate];
AFHTTPRequestOperation *operation = [[MLVAFParseAPIClient sharedClient] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([responseObject isKindOfClass:[NSDictionary class]]) {
[self writeJSONResponse:responseObject toDiskForClassWithName:className];
NSLog(#"Response for %#: %#", className, responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Request for class %# failed with error: %#", className, error);
}];
[operations addObject:operation];
}
[[MLVAFParseAPIClient sharedClient] enqueueBatchOfHTTPRequestOperations:operations progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) {
} completionBlock:^(NSArray *operations) {
NSLog(#"All operations completed");
[self processJSONDataRecordsIntoCoreData];
}];
}
- (void)processJSONDataRecordsIntoCoreData {
NSManagedObjectContext *managedObjectContext = [[MLVCoreDataController sharedInstance] backgroundManagedObjectContext];
//
// Iterate over all registered classes to sync
//
for (NSString *className in self.registeredClassesToSync) {
if (![self initialSyncComplete]) {
NSDictionary *JSONDictionary = [self JSONDictionaryForClassWithName:className];
NSArray *records = [JSONDictionary objectForKey:#"results"];
for (NSDictionary *record in records) {
[self newManagedObjectWithClassName:className forRecord:record];
}
} else {
NSArray *downloadedRecords = [self JSONDataRecordsForClass:className sortedByKey:#"objectId"];
if ([downloadedRecords lastObject]) {
NSArray *storedRecords = [self managedObjectsForClass:className sortedByKey:#"objectId" usingArrayOfIds:[downloadedRecords valueForKey:#"objectId"] inArrayOfIds:YES];
int currentIndex = 0;
for (NSDictionary *record in downloadedRecords) {
NSManagedObject *storedManagedObject = nil;
if ([storedRecords count] > currentIndex) {
storedManagedObject = [storedRecords objectAtIndex:currentIndex];
}
if ([[storedManagedObject valueForKey:#"objectId"] isEqualToString:[record valueForKey:#"objectId"]]) {
[self updateManagedObject:[storedRecords objectAtIndex:currentIndex] withRecord:record];
} else {
[self newManagedObjectWithClassName:className forRecord:record];
}
currentIndex++;
}
}
}
[managedObjectContext performBlockAndWait:^{
NSError *error = nil;
if (![managedObjectContext save:&error]) {
NSLog(#"Unable to save context for class %#", className);
}
}];
[self deleteJSONDataRecordsForClassWithName:className];
[self executeSyncCompletedOperations];
}
}
- (void)initializeDateFormatter {
if (!self.dateFormatter) {
self.dateFormatter = [[NSDateFormatter alloc] init];
[self.dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
[self.dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
}
}
- (NSDate *)dateUsingStringFromAPI:(NSString *)dateString {
[self initializeDateFormatter];
dateString = [dateString substringWithRange:NSMakeRange(0, [dateString length]-5)];
return [self.dateFormatter dateFromString:dateString];
}
- (NSString *)dateStringForAPIUsingDate:(NSDate *)date {
[self initializeDateFormatter];
NSString *dateString = [self.dateFormatter stringFromDate:date];
dateString = [dateString substringWithRange:NSMakeRange(0, [dateString length]-1)];
dateString = [dateString stringByAppendingFormat:#".000Z"];
return dateString;
}
#pragma mark - File Management
- (NSURL *)applicationCacheDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSURL *)JSONDataRecordsDirectory{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *url = [NSURL URLWithString:#"JSONRecords/" relativeToURL:[self applicationCacheDirectory]];
NSError *error = nil;
if (![fileManager fileExistsAtPath:[url path]]) {
[fileManager createDirectoryAtPath:[url path] withIntermediateDirectories:YES attributes:nil error:&error];
}
return url;
}
-(void)writeJSONResponse:(id)response toDiskForClassWithName:(NSString *)className{
NSURL *fileURL = [NSURL URLWithString:className relativeToURL:[self JSONDataRecordsDirectory]] ;
if (![(NSDictionary *)response writeToFile:[fileURL path] atomically:YES]) {
NSLog(#"Error saving response to disk, will attempt to remove NSNull values and try again.");
//remove NSNulls and try again...
NSArray *records = [response objectForKey:#"results"];
NSMutableArray *nullFreeRecords = [NSMutableArray array];
for (NSDictionary *record in records) {
NSMutableDictionary *nullFreeRecord = [NSMutableDictionary dictionaryWithDictionary:record];
[record enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([obj isKindOfClass:[NSNull class]]) {
[nullFreeRecord setValue:nil forKey:key];
}
}];
[nullFreeRecords addObject:nullFreeRecord];
}
NSDictionary *nullFreeDictionary = [NSDictionary dictionaryWithObject:nullFreeRecords forKey:#"results"];
if (![nullFreeDictionary writeToFile:[fileURL path] atomically:YES]) {
NSLog(#"Failed all attempts to save response to disk: %#", response);
}
}
}
- (void)deleteJSONDataRecordsForClassWithName:(NSString *)className {
NSURL *url = [NSURL URLWithString:className relativeToURL:[self JSONDataRecordsDirectory]];
NSError *error = nil;
BOOL deleted = [[NSFileManager defaultManager] removeItemAtURL:url error:&error];
if (!deleted) {
NSLog(#"Unable to delete JSON records at %#, reason %#", url, error);
}
}
- (NSDictionary *)JSONDictionaryForClassWithName:(NSString *)className {
NSURL *fileURL = [NSURL URLWithString:className relativeToURL:[self JSONDataRecordsDirectory]];
return [NSDictionary dictionaryWithContentsOfURL:fileURL];
}
- (NSArray *)JSONDataRecordsForClass:(NSString *)className sortedByKey:(NSString *)key {
NSDictionary *JSONDictionary = [self JSONDictionaryForClassWithName:className];
NSArray *records = [JSONDictionary objectForKey:#"results"];
return [records sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:key ascending:YES]]];
}
#end
Honestly, if your data model is that simple, and you're deleting the local persistent store / cache on every load, you probably would be much better off not using Core Data.
Keep it simple by loading data as needed. Save a cache using NSCoding, to be loaded initially as a placeholder, while the app waits for new information to be downloaded.
So it turns out the answer was pretty straight forward, the tutorial uses an older Version of AFNetworking where AFHTTPRequestOperation can download the data but does not see it as JSON.
AFHTTPRequestOperation *operation = [[MLVAFParseAPIClient sharedClient] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([responseObject isKindOfClass:[NSDictionary class]]) {
[self writeJSONResponse:responseObject toDiskForClassWithName:className];
NSLog(#"Response for %#: %#", className, responseObject);
}
}
Needed to be updated with AFJSONRequestOperation
AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest: request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
NSDictionary * responseObject = (NSDictionary * )JSON;
if ([responseObject isKindOfClass:[NSDictionary class]]) {
NSLog(#"Response for %#: %#", className, responseObject);
[self writeJSONResponse:responseObject toDiskForClassWithName:className];

Core Data Crash during Save without error. Only one Context and only main thread

I'm simply trying to delete three nsmanagedobject from an entity, as i already do in other application,where all went ok. This time core data seems to crash during save, there's no error, i'm using the app delegate context in all the app, so i think that isn't a multiple context problem... I have tried a check with [NSThread isMainThread] , during the save i'm in the main thread, so isn't a threading problem... What's wrong in my code?
-(void)EraseStore{
if (contesto == nil) {
contesto = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
NSError *error=nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Store" inManagedObjectContext:contesto];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [contesto executeFetchRequest:fetchRequest error:&error];
NSString *Store1=[NSString stringWithFormat:#"%#",#"55"];
NSString *Store2=[NSString stringWithFormat:#"%#",#"63"];
NSString *Store3=[NSString stringWithFormat:#"%#",#"11"];
for (int i=0; i<[fetchedObjects count]; i++) {
NSString *StoreId=[NSString stringWithFormat:#"%#",[[fetchedObjects objectAtIndex:i]valueForKey:#"id"]];
if ([StoreId isEqualToString:Store1] || [StoreId isEqualToString:Store2]|| [StoreId isEqualToString:Store3]) {
[contesto deleteObject:[fetchedObjects objectAtIndex:i]];
}
}
NSError *error1 = nil;
BOOL success = [contesto save:&error1];
if (!success) {
NSLog(#"Unresolved error2 %#, %#", error1, [error1 userInfo]);
}
else{
NSLog(#"saved");
}
}
How I create my context:
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext_ != nil) {
return managedObjectContext_;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext_ = [[NSManagedObjectContext alloc] init];
[managedObjectContext_ setPersistentStoreCoordinator:coordinator];
}
return managedObjectContext_;
}
The error message I am getting:
Unresolved error2 Error Domain=NSCocoaErrorDomain Code=133020 "The operation couldn’t be completed. (Cocoa error 133020.)" UserInfo=0x23cf00 {conflictList=( "NSMergeConflict (0x23cdc0) for NSManagedObject (0x234960) with objectID '0x2da8b0 ' with oldVersion = 1 and newVersion = 2 and old object snapshot =....
EDIT
In database structure i haven't set any relationship between tables.

Core Data to SQL not working

I have been trying like hell to figure out how to establish a connection between my Core Data & my SQL database. The database isn't pre-populated, but it will be used amongst many different users when it's launched.
I have gone through the Core Data & iCloud classes provided by Stanford three times to no avail. I have also looked throughly into SQLite/SQL relational databases in iOS to no avail. The only other option I have is to come on here, post all the code I can, and pray that somebody will have an answer for me. So here it goes...
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();
}
}
}
#pragma mark - Core Data stack
- (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 = [self applicationDocumentsDirectory];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"shindy.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
- (NSURL *)applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"shindy.sqlite"];
return [NSURL fileURLWithPath:path];
}
HomeViewController.m
- (void)setupFetchedResultsController
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Shindy"];
request.sortDescriptors = [NSArray arrayWithObjects:
[NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:#"dateAndTime" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:#"photo" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:#"details" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:#"timePosted" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:#"location" ascending:YES],
nil];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.shindyDatabase.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
}
- (void)fetchShindyDataIntoDocument:(UIManagedDocument *)document
{
dispatch_queue_t fetchQ = dispatch_queue_create("Shindy Fetcher", nil);
dispatch_async(fetchQ, ^{
NSArray *shindys = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
NSLog(#"shindys = %#", shindys);
[document.managedObjectContext performBlock:^{
for (NSDictionary *shindyInfo in shindys) {
[Shindy shindyWithShindyDBInfo:shindyInfo inManagedObjectContext:document.managedObjectContext];
NSLog(#"fire");
}
}];
});
}
- (void)useDocument
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"shindy.sqlite"];
if (![[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil]) {
[self.shindyDatabase saveToURL:self.shindyDatabase.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self setupFetchedResultsController];
[self fetchShindyDataIntoDocument:self.shindyDatabase];
}];
} else if (self.shindyDatabase.documentState == UIDocumentStateClosed) {
[self.shindyDatabase openWithCompletionHandler:^(BOOL success) {
[self setupFetchedResultsController];
}];
} else if (self.shindyDatabase.documentState == UIDocumentStateNormal) {
[self setupFetchedResultsController];
}
}
- (void)setShindyDatabase:(UIManagedDocument *)shindyDatabase
{
[self useDocument];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self fetchShindyDataIntoDocument:self.shindyDatabase];
if (!self.shindyDatabase) {
[self setShindyDatabase:self.shindyDatabase];
}
}
Shindy+ShindyDB.m
+ (Shindy *)shindyWithShindyDBInfo:(NSDictionary *)shindyInfo
inManagedObjectContext:(NSManagedObjectContext *)context
{
Shindy *shindy = nil;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Shindy"];
NSSortDescriptor *dateAndTimeSort = [NSSortDescriptor sortDescriptorWithKey:#"dateAndTime" ascending:YES];
NSSortDescriptor *detailsSort = [NSSortDescriptor sortDescriptorWithKey:#"details" ascending:YES];
NSSortDescriptor *locationSort = [NSSortDescriptor sortDescriptorWithKey:#"location" ascending:YES];
NSSortDescriptor *nameSort = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
NSSortDescriptor *photoSort = [NSSortDescriptor sortDescriptorWithKey:#"photo" ascending:YES];
NSSortDescriptor *timePostedSort = [NSSortDescriptor sortDescriptorWithKey:#"timePosted" ascending:YES];
// title
request.sortDescriptors = [NSArray arrayWithObjects:dateAndTimeSort, detailsSort, locationSort, nameSort, photoSort, timePostedSort, nil];
NSError *error = nil;
NSArray *matches = [context executeFetchRequest:request error:&error];
if (!matches || ([matches count] > 1)) {
// handle error
} else if ([matches count] == 0) {
shindy = [NSEntityDescription insertNewObjectForEntityForName:#"Shindy" inManagedObjectContext:context];
shindy.dateAndTime = [shindyInfo objectForKey:#"dateAndTime"];
shindy.details = [shindyInfo objectForKey:#"details"];
shindy.location = [shindyInfo objectForKey:#"location"];
shindy.name = [shindyInfo objectForKey:#"name"];
shindy.photo = [shindyInfo objectForKey:#"photo"];
shindy.timePosted = [shindyInfo objectForKey:#"timePosted"];
// title
// Guestlist? The rest?
// Use below for reference
shindy.whoseShindy = [User userWithName:[shindyInfo objectForKey:#"whoseShindy"] inManagedObjectContext:context];
} else {
shindy = [matches lastObject];
}
shindy = [NSEntityDescription insertNewObjectForEntityForName:#"Shindy" inManagedObjectContext:context];
shindy.dateAndTime = [shindyInfo objectForKey:#"dateAndTime"];
shindy.details = [shindyInfo objectForKey:#"details"];
shindy.location = [shindyInfo objectForKey:#"location"];
shindy.name = [shindyInfo objectForKey:#"name"];
shindy.photo = [shindyInfo objectForKey:#"photo"];
shindy.timePosted = [shindyInfo objectForKey:#"timePosted"];
return shindy;
}
AddShindyViewController.m
- (void)saveShindyToDatabase
{
NSArray *shindys = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
[self.shindyDatabase.managedObjectContext performBlock:^{
for (NSDictionary *shindyInfo in shindys) {
[Shindy shindyWithShindyDBInfo:shindyInfo inManagedObjectContext:self.shindyDatabase.managedObjectContext];
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
// url = [url URLByAppendingPathComponent:#"Default Shindy Database"];
self.shindyDatabase = [[UIManagedDocument alloc] initWithFileURL:url];
[self.shindyDatabase setValue:self.detailView.text forKey:#"details"];
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
self.name = user.name;
self.photo.profileID = user.id;
self.username = user.username;
}
}];
}
[self.shindyDatabase setValue:self.name forKey:#"name"];
[self.shindyDatabase setValue:self.photo forKey:#"photo"];
[self.shindyDatabase setValue:self.username forKey:#"username"];
// [Guest guestWithName:self.name username:self.username photo:self.photo inManagedObjectContext:self.shindyDatabase.managedObjectContext];
[self.shindyDatabase setValue:self.locationManager.location forKey:#"location"];
[self.shindyDatabase setValue:self.dateAndTimePicker.date forKey:#"dateAndTime"];
}
}];
}
I know what I'm asking for is a hell of a lot, but I have exhausted every single resource I have at my disposal. If anybody can even just point me in the right direction, I would be eternally grateful!
If you plan to map an existing database with CoreData you will be unsuccessful.
There's infact no way you can map any database with CoreData.
Core Data infact is a graph object management, with different storage option, and sqllite is just one of the possibility. At startup, if you choose sqllite as option, your application is going to create a database with a specific tables structure. If you try to connect to a database not created by CoreData framework you will get an error.
What you can do is get rid of CoreData, and build your NSObject to act like entities. But then, you will have to implement all the logic to save, update, versioning, concurrency ecc... and it's a long (and buggy) way, especially in a multi user environment.
Otherwise, tell me if I misunderstood your question. Maybe, you can post an error stack trace.

How to refresh a TableView when data is inserted in the AppDelegate?

To pre-populate my Database for a small Iphone-App I do a check in the persistentStoreCoordinator Method in the AppDelegate if the sqlite-file is already there or not. If not I add some data into a table after the db is created. But the data should not directly shown in the RootViewController but in another TableView which can be accessed by pressing a Option in the RootViewController.
The Problem is that the data are saved but are not shown in the TableView. But if terminate and restart the app the data are there.
I have passed the managedObjectContext from my appDelegate to the the RootViewController and from there to the TableViewController. So the managedObjectContext is the same everywhere.
Here is the Code where I pre-populate the DB (in this example just one sample row):
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator_ != nil) {
return persistentStoreCoordinator_;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"TestDBApp.sqlite"];
NSString *storePath = [storeURL relativePath];
BOOL noDb = false;
NSFileManager *fileManager = [NSFileManager defaultManager];
if( ![fileManager fileExistsAtPath:storePath]) {
noDb = true;
}
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();
}
if( noDb) {
noDb = false;
[self populateDB];
}
return persistentStoreCoordinator_;
}
- (void) populateDB {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Kunde" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"oxid" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
NSError *error = nil;
if (![aFetchedResultsController performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
[self insertNewKunde:aFetchedResultsController];
[self saveContext];
[aFetchedResultsController release];
[sortDescriptors release];
[sortDescriptor release];
[fetchRequest release];
}
- (void)insertNewKunde:(NSFetchedResultsController *)fetchedResultsController {
// Create a new instance of the entity managed by the fetched results controller.
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[fetchedResultsController fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
// If appropriate, configure the new managed object.
[newManagedObject setValue:[[NSDate date] description] forKey:#"oxid"];
[newManagedObject setValue:#"Max" forKey:#"fname"];
[newManagedObject setValue:#"Mustermann" forKey:#"lname"];
// Save the context.
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
The managedObjectContext is passed from the AppDelegate to the RootViewController as:
- (void)awakeFromNib {
RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
rootViewController.managedObjectContext = self.managedObjectContext;
}
and to the other TableViewController:
- (void)awakeFromNib {
kundenVC = [[KundenViewController alloc] initWithManagedObjectContext:self.managedObjectContext];
}
Can anyone help me or give a hint?
I also tried to reload the tableView through the viewWillAppear-Method. But no effect.
It is very difficult to guess what is happening but my hunch is that you are not calling self.populateDB until the RootViewController is actually created. This means the RootViewController does not see that data because it is not created.
I could be wrong but I guess that your last line in delegate's awakeFromNib method is eventually calling populateDB through self.managedObjectContext -> persistentStoreCoordinator -> self.populateDB.
Please try to add a line right at the top of awakeFromNib looking like this:
(void)awakeFromNib {
NSManagedObjectContext *context = self.managedObjectContext;
RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
rootViewController.managedObjectContext = context;}
This way I hope the your problem is solved because self.managedObjectContext will call the getter (- (NSManagedObjectContext)managedObjectContext;) instead of the field. Inside there (if you use the generated code) there is a call to the getter of ** persistentStoreCoordinator** which eventually calls you populateDB method.
In case that does not work go ahead and set a breakpoint inside your populateDB. When the debugger stops you should see at the method call stack where you populateDB is actually called from and that might help to figure out your problem.
-Andy
Well, the important part you left out to answer your question. What is [self saveContext] and how are you displaying the records in your table view.
Because your data is saved I assume that the code given here works. The only guess I can make is to use reset on the NSManagedObjectContext and then refetch.
BTW I like the "insertNewKunde" which seems to be the new German grammar ;-)