Why doesn't my program enter the viewDidLoad method? - iphone

I am trying to test this program on use of Core data. Once again, this is an example from the Dave Marks book. It has four text fields on a view and it loads it by using core data to connect to the database.
The app was created as a window based application and then I added a viewController to it. The file's owner is a sub class of the custom viewController class that I have created.
When I execute it, the UIView comes up with a blank view with no text boxes or labels that I had created in the view.
I put a break point in the main method, it does not even go anywhere from there when I click on step into method button. When I place a break point on the viewDidLoad method, it does not even get to it.
Lastly I do not get any errors on the console. What is going on?
Here is the viewController class:
#import "PersistenceViewController.h"
#import "CoreDataPersistenceAppDelegate.h"
#implementation PersistenceViewController
#synthesize line1;
#synthesize line2;
#synthesize line3;
#synthesize line4;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
CoreDataPersistenceAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Line" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if (objects == nil) {
NSLog(#"There was an error");
}
for (NSManagedObject *oneObject in objects) {
NSNumber *lineNum = [oneObject valueForKey:#"lineNum"];
NSString *lineText = [oneObject valueForKey:#"lineText"];
NSString *fieldName = [NSString stringWithFormat:#"line%d", [lineNum integerValue]];
UITextField *theField = [self valueForKey:fieldName];
theField.text = lineText;
}
[request release];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(void) applicationWillResignActive:(NSNotification *)notification {
CoreDataPersistenceAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSError *error;
for (int i=1; i<=4; i++) {
NSString *fieldName = [NSString stringWithFormat:#"line%d",i];
UITextField *theField = [self valueForKey:fieldName];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Line" inManagedObjectContext:context];
[request setEntity:entityDescription];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(lineNum = %d)", i];
[request setPredicate:pred];
NSManagedObject *theLine = nil;
NSArray *objects = [context executeFetchRequest:request error:&error];
if (objects == nil) {
NSLog(#"There was an error");
}
if ([objects count] > 0)
theLine = [objects objectAtIndex:0];
else
theLine = [NSEntityDescription insertNewObjectForEntityForName:#"Line" inManagedObjectContext:context];
[theLine setValue:[NSNumber numberWithInt:i] forKey:#"lineNum"];
[theLine setValue:theField.text forKey:#"lineText"];
[request release];
}
[context save:&error];
}
- (void)viewDidUnload
{
self.line1 = nil;
self.line2 = nil;
self.line3 = nil;
self.line4 = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[line1 release];
[line2 release];
[line1 release];
[line1 release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#end

Be sure to change the viewcontroller that gets intialized in the appdelegate with the correct nib. The blank UIView is probably the view created when you started the project.
In your AppDelegate there is a method called applicationdidFinishLaunchingWithOptions, in which something like the following code is located:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[RIViewController alloc] initWithNibName:#"RIViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
In my case I load the RIViewController. By default the nib file has the same name as the controller and is hence named RIViewController aswell.

Related

Restkit 0.20 objects are not mapped after getting json response

I'm using RestKit 0.20. I'm trying to download the json response from the local rails application and save it to core-data. I tried to follow https://github.com/RestKit/RKGist/blob/master/TUTORIAL.md and everything worked fine.
I wanted to use this many times so i made it a base class(ListController) and subclassed it to SessionListController and EventListController. The mapping is provided in AppDelegate.m.
The app has a first viewcontroller which is the root controller which always maps the responses and everything works fine. But as soon as i change the viewcontroller i will get the response and the operation stops. it does't even say if the mapping has started. I'm not sure what i have missed.
Here i'm initialising restkit
AppDelegate.m
#import "AppDelegate.h"
#import <UIKit/UIKit.h>
#implementation AppDelegate
RKEntityMapping *eventEntityMapping,*sessionEntitiyMapping;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSError *error = nil;
NSURL *modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"event" ofType:#"momd"]];
NSManagedObjectModel *managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
[self setManagedObjectStore: [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel]];
// Initialize the Core Data stack
[self.managedObjectStore createPersistentStoreCoordinator];
NSPersistentStore __unused *persistentStore = [self.managedObjectStore addInMemoryPersistentStore:&error];
NSAssert(persistentStore, #"Failed to add persistent store: %#", error);
[self.managedObjectStore createManagedObjectContexts];
// Set the default store shared instance
[RKManagedObjectStore setDefaultStore:self.managedObjectStore];
NSString *url=#"http://192.168.11.11:3000";
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:url]];
objectManager.managedObjectStore = self.managedObjectStore;
[RKObjectManager setSharedManager:objectManager];
[self mapEntities];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:eventEntityMapping pathPattern:#"/api/v1/events" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
RKResponseDescriptor *responseDescriptor2 = [RKResponseDescriptor responseDescriptorWithMapping:sessionEntitiyMapping pathPattern:#"/api/v1/sessions" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor2];
// Override point for customization after application launch.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:#"mainCenterController"];
IIViewDeckController* secondDeckController = [[IIViewDeckController alloc] initWithCenterViewController:navigationController
leftViewController:[storyboard instantiateViewControllerWithIdentifier:#"sideBarController"]];
secondDeckController.centerhiddenInteractivity=IIViewDeckCenterHiddenNotUserInteractiveWithTapToClose;
self.window.rootViewController = secondDeckController;
return YES;
}
-(void)mapEntities{
//event
eventEntityMapping = [RKEntityMapping mappingForEntityForName:#"Event" inManagedObjectStore:self.managedObjectStore];
[eventEntityMapping addAttributeMappingsFromDictionary:#{
#"id": #"event_id",
#"name": #"name",
#"description": #"desc",
#"no_of_days": #"no_of_days",
#"start_date": #"start_date",
}];
eventEntityMapping.identificationAttributes = #[ #"event_id" ];
sessionEntitiyMapping = [RKEntityMapping mappingForEntityForName:#"Session" inManagedObjectStore:self.managedObjectStore];
[sessionEntitiyMapping addAttributeMappingsFromDictionary:#{
#"name": #"name",
#"description": #"desc",
#"start_time": #"start_time",
#"duration": #"duration",
#"location_id": #"location_id",
#"event_id": #"event_id",
#"id": #"session_id",
}];
sessionEntitiyMapping.identificationAttributes = #[ #"session_id" ];
}
Base class where i'm calling getObjectsAtPath for RKManager depending on the base class.
ListController.m
#implementation ListController
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectStore.mainQueueManagedObjectContext;
[self loadLocs];
[self.refreshControl beginRefreshing];
}
-(void)setModel:(Models)model{
if(self.model!=model){
_model=model;
self.title=[Model displayFor:self.model];
_fetchedResultsController = nil;
[self.tableView reloadData];
[self loadLocs];
[self.refreshControl beginRefreshing];
}
}
- (void)loadLocs
{
[[RKObjectManager sharedManager] getObjectsAtPath:[Model listApiFor:self.model]
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.refreshControl endRefreshing];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
[self.refreshControl endRefreshing];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
NSLog(#"error: %#",error);
[alertView show];
}];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[[self fetchedRCforTableView:tableView] sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
[self configureCell:cell atIndexPath:indexPath forTableView:tableView];
return cell;
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:[Model entityFor:self.model] inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:[Model sortDescriptorFor:self.model] ascending:YES];
NSArray *sortDescriptors = #[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:[Model displayFor:self.model]];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
NSLog(#"_fetchedResultsController count %d",_fetchedResultsController.fetchedObjects.count);
return _fetchedResultsController;
}
#end
This is one of the base classes where i set the model name
EventViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.model=Eventm;
// Do any additional setup after loading the view.
}
SessionViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.model=Sessionm;
// Do any additional setup after loading the view.
}
Full code is at https://github.com/leohemanth/event-app
After using
RKLogConfigureByName("RestKit", RKLogLevelWarning);
RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);
RKLogConfigureByName("RestKit/Network", RKLogLevelTrace);
I can see that, i'm getting proper Http response but it is not being mapped. Which i'm not sure why?
I've just updated my Restkit package to 0.20.2. I'm not facing the problem now. It should be fixed in the update.

iOS - Managed object context crashes app when launching from local notification

I have an app that creates a local notification. When the app is closed (i.e. not running or in the background), it crashes when being launched from the notification. I've managed to figure out which line is crashing the app (stated in a comment below):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
// Initialise the main view
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
// Initialise a Navigation Controller
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.viewController];
// Set the ViewController as the rootViewController of the window
self.window.rootViewController = nav;
// Colour the navigation bar
nav.navigationBar.tintColor = [UIColor colorWithRed:0.07f green:0.59f blue:0.94f alpha:1];
// Set the background
if (isPhone568) {
self.window.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"santa_back5.png"]];
}
else {
self.window.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"santa_back.png"]];
}
[self.window makeKeyAndVisible];
[nav release];
self.viewController.managedObjectContext = [self managedObjectContext];
application.applicationIconBadgeNumber = 0;
// Handle launching from a notification
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSPredicate *predicate = [NSPredicate
predicateWithFormat:#"(dateCreated like %#)",
[localNotif.userInfo objectForKey:#"dateCreated"]];
LetterViewController *letterView = [[LetterViewController alloc] initWithNibName:#"LetterViewController" bundle:nil];
// Get the letter to pass on
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Letter" inManagedObjectContext:[self managedObjectContext]];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
NSError *error;
//
// THIS NEXT LINE IS CRASHING THE APP
//
NSArray *letters = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
Letter *myLetter = [letters objectAtIndex:0];
letterView.theLetter = myLetter;
//[myLetter release];
// Pass the selected object to the new view controller.
[self.viewController.navigationController pushViewController:letterView animated:YES];
[letterView release];
[fetchRequest release];
}
return YES;
}
I am using the following 3 functions to get the managed object context, persistent store coordinator and managed object model:
//Explicitly write Core Data accessors
- (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;
}
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
return managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
stringByAppendingPathComponent: #"<Project Name>.sqlite"]];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeUrl options:nil error:&error]) {
/*Error for store creation should be handled in here*/
}
return persistentStoreCoordinator;
}
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
Any help in solving this problem would be greatly appreciated.
Thanks in advance.
Couple of things. You appear to be using Core Data on the main thread in what you show, if so all interaction must be on this thread. You should update the code someday to use the new 'perform' API which uses blocks.
Since your localNotif code now does some heavy lifting in the launch delegate it does not return for some time and iOS may kill your app. Take that same code and put it into dispatch block posted to the main queue and it should work. Add some asserts to insure the navigation controller property exists too.
Thanks for the answer. Seems my problem was with the predicate! It doesn't like me using "like" in the where clause. I changed it to an = and it works!

Why is my managedObjectContext coming back nill?

I'm trying to use CLLocation Manager to get someone's location whenever they move and store the lat, lng, and timestamp into core data, then display that in a table view tab. However, the output in the console always indicates that managedObjectContext is nill by throwing this log coredataproject[12478:11903] After managedObjectContext: <NSManagedObjectContext: 0x7248230>
Here's the relevant code in my AppDelgate implementation file
#import "AppDelegate.h"
#import "RootViewController.h"
#import "FirstViewController.h"
#implementation AppDelegate
#synthesize window;
#synthesize navigationController;
#pragma mark -
#pragma mark Application lifecycle
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Configure and show the window.
RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
NSLog(#"Could not create context for self");
}
rootViewController.managedObjectContext = context;
UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.navigationController = aNavigationController;
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
/**
applicationWillTerminate: saves changes in the application's managed object context before the application terminates.
*/
- (void)applicationWillTerminate:(UIApplication *)application {
NSError *error;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Handle the error.
}
}
}
Here is the FirstViewController.M code, where I'm getting the location and storing it in the core data 'Event' entity
- (void)viewDidLoad
{
locationManager =[[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
-(void) locationmanager: (CLLocationManager *) manager
didUpdateToLocation: (CLLocation *) newLocation
fromLocation: (CLLocation *) oldLocation
{
CLLocation *location = [locationManager location];
if (!location) {
return;
}
/*
Create a new instance of the Event entity.
*/
RootViewController *rootviewcontroller = [RootViewController alloc];
Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:#"Event" inManagedObjectContext:rootviewcontroller.managedObjectContext];
// Configure the new event with information from the location.
CLLocationCoordinate2D coordinate = [location coordinate];
[event setLatitude:[NSNumber numberWithDouble:coordinate.latitude]];
[event setLongitude:[NSNumber numberWithDouble:coordinate.longitude]];
// Should be the location's timestamp, but this will be constant for simulator.
// [event setCreationDate:[location timestamp]];
[event setTimeStamp:[NSDate date]];
// Commit the change.
NSError *error;
if (![rootviewcontroller.managedObjectContext save:&error]) {
NSLog(#"Save Error");
}
//RootViewController *rootviewcontroller = [RootViewController alloc];
[rootviewcontroller.eventsArray insertObject:event atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[rootviewcontroller.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[rootviewcontroller.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
And finally here is the RootViewController file where I'm trying to fetch and display what's in the core data. It's when I click this tab that the console tells me that managedObjectConsole is nill
- (void)viewDidLoad {
[super viewDidLoad];
if (managedObjectContext == nil)
{
managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After managedObjectContext: %#", managedObjectContext);
}
// Set the title.
self.title = #"Locations";
/*
Fetch existing events.
Create a fetch request; find the Event entity and assign it to the request; add a sort descriptor; then execute the fetch.
*/
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Event" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
// Order the events by time stamp, most recent first.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
// Execute the fetch -- create a mutable copy of the result.
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
NSLog(#"Mutable Fetch Results equals nill");
}
// Set self's events array to the mutable array, then clean up.
[self setEventsArray:mutableFetchResults];
}
I'm also doing some more stuff with organizing the table data once it's there, but I don't think that's where the problem is.
I'm unsure as to why nothing would be in managedObjectContext, as it should have the location data from the location manager. I'm not too familiar with Core data, so I'm probably just doing something simple wrong, but any insight would be appreciated!
Your mistake is in the didUpdateToLocation method. There you create a new instance of RootViewController. You just need to save the newLocation to CoreData and need the MOC for that (not the RootViewController). So you need to find a way to pass the MOC to the FirstViewController. You can do this similar like you did in the AppDelegate or like this:
managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
Why do you reset the MOC of RootViewController in viewDidLoad? You already passed it in applicationDidFinishLaunching!
I'd recommend to use a NSFetchedResultsController for the table view. It automatically detects changes of the data and reloads the table if needed, just implement the delegate correctly. Here is a helpful tutorial on this: http://www.raywenderlich.com/999/core-data-tutorial-how-to-use-nsfetchedresultscontroller

managedObjectContext question

I have an app which is a UITabBarController, I have defined two subviews
Both tabs have their Class attribute in the Identity Inspector set to UINavigationController.
Now i have managed to get this far with my coding after VERY LONG trials.
- (void)viewDidLoad {
[super viewDidLoad];
myAppDelegate *appDelegate = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectContext;
{
NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"User" inManagedObjectContext:self.managedObjectContext]];
NSArray *fetchedItems = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSEntityDescription *entityDesc =
[NSEntityDescription entityForName:#"User" inManagedObjectContext:self.managedObjectContext];
// replace the old data with new. this DOESNT WORK
if (fetchedItems.count > 0)
{
Usr *newUsr;
for (newUsr in fetchedItems)
{
if ([newUsr.name isEqualToString:#"Line One"])
{
newUsr.uName = #"Line One (new)";
}
}
}
//add a new default data. THIS ADDS DATA TO MY TABLEVIEW BUT IT DOESNT SAVE THEM TO THE SQLITE
User *addedDefaultdata = nil;
addedDefaultdata = [[User alloc] initWithEntity:entityDesc insertIntoManagedObjectContext:self.managedObjectContext];
addedDefaultdata.name = #"Added new 1";
[addedDefaultdata release];
}
NSError *error = nil;
if (![User.managedObjectContext save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
and my appdelegate looks like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[application setStatusBarStyle:UIStatusBarStyleBlackOpaque];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
}
now I cannot quire the "User" at all! although i get no errors or warnings!
Any suggestions would be much appreciated!
Thanks
It seems that you may be asking how to update to CoreData?
If so, you need to use the save: method on NSManagedObjectContext, like this:
NSError *error;
[managedObjectContent save:&error];
if (error) {
...
}

Problem with entityForName & ManagedObjectContext when extending tutorial material

Afternoon all,
I tried to add a second data entity to the persistent store in the (locations) coredata tutorial code, and then access this in a new view. I think that I've followed the tutorial, and checked that I'm doing a clean build etc, but can't see what to change to prevent it crashing.
I'm afraid I'm at my wits end with this one, and can't seem to find the step that I've missed. I've pasted the header and code files below, please let me know if I need to share any more of the code. The crash seems to happen on the line:
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Album" inManagedObjectContext:[self managedObjectContext]];
There is one other line in the code that refers to galleryviewcontroller at the moment, and that's in the main application delegate:
galleryViewController.managedObjectContext = [self managedObjectContext];
GalleryViewController.h
#import <UIKit/UIKit.h>
#interface GalleryViewController : UIViewController {
NSManagedObjectContext *managedObjectContext;
int rowNumber;
IBOutlet UILabel *lblMessage;
UIBarButtonItem *addButton;
NSMutableArray *imagesArray;
}
#property (readwrite) int rowNumber;
#property (nonatomic,retain) UILabel *lblMessage;
#property (nonatomic,retain) NSMutableArray *imagesArray;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain) UIBarButtonItem *addButton;
-(void)updateRowNumber:(int)theIndex;
-(void)addImage;
#end
GalleryViewController.m
#import "RootViewController.h"
#import "LocationsAppDelegate.h"
#import "Album.h"
#import "GalleryViewController.h"
#import "Image.h"
#implementation GalleryViewController
#synthesize lblMessage,rowNumber,addButton,managedObjectContext;
#synthesize imagesArray;
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
-(void)updateRowNumber:(int)theIndex{
rowNumber=theIndex;
LocationsAppDelegate *mainDelegate =(LocationsAppDelegate *)[[UIApplication sharedApplication] delegate];
Album *anAlbum = [mainDelegate.albumsArray objectAtIndex:rowNumber];
lblMessage.text = anAlbum.uniqueAlbumIdentifier;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addImage)];
addButton.enabled = YES;
self.navigationItem.rightBarButtonItem = addButton;
/* Found this in another answer, adding it to the code didn't help.
if (managedObjectContext == nil) {
managedObjectContext = [[[UIApplication sharedApplication] delegate] managedObjectContext];
}
*/
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Album" inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];
// Order the albums by creation date, most recent first.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"imagePath" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];
// Execute the fetch -- create a mutable copy of the result.
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[self setImagesArray:mutableFetchResults];
int a = 5;
int b = 10;
for( int i=0; i<[imagesArray count]; i++ )
{
if( a == 325 )
{
a = 5;
b += 70;
}
UIImageView *any = [[UIImageView alloc] initWithFrame:CGRectMake(a,b,70,60)];
any.image = [imagesArray objectAtIndex:i];
any.tag = i;
[self.view addSubview:any];
[any release];
a += 80;
}
}
-(void)addImage{
NSString *msg = [NSString stringWithFormat:#"%i",rowNumber];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Add image to" message:msg
delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
[alert release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[lblMessage release];
[managedObjectContext release];
[super dealloc];
}
#end
It helps to post the error you are getting.
Have you tried the following:
Clean build of your project
Resetting the simulator to remove the older sqlite data file
If neither of those solve the issue then post the error you are getting as an update to your question.
update
The information I was looking for would be printing out in the console, while the debugger is an infinitely useful tool and I recommend learning it, in this case your issue would have been resolved by reviewing the console output of your application.