In xcode, I am trying to add some way to log what is deleted from a tableview.
Here is my delete code
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSManagedObjectContext *context = [self managedObjectContext];
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete object from database
[context deleteObject:[self.contacts objectAtIndex:indexPath.row]];
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
}
NSManagedObject *device = [self.contacts objectAtIndex:indexPath.row];
NSLog(#"Deleting %# ", [device valueForKey:#"name1"]);
// Remove contact from table view
[self.contacts removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
all fairly standard stuff except for these two lines
NSManagedObject *device = [self.contacts objectAtIndex:indexPath.row];
NSLog(#"Deleting %# ", [device valueForKey:#"name1"]);
I'm trying to access the data in the fields in this row before it is deleted, but NSLog returns null. I've tried other variations, and had one version that returned the variables in the previous row!
What am I missing here?
You are trying to print an object after you have deleted it and committed this action by saving.
You could just move the following lines:
NSManagedObject *device = [self.contacts objectAtIndex:indexPath.row];
NSLog(#"Deleting %# ", [device valueForKey:#"name1"]);
above your call to [context save:&error]
It seems to me you are trying to access the data after you have deleted it. Move this
NSManagedObject *device = [self.contacts objectAtIndex:indexPath.row];
NSLog(#"Deleting %# ", [device valueForKey:#"name1"]);
before this
[context deleteObject:[self.contacts objectAtIndex:indexPath.row]];
Related
I am new to IOS i need to know how to create prefetched data to save in tableview.New entry data to be saved successfully.Prefetched data stored in array[currarray] that data how to save in tableview using core data.
Coding for save method:
- (IBAction)save:(id)sender {
NSManagedObjectContext *context = [self managedObjectContext];
// Create a new managed object
NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:#"Device" inManagedObjectContext:context];
//[newDevice setValue:self.amountTxt.text forKey:#"amount"];
[newDevice setValue:self.nameTextFeild.text forKey:#"name"];
[newDevice setValue:self.companyTextFeild.text forKey:#"company"];
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
[self dismissViewControllerAnimated:YES completion:nil];}
coding for tableview:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"Cell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSManagedObject *device = [self.devices objectAtIndex:indexPath.row];
cell.namelbl.text = [device valueForKey:#"name"];
cell.companylbl.text = [device valueForKey:#"company"];
return cell;
}
So basically I have a table view of folder objects and I want to be able to remove/ delete folders. So far if I try to delete, the folders are removed, but when I re run the application they are all back (so the delete is not saved). Any advice?
here is my delete method for the UITableView:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[self.folders removeObjectAtIndex:indexPath.row];
NSMutableArray *newSavedFolders = [[NSMutableArray alloc] init];
for (Folder *folder in self.folders){
[newSavedFolders addObject:[self folderWithName:folder.name]];
}
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
and the folderWithName method is from here:
- (Folder *)folderWithName:(NSString *)name {
id delegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [delegate managedObjectContext];
Folder *folder = [NSEntityDescription insertNewObjectForEntityForName:#"Folder" inManagedObjectContext:context];
folder.name = name;
folder.date = [NSDate date];
NSError *error;
if (![context save:&error]) {
//we have an error
}
return folder;
}
The reason it deletes is because of this line:
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
That removes the row from view, but doesn't remove the data.
If your using CoreData then you simply do the following with a NSFetchedResultsController:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
[self.tableView reloadData];
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
}
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
Add call your items with the NSFetchedResultsController this way:
#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:#"Folder" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number for displaying in UITableView.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = #[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return fetchedResultsController;
}
i'm trying to delete an object in core data when you press swipe and press delete. The problem is it deletes the the tablecell, but when i go back and in again the deleted cells are back again. I guess thats because i only deleted the object in the NSMUtableArray (devices) and did not delete the core data object. How can i do this?
The saveTap where the objects are saved:
-(void)saveTap:(id)sender{
Entity *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:#"Entity" inManagedObjectContext:_managedObjectContext];
[newManagedObject setValue:self.textfield.text forKey:#"playlistName"];
[newManagedObject setValue:[NSNumber numberWithInt:selectedRowValue] forKey:#"idnumber"];
// Save the context.
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
[self fetchDevices];
NSLog(#"COUNT %d", [devices count]);
}
and the commiteditingstyle method
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.devices removeObjectAtIndex:indexPath.row];
[tableViewData reloadData]; }
}
Is [self.devices objectAtIndex:indexPath.row]; returning that NSManagedObject you want to delete?
Then you should make the second function like this:
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_managedObjectContext deleteObject:[self.devices objectAtIndex:indexPath.row]];
[_managedObjectContext save:nil];
[self.devices removeObjectAtIndex:indexPath.row];
[tableViewData reloadData]; }
}
Instead of reloading while of UitableView you should only reloadrowatindexpaths: and before it [UITableView beganEditing];
And after Reloading rows
[UITableView endEditing];
I am writing a simple app which lets users add entries to a database. The data is displayed in a UITableView. What I can't figure out is how to delete just one record from the database using the swipe-to-delete functionality of a tableview. I know that the code goes in this method:
-(void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
}
But I don't know how to fetch the record of the database that populates the cell that has been swiped.
I have a method which deletes all cells when the user clicks on a button on the navigation bar:
-(void)deleteAll {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Parameters" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *managedObject in items) {
[context deleteObject:managedObject];
}
if (![context save:&error]) {
}
[self.tableView reloadData];
}
But I don't how to customize this code to delete one record at a time. Any help to get me started would be appreciated.
I have this method as well...I would think this would delete the record permanently but it doesn't...
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[self.arr removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
[self.tableView reloadData];
}
I have done the same swipe to delete functionality using MCSwipeTableCell
For deleting a particular row from table with animation do this:
//I am passing 0,0 so you gotta pass the row that was deleted.
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:0 inSection:0]
[self.yourTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
For deleting from core data do this:
YourCustomModel *modelObj;
NSManagedObjectContext *context= yourmanagedObjectContext;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"YourCustomModel" inManagedObjectContext:context]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"yourField == %#", passTheFieldValueOfTheRowDeleted];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
if ([results count]>0)
{
modelObj = (Customers *)[results objectAtIndex:0];
}
[context deleteObject:modelObj];
if (![context save:&error])
{
NSLog(#"Sorry, couldn't delete values %#", [error localizedDescription]);
}
You are almost there.. Just add a predicate to the fetch request.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(somePropertyInParameters = %d)",value];
[fetchRequest setPredicate:predicate];`
Also, you can get the index path of the swiped cell (and the Parameter object) in this method
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath`
when I remove one row from my TableView with this code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
NSError *error = nil;
NSLog(#"Rows before deletion: %d", [[self.fetchedResultsController fetchedObjects] count]);
NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.managedContext deleteObject:obj];
NSLog(#"Rows before save: %d", [[self.fetchedResultsController fetchedObjects] count]);
if (![self.managedContext save:&error]) {
NSLog(#"Error while deleting time: %s", error.localizedDescription);
}
NSLog(#"Rows after save: %d", [[self.fetchedResultsController fetchedObjects] count]);
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
Then I get the following Error. What could be the reason? The count of objects is everytime the same. Why the context don't get this information of the removed object. Wasn't it automatic?
The error is that the count of rows after the row deletion must be plus or minus the removed/added rows.
Thanks
After saving your context, you a have to re-execute your request to "update" your self.fetchedResultsController.
if (![self.managedContext save:&error]) {
NSLog(#"Error while deleting time: %s", error.localizedDescription);
}
self.fetchedResultsController = ...
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
...