Disable persistence of a given NSManagedObject until user hits a button? - iphone

I have an NSManagedObject with attributes that a user can edit with a view. The view is populated with the values from the object, the user can edit the values, and the values are written back to the object. I want the user to explicitly tap a save or cancel button to commit or undo the changes.
The problem is that the view is in a UITabbarController where other things are going on. The user might perform operations in another tab where [NSManagedObjectContext save] or [NSManagedObjectContext undo] might get called. This would affect the NSManagedObject (from the first mentioned tab) before the user decides if they want to save or cancel it.
Is there a way around this? Can we temporarily disable persistence on an NSManagedObject until the user taps the button?

There is no way to disable persistence for a managed object. Instead I would recommend an approach like this:
Typically, when showing a view that edits a particular object, you update that view with the data from the object in the viewWillAppear: method and update the object with the changed data in a corresponding "save" action or viewWillDisappear:.

Related

Pass an NSFetchedResultsController as a property

I have a workflow in my app where the user will build a compound filter and then press a button to view the results of the filter.
In the screen that builds the filter they get to select from a list of fields and set what the value should be. There is also a UILabel that shows how many results match the currently selected filter.
I use an NSFetchedResultsController to make it easier to get the count and change the predicates etc...
When the user presses "Next" (or whatever the button is labelled) they will then view a TableView with those results in it.
Is it bad practise to pass the NSFetchedResultsController in to the tableViewController?
Or should I just pass the information required to build a new NSFetchedResultsController (i.e. the NSPredicate).
I can do either just not sure if there are any pros/cons of either method?
NSFetchedResultsController has a delegate on it. You will have to assign a new delegate when passing the NSFetchedResultsController, and you will have to assign the delegate again when removing the view controller you presented base on the pressing of that button. Keep also in mind that when you are changing the predicate of the NSFetchedResultsController's fetch request, you are performing another fetch. Basically, you are complicating your architecture while gaining basically nothing. Create a new NSFetchedResultsController object.
NSFetchedResultsController is really what u need for tableView.

Core data, validateForInsert: / validateForUpdate: create an entity even when they cancel

iPhone forms, where do you put your validation?
People suggested me to directly put the value of my textfields in my core data entity, which I did (see my second edit). Thing is, when a person update an entity, since I put directly the value that the user is typing in my entity, even when I don't save my ManagedObjectContext, my TableViewController (using NSFRC) updates with the latest infos the user entered (even if he pressed cancel). If I restart the app, since it didnt save, everything is back to normal.
How can I avoid this?
I'm assuming you are using the same NSManagedObjectContext for both viewControllers. You could use a separate NSManagedObjectContext for each viewController. If you are using iOS 5.1 set the 1st viewController's managedObjectContext (MOC) as the parent of the 2nd viewControllers managedObjectContext. So if you save the 2nd view's MOC via [theContext save], it will merge the changes with the 1st MOC automagically. If you don't want to keep the changes simply pop that view off the navigation stack.
MOC's are scratchpads. So in essence you want to use that 2nd viewController as a scratch pad, until you hit save.

Deleting rows UItableview iphone using userdefaults

I need your help, maybe its something silly but I can't find the error.
I have a table view and an add button, when its clicked I show a modal view with a little form, when save button is pressed I send the data to the TableView controller to show it, also I'm using NSUserDefaults to save this data in an array.
My problem comes when, for example, I add 2 new rows and delete 1 of them, then when I add another, it shows the last row I delete instead of showing the one I just add.
I'm doing the saving and reading this way:
in viewDidAppear I read the NSUserDefaults and get the data if exist.
in the method that catches the data from the ModalView I save to userdefaults.
in commitEditing method I read userdefaults and then delete the row from the array and from the table and then save this change in userdefaults.
I don't know what I doing wrong, Can anybody help me with this?
Use [self.tableView reloadData]; in the viewWillAppear of that class. You can also reference that class in another view controller, create an object for it and call [classObject.tableView reloadData];
Always remember to reload the tableView after an add operation or a delete operation.
Don’t use NSUserDefaults to act as the direct datasource of a table. Store it in an intermediate model. It’ll be a LOT easier to debug that way.
If you’re having trouble keeping your model synced with the user defaults, call [[NSUserDefaults standardUserDefaults] synchronize] whenever you alter them.
Also, make sure you’re not making some mistakes in your table cell reuse. You might be seeing old data if you have a customer UITableViewCell class and you’re not correctly implementing -prepareForReuse.

How to reset an iOS application state after a user clicks sign out?

So I posted a question a while back which can be seen at: How to reset an iOS application when a user clicks the "sign out button"?
Following the advice I made a sign out button where a user where by is taken to the main screen where they can register or sign in again. What I am finding out is that when a new user signs in, I am seeing certain value from the old user in pickers, UITextView ETC
Is there a way to reset application state or do I have to go the long route of making sure that each outlet is set to default values? Is this a sign of bad programming practice somewhere?
The Cocoa way = KVO (key value observing). Controllers interested in being informed about login state change register themselves as observers on login component/controller/whatever instance does the login.
After login/logout this component notifies all observers about state change. Those then do all necessary actions: populating UI with user data after log in or resetting them after log out.
Very flexible pattern that avoids unnecessary dependencies between components.
Ok first thing you have to do is make your main view implement the delegate for signout successful. In this you got to reset all the data and views which will be recreated/repopulated when a new user signs in.
Inorder to achieve this you can analyse your code/logic as to what is created on a new user sign in and reset all these in the delegate method for sign out. This is way to generic an answer but resetting the data is the way to do it.
Alternatively you can recreate your main view when sign in is successful i.e. remove the main view and on sign in success create it afresh for the new user.
The cleanest way would be to create a new set of view controllers and set them to the viewControllers of the UITabBarController object but it needn't be the cheapest always. This will be something that you need to check if it's viable or not.
Otherwise, you'll have to to consider adding reset methods to the view controllers. If the tab is a navigation controller, popToRootViewControllerAnimated: and reset the first view controller. This one is a bit of effort to implement compared to the former approach.
When ever you go to new controller just allocate the whole controller again. and dont forget to release once the navigation is done.
Heres the sample code example to do it
-(void)goToFormController
{
FormViewController *objFormViewController = [[FormViewController alloc]initWithNibName:#"FormViewController" bundle:nil];
[self.navigationController pushViewController:objFormViewController animated:YES];
[objFormViewController release];
}
Happy iCoding...

General advice on tracking an object's changes

I have an option menu where a user can change the application's settings. I need to track the changes. There is a DONE button, I want to make changes to the data model only when the button is pressed.
My question is, I am not sure the best way to track the changes. I don't want to introduce a giant if blocks in the doneButtonPressed button. Any general advice?
Well, the generic answer is: add callback to your controls in your options screen.
For example if you are using UISlider, then you have to customize it slightly. Probably create a subclass, that would receive touch events and then you redirect them to the delegate. OR you can use this one: RCSwitch
If you are using UIButton's then it's even easier: just add action to it.
After that you can create method like:
-(void) controlDidChange:(UIView*) control {
//mark changed items here
}