Delete object in Core Data - iphone

How I can delete an object which I had added before with this code. Its a favorites section, in the begin, I add a gray star which adds an object coming from a fetch. Then It turns yellow and the backwards method should be star yellow = deletes.
But I have no idea how to do this.
-(IBAction)inFavoris:(id)sender {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *favorisObj = [NSEntityDescription
insertNewObjectForEntityForName:#"Favoris"
inManagedObjectContext:context];
[favorisObj setValue:idTaxi forKey:#"idTaxi"];
[favorisObj setValue:nomTaxi forKey:#"nomTaxi"];
[favorisObj setValue:taxiCB forKey:#"cb"];
[favorisObj setValue:taxiAvion forKey:#"avion"];
[favorisObj setValue:taxiColis forKey:#"colis"];
[favorisObj setValue:taxiHandicape forKey:#"handicape"];
[favorisObj setValue:taxiHoraires forKey:#"horaire"];
[favorisObj setValue:lugagge forKey:#"lugagge"];
[favorisObj setValue:luxury forKey:#"luxury"];
[favorisObj setValue:languesParlees forKey:#"langues"];
[favorisObj setValue:taxiNote forKey:#"note"];
[favorisObj setValue:taxiPassengers forKey:#"passenger"];
[favorisObj setValue:taxiVote forKey:#"etoiles"];
[favorisObj setValue:taxiTel forKey:#"tel"];
[self.view addSubview:favorisB];
}
UPDATE
I made this method.. It gets the job done :)
-(IBAction)outFavoris:(id)sender {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSString *testEntityId = idTaxi;
NSManagedObjectContext *moc2 = [appDelegate managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
fetch.entity = [NSEntityDescription entityForName:#"Favoris" inManagedObjectContext:moc2];
fetch.predicate = [NSPredicate predicateWithFormat:#"idTaxi == %#", testEntityId];
NSArray *array = [moc2 executeFetchRequest:fetch error:nil];
for (NSManagedObject *managedObject in array) {
[moc2 deleteObject:managedObject];
}
[self.view addSubview:favorisO];
}

Its quite simple :)
[context deleteObject:favorisObj];
And the bad object is all gone.
Update
You'd just reverse it with something like this if you need a button to delete the object.
-(IBAction)removeFavoris:(id)sender {
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
[context deleteObject:favorisObj];
}

Don't forget to save the Context after you have deleted a NSManagedObject. So here is the general code;
NSManagedObjectContext * context = [self managedObjectContext];
[context deleteObject:objectToDelete];
NSError * error = nil;
if (![context save:&error])
{
NSLog(#"Error ! %#", error);
}
In your case it should have the snippet after the for loop.
for (NSManagedObject *managedObject in array) {
[moc2 deleteObject:managedObject];
}
NSError * error = nil;
if (![context save:&error])
{
NSLog(#"Error ! %#", error);
}

Related

iOS Nested Context slower on Device

I'm trying to move from one NSManagedContext to multiple via nested context.
I'm using those article to help me :
http://www.cocoanetics.com/2012/07/multi-context-coredata/
http://floriankugler.com/blog/2013/4/2/the-concurrent-core-data-stack
Actual System
[myHTTPClient getPath:path
parameters:#{access_token & stuff}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
for (NSDictionary *dictionary in responseObject)
{
// filling the dic in a NSManagedObject
}
[myMainContext save:&error];
}, failure:failureBlock];
Wanted System
[myHTTPClient getPath:path
parameters:#{access_token & stuff}
success:^(AFHTTPRequestOperation *operation, id responseObject) {
__block NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
__block NSManagedObjectContext *writerObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] writerManagedObjectContext];
__block NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
temporaryContext.parentContext = managedObjectContext;
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
[temporaryContext performBlock:^{
for (NSDictionary *dictionary in responseObject)
{
// filling the dic in a NSManagedObject
}
[temporaryContext save:&error];
[managedObjectContext performBlock:^{
[managedObjectContext save:&error];
[writerObjectContext performBlock:^{
[writerObjectContext save:&error];
}];
}];
}];
}, failure:failureBlock];
Diagram
Problem
I had problems saving my data while using this method but I solved it (cf. https://stackoverflow.com/questions/18151827/coredata-writermanagedobjectcontext-freeze-when-save)
However, as I said in the previous question, it speed up 2 times on the simulator but it's like 5x slower on a device. I use iPod Touch 4th to test.
How is it possible and how can I improve that ?
I'm not against using this diagram :
But I want to find out HOW to integrate that in my code because I tried and it changed nothing.
Thank you.

Display two entities into one table view

i have a custom table view cell. With two labels.
The Label on the right loads its text from an entity. (See picture Below)
-(void)viewWillAppear:(BOOL)animated{
if (self.context == nil)
{
self.context = [(RootAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Entity" inManagedObjectContext:self.context];
[request setEntity:entity];
NSError *error;
NSMutableArray *array = [[self.context executeFetchRequest:request error:&error] mutableCopy];
[self setTableArray:array];
[self.myTableView reloadData];
[super viewWillAppear:YES];
}
And i set the text accordingly as per documentation.
My problem lies when i try to load the second labels text from a different entity, So simply, i tried this:
-(void)viewWillAppear:(BOOL)animated{
if (self.context == nil)
{
self.context = [(RootAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSFetchRequest *sRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Entity" inManagedObjectContext:self.context];
NSEntityDescription *sEntity = [NSEntityDescription entityForName:#"Entity2" inManagedObjectContext:self.context];
[request setEntity:entity];
[sRequest setEntity:sEntity];
NSError *error;
NSError *sError;
NSMutableArray *array = [[self.context executeFetchRequest:request error:&error] mutableCopy];
NSMutableArray *sArray = [[self.context executeFetchRequest:sRequest error:&sError]mutableCopy];
[self setTableArray:array];
[self setSecondTableArray:sArray];
[self.ammoTable reloadData];
[super viewWillAppear:YES];
}
And i set the table View's cell's text via:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * identifier = #"identifier";
self.cell = [tableView dequeueReusableCellWithIdentifier:identifier];
Entity2 *entity2 = [self.secondTableArray objectAtIndex:indexPath.row];
Entity *entity = [self.tableArray objectAtIndex:indexPath.row];
self.cell.rightLabel.text = [[entity.brand stringByAppendingString:#" "] stringByAppendingString:entity.model];
self.cell.leftLabel.text = entity2.numberOfRounds;
return self.cell;
}
and i get this error, when i push this view:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
and i get a SIGABRT error on this line:
Entity2 *entity2 = [self.secondTableArray objectAtIndex:indexPath.row];
Any help would be greatly appreciated, Thank you!
Instead of trying to load 2 different entities, i just added another attribute to the original entity, and i imported/used the newly created attribute in the entity to populate the right label!

Retrieve NSString from core-data error

The app needs to retrieve data from core-data then compare one of the values with an IF STATEMENT
MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *getDetails = [NSEntityDescription entityForName:#"Detail" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:getDetails];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(genID = %i)", genID];
[request setPredicate:pred];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"genID" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sort]];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
for (NSManagedObject *oneObject in objects) {
NSString *type = [oneObject valueForKey:#"type"];
if (type == #"straight") {
NSLog(#"straight");
//straight logic removed
}else if (type == #"Left") {
NSLog(#"Left");
//Left logic removed
}else {
NSLog(#"Else");
//Else logic removed
}
}
The issue is that it never goes into "straight" or "left" always the ELSE. Stepping through the code I can see that values do match straight and left, even dumped them into a log file shows them fine. What is wrong?
You need to compare strings using isEqual: or isEqualToString: or compare:.
For instance:
NSString *type = [oneObject valueForKey:#"type"];
if ([type isEqualToString:#"straight"])
// etc.
Search StackOverflow for "NSString equal" or "NSString compare" if you need more explanation. You aren't anywhere near the first person to ask this question, and you definitely won't be the last.

Error when populating table view with coredata

I am working with coredata and successfully saved the data in data storage but when I try to output what I stored using table view ,I am not able to do it.
Here the user will enter and click save ..so when he goes back..I want the table to populated with what name he or she has entered.
So I wrote the below code for saving and find data:
- (void) saveData
{
coredata123AppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
Contacts *newContact;
newContact = [NSEntityDescription
insertNewObjectForEntityForName:#"Contacts"
inManagedObjectContext:context];
[newContact setValue:name.text forKey:#"name"];
[newContact setValue:address.text forKey:#"address"];
[newContact setValue:phone.text forKey:#"phone"];
name.text = #"";
address.text = #"";
phone.text = #"";
NSError *error;
[context save:&error];
status.text = #"Contact saved";
}
- (void) findContact
{
coredata123AppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
NSEntityDescription *entityDesc =
[NSEntityDescription entityForName:#"Contacts"
inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred =
[NSPredicate predicateWithFormat:#"(name = %#)",
name.text];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request
error:&error];
for(Contacts *info in objects)
{
NSLog(#"Name:%#",info.name);
NSLog(#"Address:%#",info.address);
}
if ([objects count] == 0) {
status.text = #"No matches";
} else {
matches = [objects objectAtIndex:0];
address.text = [matches valueForKey:#"address"];
phone.text = [matches valueForKey:#"phone"];
status.text = [NSString stringWithFormat:
#"%d matches found", [objects count]];
}
[request release];
}
And to populate the table view i have written this code..
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Contacts" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
self.contacts = [context executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
Contacts *info =[contacts objectAtIndex:indexPath.row];
cell.textLabel.text =info.name;
cell.detailTextLabel.text=info.address;
// Configure the cell...
return cell;
}
Are you getting proper number of elements in this objects array?
NSArray *objects = [context executeFetchRequest:request
error:&error];
if not, try changing the predicate with,
[NSPredicate predicateWithFormat:#"name=%#", name.text];
Otherwise, your code seems correct to me.

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) {
...
}