iPhone Data Persistence, syncing views

It’s iPhone blog time! and I’m going to comment on a lab I recently had in an Apple Development class covering data persistence and syncing multiple views from a tab bar controller.  It also covered a little on Alerts, and instantiating UIViewController from another view file for the sake of updating its information before it is viewed again.

I had some difficulties getting the views to reload after the data source was updated in another view (in this case a simple array based plist file was the data source).  However, I managed to find a magic method that each view has in order to simplify the process. Also, I’m posting some notes on implementing a simple alert dialog that pops up on the iPhone and offering some links to others peoples sites that went more involved.

Initializing from Resources / Saving to user’s Documents

We learned one concept that can allow you to store default values in a stored file in your ‘resources’ directory for your iPhone application.  The trick is that you can only read from this file and cannot update it.  This of course, is an ideal method however to be able to store initialization settings that are never updated.  What I chose to do is to use this file to not only restore default values when the users selects to do so, but I use it as a source for loading the user’s own writable settings file on first run of the program.

There are dedicated method calls that allow to you retrieve these directory paths, so you will see the code for that hear aswell.

These are my helper methods which resolve the directory paths:

- (NSString *)getDocsPathAndFileName:(NSString *)docsFileName {
 return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
          stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@.plist",docsFileName]];
}

- (NSString *)getResourcePathAndFileName:(NSString *)fileName{
 return [[NSBundle mainBundle] pathForResource:fileName ofType:@"plist"];
}

These are my programmed calls to retrieve the Resource data, and store it in the documents area.

NSArray *tickets = [NSArray arrayWithContentsOfFile:[self getResourcePathAndFileName:@"Tickets"]];
[tickets writeToFile:[self getDocsPathAndFileName:@"Tickets"] atomically:YES];

I’m sure there is a better way to actually just copy the file from one directory to the next, but this solution works to.  As I improve and have more time, I’ll start developing some more effective code.  In the meantime, this works.

Updating Views (to sync data changes)

Now I had 3 views linked off a Tab Bar controller and needed two of them to resync off of the plist file’s contents whenever the view’s were re-displayed by the user from the Tab Bar buttons.  Our instructor offered us a method involving creating an instance of the other Views that are linked from the Tab Bar, but in all of my attempts, I just couldn’t get the views to update properly.  So, I’m still aiming to figure that out, because it worked for him, but this way that I found was rather smooth, and required no complicated instantiations of other views.  The quick answer is here on Apple’s own docs.  However, here is the code in action and what I did to accomplish it.

- (void)viewDidAppear:(BOOL)animated{
 [super viewDidAppear:YES];
 [self rebuildPickerDS];
 [self clearLabel];
}

viewDidAppear:
Originally I found a way to trigger “viewDidLoad” which was a default method call that appears in some of Apple’s templates for building iPhone app’s.  That method will run first before this one.  ViewDidAppear will always run when the user selects to actually view the page that its controller is managing.  So if your user is on page 2, and they select on your tab bar to go to page 1, then at the time they click the tab bar, the view will run the code in that method.  In the case of “viewDidLoad”, this only runs the first time the person selects that particular view, and even when you trigger it remotely from another view, it won’t update what the person sees.  It’ll maintain is visual state.  “viewDidAppear”, will in fact update the visual state of the view.

iPhone Alerts!

The dreaded pop-up alert box.  Nonetheless, it needs to be done.  Apple has some other nice methods of working with these types of situations, but here is an example of an alert in action.

First:  create a method that receives an IBAction so that it can be linked to a button event on your GUI front-end.  This method will create an “Alert” instance and then prompt to “show” it.

- (IBAction)reset:(id)sender{ // call the alert message
 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Reset Values?"
 message:@"Do you really want to do that!"
 delegate:self cancelButtonTitle:@"Cancel"  otherButtonTitles:@"OK", nil];
 [alert show];
}

Pretty simple, right!  Now, create a local handler that will act on the person button selection choices that you’ve given for them above.

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
  if(buttonIndex != [alertView cancelButtonIndex]){
    // something to do in order to accommodate them choosing "OK"
  }
}

Other People’s Solutions

Here are some other sites that had nice solutions that related to this post.  From the collection of them I was able to determine how to implement the above items, so for that I say thank you to them.

Here is a nice link programmatically, take someone to a different view via a Tab Bar controller: accessing view controllers within a TabController

Another UITabBarController item: User Customized Tab Order

An customer Alert class for handling alerts:  Alert view with prompt

This is the one that gave me the clearest understanding of alerts, but also went into some great customization of an alert box:  Alert with Textfields

Enjoy!

About Andrew Grimo

Currently working for Oracle in Canada, happily associated to the MySQL team as a Principal Solution architect serving Canada and beyond. See my blog on MySQL at https://thesubtlepath.com
This entry was posted in _Old Archived Posts. Bookmark the permalink.

Leave a comment