Cells in UITableView going blank after the view loads - core-data

I am calling data from web service storing it into CoreData and then putting it into an array that I am using to populate the tableview. When the view loads I am deleting all the data held in the entity in CoreData as the data from the web service will be updated frequently and potentially from multiple platforms. Without the delete code everything worked fine (except old data would build up in CoreData) but as soon as I implemented the deleteEntityData call I got this weird thing happening on the simulator. The data appears and then immediately disappears almost as if the delete code is being called before and after the tableview loads. Checking with NSLogs the code appears to be firing in the right order (and at least according to the NSLogs the delete code is not firing twice)..
Here is a link to a screencast so you can see what I am seeing on the simulator.
http://youtu.be/kvDynYQPln8
Code for the main methods in my tableview are below:
- (void)viewDidLoad{
[super viewDidLoad];
[self setUpData];
}
- (void) deleteEntityData {
//Delete All Old Exlpore View Entities in Core Data
NSLog(#"Delete code being called");
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setEntity:[NSEntityDescription entityForName:#"HomeView" inManagedObjectContext:context]];
[fetch setIncludesPropertyValues:NO];
NSError *error = nil;
NSArray *entities = [context executeFetchRequest:fetch error:&error];
for (NSManagedObject * exploreView in entities) {
[context deleteObject:exploreView];
}
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
};
[self.tableView reloadData];
}
- (void) setUpData {
//Initialize AFHTTPRequestOperationManager with Dribbble API base URL
_operationManager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://www.karmo.com/home/news"]];
[_operationManager GET:#"?user_id=XXXX" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
//Success - Runs if connection is made and data recieved
[self deleteEntityData];
//Extrat parsed JSON file into objects to prepare for Core Data import -- Should verify if I can skip and go directly into Core Data
NSManagedObjectContext *context = [self managedObjectContext];
for (int i = 0; i < [[responseObject valueForKey:#"userBeliefs"] count]; i++) {
NSString * type = #"user";
NSString * userFirstName = [[[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"user"] valueForKey:#"firstName"];
NSString * userLastName = [[[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"user"] valueForKey:#"lastName"];
NSString * userID = [[[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"user"] valueForKey:#"_id"];
NSString * topicID = [[[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"topic"] valueForKey:#"_id"];
NSString * title = [[[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"topic"] valueForKey:#"title"];
NSString * vote = [[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"vote"];
NSString * voice = [[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"voice"];
NSString * beliefID = [[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"_id"];
NSNumber * nPoints = #([[[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"nPoints"]intValue]);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *updatedAt = [dateFormat dateFromString:[[[responseObject valueForKey:#"userBeliefs"]objectAtIndex:i] valueForKey:#"updatedAt"]];
NSManagedObject *newHome = [NSEntityDescription insertNewObjectForEntityForName:#"HomeView" inManagedObjectContext:context];
[newHome setValue:type forKey:#"type"];
[newHome setValue:userFirstName forKey:#"userFirstName"];
[newHome setValue:userLastName forKey:#"userLastName"];
[newHome setValue:userID forKey:#"userID"];
[newHome setValue:topicID forKey:#"topicID"];
[newHome setValue:title forKey:#"title"];
[newHome setValue:vote forKey:#"vote"];
[newHome setValue:voice forKey:#"voice"];
[newHome setValue:beliefID forKey:#"beliefID"];
[newHome setValue:nPoints forKey:#"nPoints"];
[newHome setValue:updatedAt forKey:#"updatedAt"];
}
for (int i = 0; i < [[responseObject valueForKey:#"followeeBeliefs"] count]; i++) {
NSUInteger arrayCount = [[[responseObject valueForKey:#"followeeBeliefs"] objectAtIndex:i] count];
NSUInteger subtract = 2;
NSUInteger finalCount = arrayCount - subtract;
for (int ii = 0; ii < finalCount; ii++) {
NSString * type = #"followee";
NSString * followeeUserID = [[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:#"followee"];
NSString * connectionID = [[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:#"_id"];
NSString * userFirstName = [[[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"user"] valueForKey:#"firstName"];
NSString * userLastName = [[[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"user"] valueForKey:#"lastName"];
NSString * userID = [[[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"user"] valueForKey:#"_id"];
NSString * topicID = [[[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"topic"] valueForKey:#"_id"];
NSString * title = [[[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"topic"] valueForKey:#"title"];
NSString * vote = [[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"vote"];
NSString * voice = [[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"voice"];
NSString * beliefID = [[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"_id"];
NSNumber * nPoints = #([[[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"nPoints"]intValue]);
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *updatedAt = [dateFormat dateFromString:[[[[responseObject valueForKey:#"followeeBeliefs"]objectAtIndex:i] valueForKey:[#(ii) stringValue]] valueForKey:#"updatedAt"]];
NSManagedObject *newHome = [NSEntityDescription insertNewObjectForEntityForName:#"HomeView" inManagedObjectContext:context];
[newHome setValue:type forKey:#"type"];
[newHome setValue:followeeUserID forKey:#"followeeUserID"];
[newHome setValue:connectionID forKey:#"connectionID"];
[newHome setValue:userFirstName forKey:#"userFirstName"];
[newHome setValue:userLastName forKey:#"userLastName"];
[newHome setValue:userID forKey:#"userID"];
[newHome setValue:topicID forKey:#"topicID"];
[newHome setValue:title forKey:#"title"];
[newHome setValue:vote forKey:#"vote"];
[newHome setValue:voice forKey:#"voice"];
[newHome setValue:beliefID forKey:#"beliefID"];
[newHome setValue:nPoints forKey:#"nPoints"];
[newHome setValue:updatedAt forKey:#"updatedAt"];
}
}
for (int i = 0; i < [[responseObject valueForKey:#"topics"] count]; i++) {
NSString * type = #"topic";
NSString * topicID = [[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"_id"];
NSString * category = [[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"category"];
NSString * title = [[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"title"];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSDate *updatedAt = [dateFormat dateFromString:[[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"updatedAt"]];
NSString * eventTitle = [[[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"lastEvent"] valueForKey:#"title"];
NSString * eventBody = [[[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"lastEvent"] valueForKey:#"body"];
NSString * eventID = [[[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"lastEvent"] valueForKey:#"_id"];
NSDate * eventUpdatedAt = [dateFormat dateFromString:[[[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"lastEvent"] valueForKey:#"updatedAt"]];
NSDate * eventCreatedAt = [dateFormat dateFromString:[[[[responseObject valueForKey:#"topics"]objectAtIndex:i] valueForKey:#"lastEvent"] valueForKey:#"updatedAt"]];
NSManagedObject *newHome = [NSEntityDescription insertNewObjectForEntityForName:#"HomeView" inManagedObjectContext:context];
[newHome setValue:type forKey:#"type"];
[newHome setValue:topicID forKey:#"topicID"];
[newHome setValue:category forKey:#"category"];
[newHome setValue:title forKey:#"title"];
[newHome setValue:updatedAt forKey:#"updatedAt"];
[newHome setValue:eventTitle forKey:#"eventTitle"];
[newHome setValue:eventBody forKey:#"eventBody"];
[newHome setValue:eventID forKey:#"eventID"];
[newHome setValue:eventUpdatedAt forKey:#"eventUpdatedAt"];
[newHome setValue:eventCreatedAt forKey:#"eventCreatedAt"];
}
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//Failure
NSLog(#"Failed to fetch shots from Karmo API!");
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Unable to Connect"
message:#"We were not able to connect to the karmo database. Some data may be out of date."
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert show];
} ];
[self fetchData];}
- (void) fetchData {
[homeSortData removeAllObjects];
[homeTableData removeAllObjects];
// Fetch the recipes from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"HomeView"];
homeSortData = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
sortDescriptorWithKey:#"updatedAt"
ascending:YES];
NSMutableArray * descriptors = [[NSArray arrayWithObjects:dateDescriptor, nil]mutableCopy];
homeTableData = [[homeSortData sortedArrayUsingDescriptors:descriptors]mutableCopy];
[self.tableView reloadData];}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"type"] isEqualToString:#"topic"]) {
HomeTopicUpdateTableViewCell *topicCell = (HomeTopicUpdateTableViewCell *) [tableView dequeueReusableCellWithIdentifier:#"Topic" forIndexPath:indexPath];
NSDate * topicDate = [[homeTableData objectAtIndex:indexPath.row] valueForKey:#"updatedAt"];
NSString *currentDateString;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
currentDateString = [dateFormat stringFromDate:[NSDate date]];
NSDate *currentDate = [dateFormat dateFromString:currentDateString];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dayComponents = [gregorianCalendar components:NSDayCalendarUnit
fromDate:topicDate
toDate:currentDate
options:0];
NSString *dayDifference = [NSString stringWithFormat:#"%#d", [#([dayComponents day]) stringValue]];
[topicCell.title setText:[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"title"]];
[topicCell.days setText:dayDifference];
[topicCell.eventTitle setText:[[homeTableData objectAtIndex:indexPath.row]valueForKey:#"eventTitle"]];
return topicCell;
}
if ([[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"type"] isEqualToString:#"user"]) {
HomeBeliefTableViewCell *userCell = (HomeBeliefTableViewCell *) [tableView dequeueReusableCellWithIdentifier:#"User" forIndexPath:indexPath];
NSDate * topicDate = [[homeTableData objectAtIndex:indexPath.row] valueForKey:#"updatedAt"];
NSString *currentDateString;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
currentDateString = [dateFormat stringFromDate:[NSDate date]];
NSDate *currentDate = [dateFormat dateFromString:currentDateString];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dayComponents = [gregorianCalendar components:NSDayCalendarUnit
fromDate:topicDate
toDate:currentDate
options:0];
NSString *dayDifference = [NSString stringWithFormat:#"%#d", [#([dayComponents day]) stringValue]];
NSString *pointCount = [[[homeTableData objectAtIndex:indexPath.row] valueForKey: #"nPoints"]stringValue];
[userCell.title setText:[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"title"]];
[userCell.belief setText:[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"voice"]];
[userCell.points setText:pointCount];
[userCell.profileName setText:#"Me"];
[userCell.days setText:dayDifference];
return userCell;
} else {
HomeFolloweeBeliefTableViewCell *followeeCell = (HomeFolloweeBeliefTableViewCell *) [tableView dequeueReusableCellWithIdentifier:#"Followee" forIndexPath:indexPath];
NSDate * topicDate = [[homeTableData objectAtIndex:indexPath.row] valueForKey:#"updatedAt"];
NSString *currentDateString;
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
currentDateString = [dateFormat stringFromDate:[NSDate date]];
NSDate *currentDate = [dateFormat dateFromString:currentDateString];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dayComponents = [gregorianCalendar components:NSDayCalendarUnit
fromDate:topicDate
toDate:currentDate
options:0];
NSString *dayDifference = [NSString stringWithFormat:#"%#d", [#([dayComponents day]) stringValue]];
NSString *fullName = [NSString stringWithFormat:#"%# %#",[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"userFirstName"],[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"userLastName"]];
NSString *pointCount = [[[homeTableData objectAtIndex:indexPath.row] valueForKey: #"nPoints"]stringValue];
[followeeCell.title setText:[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"title"]];
[followeeCell.belief setText:[[homeTableData objectAtIndex:indexPath.row] valueForKey:#"voice"]];
[followeeCell.profileName setText:fullName];
[followeeCell.days setText:dayDifference];
return followeeCell;}}

It seems that in the "success" block in your network call, after parsing the response and saving it in core data, you are not calling [self.tableView reloadData].
reloadData is called in deleteEntityData (That's why you see the data disappearing) and in fetchData, but fetchData most probably executes before the success block finishes, thus the data is not yet saved in core data. Either call [self.tableView reloadData at the end if the success block after saving to core data, or move the call to fetchData to the end of the success block (also after the core data context has been saved)

Related

core data simple fetch request template

I have a small core data base "Guests" and I am trying to get the results from a fetch request template called FetchRequestA, I made a button to trigger in the console the results from the request but I keep on getting a null answer, the request is set to display all guestlastnames that contain a d ? here is the code that i am using :
- (IBAction)fetchA:(id)sender {
NSFetchRequest *request2 = [[[self managedObjectModel] fetchRequestTemplateForName:#"FetchRequestA"] copy];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]initWithKey:#"guestlastname" ascending:YES];
[request2 setSortDescriptors:[NSArray arrayWithObject:sort]];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sort, nil];
[request2 setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:request2 error:&error];
if (fetchedObjects == nil) {
NSLog(#"problem %#", error);
}
for (Guests *guestlastname in fetchedObjects) {
NSLog(#"Fetched Object = %#", guestlastname.guestlastname);
}
}
Am I missing a method ? have perused around but to no avail, thanks in advance.
Here is solution :
(IBAction)gettemplatebutton:(id)sender {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObjectModel* model = [[context persistentStoreCoordinator] managedObjectModel];
NSDictionary* dict = [[NSDictionary alloc]initWithObjectsAndKeys: self.fetchedObjects, #"guestlastname",nil];
NSFetchRequest* request2 = [model fetchRequestFromTemplateWithName:#"FetchRequestA" substitutionVariables: dict];
NSError* error = nil;
NSArray *Guests2 = [context executeFetchRequest:request2 error:&error];
NSString *g3 = #"";
for(NSManagedObject *guestlastname in Guests2)
{
g3 = [g3 stringByAppendingString:[NSString stringWithFormat:#"%#\n", [guestlastname valueForKey:#"guestlastname"]]];
}
self.displaytemplateLabel.text = g3;
[_displaytemplateLabel setNumberOfLines:0];
for (NSManagedObject *guestlastname in Guests2)
{
{
NSLog(#"%#", [guestlastname valueForKey:#"guestlastname"]);
}
}
}
and added #property (nonatomic, retain) NSArray *fetchedObjects; in header file.

Core Data: Not saving

I'm having trouble saving to one variable letsMeet.startTimeLabel. Right after selecting NSLog shows the correct Value, however, after I save to another variable (letsMeet.endTimeLabel), letsMeet.startTimeLabel changes to (NULL). Below is the code:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:#"LetsMeet" inManagedObjectContext:managedObjectContext];
switch (actionSheet.tag)
{
case 1:
{
if (buttonIndex == 0)
{
UIDatePicker *startDatePicker = (UIDatePicker *)[actionSheet viewWithTag:kDatePickerTag1];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd"];
NSDate *selectedDate = [startDatePicker date];
NSDateFormatter *dayFormatter = [[NSDateFormatter alloc] init];
[dayFormatter setDateFormat:#"EEEE"];
NSDate *selectedDay= [startDatePicker date];
NSDateFormatter *monthFormatter = [[NSDateFormatter alloc] init];
[monthFormatter setDateFormat:#"MMMM"];
NSDate *selectedMonth = [startDatePicker date];
NSString *date = [[NSString alloc] initWithFormat:#"%#", [dateFormatter stringFromDate:selectedDate]];
DateLabel.text = date;
[letsMeet setDateLabel:date];
NSString *month = [[NSString alloc] initWithFormat:#"%#", [dayFormatter stringFromDate:selectedMonth]];
MonthLabel.text = month;
[letsMeet setMonthLabel:month];
NSString *day = [[NSString alloc] initWithFormat:#"%#", [monthFormatter stringFromDate:selectedDay]];
DayLabel.text = day;
[letsMeet setDateLabel:day];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat: #"h:mm a"];
NSDate *selectedStartTime = [startDatePicker date];
NSString *startTime = [[NSString alloc] initWithFormat:#"%#", [timeFormatter stringFromDate:selectedStartTime]];
StartTimeLabel.text = startTime;
[letsMeet setStartTimeLabel:startTime];
NSError *error = nil;
if (![managedObjectContext save:&error]){
NSLog(#"Error Saving");
}
}
NSLog (#"This is the StartTime after selecting %#", letsMeet.startTimeLabel);
}
break;
case 2:
{
if (buttonIndex == 0)
{
UIDatePicker *endTimePicker = (UIDatePicker *)[actionSheet viewWithTag:kDatePickerTag2];
NSDateFormatter *endTimeFormatter = [[NSDateFormatter alloc] init];
[endTimeFormatter setDateFormat: #"h:mm a"];
NSDate *endSelectedTime = [endTimePicker date];
NSString *endTime = [[NSString alloc] initWithFormat:#"%#", [endTimeFormatter stringFromDate:endSelectedTime]];
EndTimeLabel.text = endTime;
[letsMeet setEndTimeLabel:endTime];
NSLog (#"This is the EndTime %#", letsMeet.endTimeLabel);
NSLog (#"This is the StartTime after selecting BOTH %#", letsMeet.startTimeLabel);
}
else if (buttonIndex == 1)
{
EndTimeLabel.text = #"Whenever";
[letsMeet setEndTimeLabel:EndTimeLabel.text];
}
NSError *error = nil;
if (![managedObjectContext save:&error]) {
}
}break;
// Handle the error.
}
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *destinationViewController = segue.destinationViewController;
NSLog (#"Prepare For Segue StartTime %#", letsMeet.startTimeLabel);
NSLog (#"Prepare For Segue EndTime%#", letsMeet.endTimeLabel);
}
Here is the log:
2013-02-20 21:38:24.253 AppointmentTime[3129:c07] This is the StartTime after selecting 9:30 AM
2013-02-20 21:38:32.325 AppointmentTime[3129:c07] This is the EndTime 12:15 PM
2013-02-20 21:38:32.325 AppointmentTime[3129:c07] This is the StartTime after Selecting BOTH (null)
2013-02-20 21:38:34.069 AppointmentTime[3129:c07] Prepare For Segue StartTime (null)
2013-02-20 21:38:34.069 AppointmentTime[3129:c07] Prepare For Segue EndTime12:15 PM
Q: Why would letsMeet.startTimeLabel show up correct the first time and after selecting EndTime, it changes to NULL. Please note EndTime continues to show the correct Value all the way up to prepareForSegue. Weird!
According to your logs and code , you are entering the switch block twice. Which means you are entering the actionSheet:clickedButtonAtIndex: method twice. So each time you enter the method
letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:#"LetsMeet" inManagedObjectContext:managedObjectContext];
statement is executed twice, in turn creating two objects. You can see this by doing a fetch from the store.
So you are checking for properties in two different objects and hence the null.
If you are using just one managed object, you can probably add a check for nil for the object before executing insertNewObjectForEntityForName:inManagedObjectContext:. This will make sure you are using the same object.
If you are using more than one object at the same time use the object id or some unique key to identify your object and manipulate it.
Edit:
You can check for nil with the following code:
if(letsMeet==Nil){
letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:#"LetsMeet" inManagedObjectContext:managedObjectContext];
}
This will work only, if the object you are calling the actionSheet:clickedButtonAtIndex: method is always in memory. But since you are persisting you might want to fetch the object from the store and then check for no. of objects.
NSError *error;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"LetsMeet" inManagedObjectContext:managedObjectContext]];
NSArray *objectArray = [managedObjectContext executeFetchRequest:request error:&error]
if(objectArray.count==0){
letsMeet = (LetsMeet *) [NSEntityDescription insertNewObjectForEntityForName:#"LetsMeet" inManagedObjectContext:managedObjectContext];
}else{
letsMeet = (LetsMeet *)[objectArray objectAtIndex:0];
}
Note: If you need to persist only a couple of variables, core-data might be an overkill. Use NSUserDefaults instead and keep it simple.

Core Data - One to Many relationship with object(one) and UIImages(many), storing and fetching

I aim to build a app with the object of:
- Request(contains an unique id, customer name, phone, email, a brief summary of request info, a list of images(store in NSMutable Array)
My Core data contains:
Request
Image
For my request object, I have:
#import <Foundation/Foundation.h>
#interface BAPRequest : NSObject
#property (nonatomic, retain) NSString *requestID;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *email;
#property (nonatomic, retain) NSString *phone;
#property (nonatomic, retain) NSString *detail;
#property (nonatomic, retain) NSMutableArray *images;
#property (nonatomic, retain) NSDate *requestDate;
#property (nonatomic) BOOL isSent;
- (void)fetchImages;
#end
And the .m File:
#import "BAPAppDelegate.h"
#import "BAPRequest.h"
#implementation BAPRequest
#synthesize name, email, phone, detail;
#synthesize images;
#synthesize requestDate;
#synthesize isSent;
#synthesize requestID;
- (id)init{
self = [super init];
if(self != nil){
self.isSent = false;
self.requestID = [[NSProcessInfo processInfo] globallyUniqueString];
self.images = [[NSMutableArray alloc] init];
}
return self;
}
- (void)fetchImages{
//get delegation
BAPAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSError *error;
//init request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
//load the entity description
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Image"
inManagedObjectContext:context];
//set the request query
[fetchRequest setEntity:entityDescription];
//set predicate to request to ask select specific entity with the matching line num
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(requestId == %#)", self.requestID];
[fetchRequest setPredicate:pred];
//exec the command to find the object(table) from core database
NSArray * imageList = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *imageObject in imageList){
[self.images addObject: [UIImage imageWithData:[imageObject valueForKey:#"content"]]];
}
}
#end
To fetch all the requests, I also do:
- (void)removeRequest:(BAPRequest*)request{
//get delegation
BAPAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSError *error;
//init request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
//load the entity description
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Request"
inManagedObjectContext:context];
//set the request query
[fetchRequest setEntity:entityDescription];
//set predicate to request to ask select specific entity with the matching line num
NSLog(#"request id is %#", request.requestID);
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(requestId LIKE %#)", request.requestID];
[fetchRequest setPredicate:pred];
//exec the command to find the object(table) from core database
NSArray *objects = [context executeFetchRequest:fetchRequest error:&error];
//if this object doesn't exist in the database, it must be something wrong
if (objects == nil) {
NSLog(#"There was an error !");
NSLog(#"Error Info: %#", error);
}
//if object exist in database, take the first search object, and deletes it
if ([objects count] > 0){
NSManagedObject *theRequest = [objects objectAtIndex:0];
[context deleteObject:theRequest];
}
[context save:&error];
/*
//delete existing images relates to this request first
entityDescription = [NSEntityDescription entityForName:#"Image"
inManagedObjectContext:context];
pred = [NSPredicate predicateWithFormat:#"(self.request == %#)", request];
[fetchRequest setPredicate:pred];
NSArray * imageList = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *removeImageObject in imageList){
[context deleteObject:removeImageObject];
}
*/
}
#pragma mark - Convert Core Data Object to Request Object
#pragma mark - Core Data Methods
- (NSMutableArray *)getRequests{
//get app delegate
BAPAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
//get object context that's created for us
NSManagedObjectContext *context = [appDelegate managedObjectContext];
//define the entities we want load to description
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"Request"
inManagedObjectContext:context];
//init request and set search query to the request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entityDescription];
NSError *error;
//get objects(table) though request
NSArray *objects = [context executeFetchRequest:fetchRequest error:&error];
if (objects == nil){
NSLog(#"There was an error !");
//error handling there
NSLog(#"Error Info: %#", error);
}
NSMutableArray *requests = [[NSMutableArray alloc] init];
for (NSManagedObject *requestObj in objects){
BAPRequest *request = [[BAPRequest alloc] init];
request.requestID = [requestObj valueForKey:#"requestId"];
request.name = [requestObj valueForKey:#"name"];
request.email = [requestObj valueForKey:#"email"];
request.phone = [requestObj valueForKey:#"phone"];
request.detail = [requestObj valueForKey:#"detail"];
request.requestDate = [requestObj valueForKey:#"requestDate"];
request.isSent = [[requestObj valueForKey:#"isSent"] boolValue];
[request fetchImages];
[requests addObject: requestObj];
}
return requests; //return the requests
}
- (void)saveRequest:(BAPRequest *)request{
request.requestDate = [NSDate date];
//get delegation
BAPAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSError *error;
BAPRequest *theRequest = [NSEntityDescription insertNewObjectForEntityForName:#"Request"
inManagedObjectContext:context];
//set the request obejct basics
[theRequest setValue:request.requestID forKey:#"requestId"];
[theRequest setValue:request.name forKey:#"name"];
[theRequest setValue:request.email forKey:#"email"];
[theRequest setValue:request.phone forKey:#"phone"];
[theRequest setValue:request.detail forKey:#"detail"];
[theRequest setValue:request.requestDate forKey:#"requestDate"];
[theRequest setValue:[NSNumber numberWithBool:request.isSent ] forKey:#"isSent"];
//also save its requests
for (UIImage *img in request.images) {
//init image object
UIImage *newImage=[NSEntityDescription insertNewObjectForEntityForName:#"Image" inManagedObjectContext:context];
[newImage setValue:request.requestID forKey:#"requestId"];
[newImage setValue:UIImagePNGRepresentation(img) forKey:#"content"];
}
[context save:&error]; //save the object
}
#end
My Issue is:
I guess it just doesn't fetch the images at all. Even they fetched the images in the getRequests method, when I try to pass the request to somewhere else, it still get lots issues:
boolean not loading properly
images are nil(even it was loaded when fetch)
and the reason is(I can be wrong) that when I store these request objects(BAPRequest*) into a NSArray and pass it to a table view, when I load them from array (e.g [myArray objectAtIndex:0]), they are still NSManagedObject. I tried to give a class name in the core data entity option to make the Request(Core Data) Object Class of BAPRequest, but it keeps saying I have to subclass NSManagedObject, where subclassing NSManagedObject is not possible:
I can't do:
BAPRequest: NSManagedObject
XCode doesn't likes it.
Look at mogenerator. Here's a tutorial on how to use it: http://raptureinvenice.com/getting-started-with-mogenerator/ . It will save you a lot of trouble.

Serious issue in parsing xml and storing details using coredata

I am using google weather api to get weather information,I am using coredata to store information.I am running into troble.I am getting results on labels and UImageview to store information using coredata.My code is posted below
-(IBAction)sBarpress:(id)sender
{
NSString *urlString = [NSString stringWithFormat:#"http://www.google.co.uk/ig/api?weather=%#",sBar.text];
NSURL *url = [NSURL URLWithString:urlString];
NSLog(#"buttonpress");
WeatherXMLParser *delegate = [[WeatherXMLParser alloc] init];
NSXMLParser *locationParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[locationParser setDelegate:delegate];
[locationParser setShouldResolveExternalEntities:YES];
[locationParser parse];
/*
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:#"Weather" inManagedObjectContext:context];
request.predicate = [NSPredicate predicateWithFormat:#"uniqueId = %#", [Data objectForKey:#"id"]];
NSError *error = nil;
NSManagedContext *returnedData = [[context executeFetchRequest:request error:&error] lastObject];
[request release];
[NSEntityDescription insertNewObjectForEntityForName:#"condition" inManagedObjectContext:context];
MODEL_OBJECT.uniqueId = [Data objectForKey:#"id"];
MODEL_OBJECT.title = [Data objectForKey:#"title"];
*/
for (WeatherCondition *condition in delegate.forecastConditions) {
NSLog(#"description is %#", condition.description);
hightemplabel.text=condition.description;
}
for (WeatherCondition *condition in delegate.forecastConditions) {
NSLog(#"description is %#", condition.icon);
NSData *mydata=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"http://www.google.co.uk/ig/images/weather/partly_cloudy.gif"]];
conditionsImageView.image = [[UIImage alloc] initWithData:mydata ];
}
for (WeatherCondition *condition in delegate.forecastConditions) {
NSLog(#"description is %#", condition.icon);
NSData *mydata=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"http://www.google.co.uk/ig/images/weather/thunderstorm.gif"]];
forecastimage.image = [[UIImage alloc] initWithData:mydata ];
}
for (WeatherCondition *condition in delegate.forecastConditions) {
NSLog(#"description is %#", condition.description);
humiditylabel.text=condition.description;
}
[self fetchRecords];
[locationParser release];
[delegate release];
// NSDictionary *airport = [responseString JSso ];
// displaybox.text=[airport objectForKey:#"location"];
/*
NSURL *url=[NSURL URLWithString:#"http://airportcode.riobard.com/airport/%#?fmt=json"];http://free.worldweatheronline.com/feed/weather.ashx?q=omaha%2c+ne,united+states&format=json&num_of_days=5&key=691607e82d192404111506 &format=jason
//NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [response dataUsingEncoding:NSUTF8StringEncoding];
WeatherParser *locationParser = [[WeatherParser alloc] init];
[locationParser parseData:data];
label.text = locationParser.location;
urlString = [NSString stringWithFormat:#"http://free.worldweatheronline.com/feed/weather.ashx?q=%#&format=json&num_of_days=5&key=691607e82d192404111506",locationParser.location];
url = [NSURL URLWithString:urlString];
NSLog(#"area coming");
[response release];
response = [[NSString alloc] initWithContentsOfURL:url];
data = [response dataUsingEncoding:NSUTF8StringEncoding];
WeatherParser *weatherParser = [[WeatherParser alloc] init];
[weatherParser parseData:data];
[locationParser release];
[weatherParser release];
*/
}
- (void)fetchRecords {
// Define our table/entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Weather" inManagedObjectContext:managedObjectContext];
NSLog(#" entity is %#",entity);
// Setup the fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
// If a predicate was passed, pass it to the query
if(predicate != nil)
{
[request setPredicate:predicate];
}
// Define how we will sort the records
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"condition" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
// Fetch the records and handle an error
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (!mutableFetchResults) {
// Handle the error.
// This is a serious error and should advise the user to restart the application
}
// Save our fetched data to an array
[self setEventArray: mutableFetchResults];
[mutableFetchResults release];
[request release];
}
You didnt really describe what the trouble is, but I can see some possible performance issues in your code ...
You are looping multiple times:
for (WeatherCondition *condition in delegate.forecastConditions) {
NSLog(#"description is %#", condition.description);
hightemplabel.text=condition.description;
}
for (WeatherCondition *condition in delegate.forecastConditions) {
NSLog(#"description is %#", condition.icon);
NSData *mydata=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"http://www.google.co.uk/ig/images/weather/partly_cloudy.gif"]];
conditionsImageView.image = [[UIImage alloc] initWithData:mydata ];
}
refactor these loops into one loop through the results:
for (WeatherCondition *condition in delegate.forecastConditions) {
NSLog(#"description is %#", condition.description);
hightemplabel.text=condition.description;
NSLog(#"icon is %#", condition.icon);
NSData *mydata=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"http://www.google.co.uk/ig/images/weather/partly_cloudy.gif"]];
conditionsImageView.image = [[UIImage alloc] initWithData:mydata ];
}

Printing Core Data

I'm working on a program and I have created a fetch request to grab the data that I need to print. I'm able to log information like this:
2010-10-03 16:57:10.362 lzshow7.2[2537:10b] <NSManagedObject: 0x2ca120> (entity: Song; id: 0x2afcb0 <x-coredata://CF5A85CE-BE0F-4ADC-979A-7F4214A8FB19/Song/p9> ; data: {
cueName = Freedom;
cueNo = 014;
cueNotes = nil;
songToInstrument = "<relationship fault: 0x2b1800 'songToInstrument'>";
})
How do I seperate the properties like cueName, cueNo, cueNotes out to be printed?
Here is the fetch request:
//Managed object context???
NSLog(#"setting Managed object stuff");
NSManagedObjectContext *context=[[[NSDocumentController sharedDocumentController] currentDocument] managedObjectContext];
NSLog(#"Second line of Managed object stuff");
//fetch request:
NSLog(#"Starting to fetch:");
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Song" inManagedObjectContext:context];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"cueNo" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error;
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
for (id obj in mutableFetchResults)
NSLog(#"%#", obj);
NSLog(#"finished looping");
//Error handling
if (mutableFetchResults == nil) {
// Handle the error.
}
//[self setEventsArray:mutableFetchResults];
[mutableFetchResults release];
[request release];
}
Any help would be greatly appreciated.
Thank you,
Loren
You use basically the opposite of how you stored the values in your managedObject
NSString *name = [song valueForKey:#"cueName"];
NSNumber *number = [song valueForKey:#"cueNo"];
NSString *notes = [song valueForKey:#"cueNotes"];
...
NSLog(#"%# %# %#", name, number, notes);
if you've created a custom Class of your entity you could add this method:
- (NSString *)description {
NSString *name = [song valueForKey:#"cueName"];
NSNumber *number = [song valueForKey:#"cueNo"];
NSString *notes = [song valueForKey:#"cueNotes"];
...
NSString *returnString = [NSString stringWithFormat:#"%# %# %#", name, number, notes];
return returnString;
}
With this method you can just use NSLog(#"%#", object); to get a nice formatted output

Resources