Thursday, December 16, 2010

How to target a specific iPhone version?

 
 
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 3.0)
    {
    // iPhone 3.0 code here
    }

user interface

User Experience Coding How-To's

General

How do I create my user interface?

In general, there are three application styles for iPhone OS: productivity, utility, and immersive. Each style has some common approaches to user interface design, which you can learn about in detail by looking at iPhone Human Interface Guidelines.
When you are ready to start your application, take a look at the templates that Xcode offers and choose the one that matches your application's design.
The fastest way to create your user interface is to use Apple's visual tool, Interface Builder. In it you can assemble your application’s user interface graphically, and then programmatically create any user interface elements not offered by the tool. You can see some examples of how to create a variety of user interface elements by looking at these sample applications:
  • TheElements uses a navigation bar and a toolbar.
  • Metronome uses one standalone UIView object with embedded views.
  • NavBar uses a navigation bar.
For comprehensive information on the classes and methods for creating individual elements, see UIKit Framework Reference.

How do I start my application in landscape mode?

To start your application in landscape mode, edit your Info.plist file to add the UIInterfaceOrientation key with the appropriate value (UIInterfaceOrientationLandscapeRight or UIInterfaceOrientationLandscapeLeft), as shown in Listing 1. This provides a hint to the system to set the orientation of the status bar appropriately at launch time.
Listing 1: Starting your application in landscape mode
<key>UIInterfaceOrientation</key>
    <string>UIInterfaceOrientationLandscapeRight</string>
For detailed information see "Launching in Landscape Mode" in iPhone Application Programming Guide.

How do I enable autorotation?

To use autorotation, you must use a view controller (and subclass it), and the subclass must return YES for the method shouldAutorotateToInterfaceOrientation:. See Listing 2.
Listing 2: Enabling autorotation
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
 return YES;
}
You can also choose whether to allow or deny the rotation, returning YES or NO as appropriate, after considering, for example, the value of UIInterfaceOrientation. See UIApplication Class Reference for the possible values of UIInterfaceOrientation.
You can also enable support for autorotation in Interface Builder:
  1. Open a nib file with a UIWindow already defined.
  2. Drag in a UIViewController from the library to the nib window.
  3. Open (double-click) the UIViewController object.
  4. Set its custom class name to your UIViewController subclass name.
  5. Drag in a empty UIView from the library window into the UIViewController. (Interface Builder will provide visual feedback as the UIView is moved into place inside the UIViewController)
  6. Set or connect the window's view property to be that of the UIViewController's view property
If you are also using a toolbar, the view controller for each toolbar item must implement the shouldAutorotateToInterfaceOrientation: method and return YES for each of the orientations you wish to support. If you have a navigation controller for a toolbar item, the root view controller of that navigation controller must implement the shouldAutorotateToInterfaceOrientation: method and return YES.

How do I flip my interface, as the Weather application does?

To "flip" your user interface, use the setAnimationTransition:forView:Cache: method of the UIView class, and provide the appropriate constant to specify the flip direction (using UIViewAnimationTransitionFlipFromRight or UIViewAnimationTransitionFlipFromLeft).
See the UICatalog sample application and UIView Class Reference.
The "Utility Application" template in Xcode provides a starting point for implementing applications which, like the Weather application, have a "front" and a "back" view.

How do I handle autorotation of my user interface?

For your application to support autorotation, where your interface changes between portrait and landscape orientation, it needs to implement a UIViewController object and override the shouldAutorotateToInterfaceOrientation: method. See "Autorotating views" in View Controller Programming Guide, and the WhichWayIsUp sample code.

How do I internationalize or localize my application's text strings?

To internationalize your application's text strings, you store your localized text in Localizable.strings inside a folder named <language_code>.lproj, where <language_code> is an ISO 639-1 language code (for example, en.lproj or fr.lproj).
You can then obtain the localized text in the user's currently selected language for display using the NSLocalizedString function.
For example, to display the French word for "City" in your interface, you would first add an entry to your fr.lproj/Localizable.strings file, as shown in Listing 3, and then use the code shown in Listing 4 to get the appropriate localized version.
Listing 3: An entry in fr.lproj/Localizable.strings
"City" = "Ville";
Listing 4: Using NSLocalizedString
label.text = NSLocalizedString(@"City", @"Label for City text field");
You can also define the localizable strings in your nib file, and create localized copies of that nib.
See "Internationalizing Your Application" in iPhone Application Programming Guide for more information.


Multi-Touch

How do I handle touch-based input such as tracking the user's finger or detecting multiple touches?

To receive touch input, you instantiate a UIResponder object (typically a view) and add instance methods that handle touches. Your methods are invoked when those touches occur.
You can implement separate handlers for the different "phases" of a touch—when touches begin, move, end, or are canceled by the system. See Listing 5 for the available set of handlers.
Listing 5: Available touch event handlers
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
By default, a view ignores all but the first touch during a multi-touch sequence. If you want the view to handle multiple touches you must enable multiple touches for the view. This can be done programmatically by setting the multipleTouchEnabled property of your view to YES, or in Interface Builder using the inspector for the related view.
For detailed information, see "Event Handling" in iPhone Application Programming Guide and the UITouch Class Reference. For an example of how to handle touch input, see the MoveMe sample application.


Windows, Views, and Controls

How do I detect the screen boundary?

To detect the screen boundary, use the UIScreen class, which contains the bounding rectangle of the device's entire screen. When you set up the user interface for your application, use the properties of this object to get the recommended frame rectangles for your application views.

How do I create a window?

To create a window, use the UIWindow class, as shown in Listing 6.
Listing 6: Creating a window
window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
For more information, see UIWindow Class Reference.

How do I create a window with a navigation controller?

To create a window with a navigation controller, use the UINavigationController class, as shown in Listing 7.
Listing 7: Creating a window with a navigation controller
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[window setBackgroundColor:[UIColor redColor]];
MainViewController *navController = [[MainViewController alloc] init];

// create a navigation controller using the new controller
navigationController = [[UINavigationController alloc] initWithRootViewController:navController];
[navController release];

// Add the navigation controller's view to the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
For more information, see UINavigationController Class Reference.

How do I create a button?

To create a button, use the UIButton class, as shown in Listing 8.
Listing 8: Creating a button
CGRect frame = CGRectMake(0.0, 0.0, 100.0, 40.0);
UIImage *buttonImage = [UIImage imageNamed:@"grayButton.png"];
UIButton *stopButton = [[UIButton alloc] initWithFrame:frame];
[stopButton setTitle:@"Button" forState:UIControlStateNormal];
[stopButton setTitleColor:[UIColor blackColor] forState:UIControlEventTouchDown];
[stopButton setBackgroundImage:buttonImage forState:UIControlStateNormal];
stopButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
stopButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[stopButton addTarget:self action:@selector(stopAction:) forControlEvents:UIControlEventTouchUpInside];
[stopButton setBackgroundColor:[UIColor clearColor]];
// then add the button to a UIView like this:
// [myView addSubview: stopButton];
For more information, see UIButton Class Reference.

How do I create a label?

To create a label, use the UILabel class, as shown in Listing 9.
Listing 9: Creating a label
CGRect labelFrame = CGRectMake(0.0, 0.0, 100.0, 30.0);
UILabel *label = [[UILabel alloc] initWithFrame:labelFrame];
[label setFont:[UIFont systemFontOfSize:12]];
label.textAlignment = UITextAlignmentLeft;
[label setText:@"TextLabel:"];
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor blackColor];
[self.view addSubview:label];
For more information, see UILabel Class Reference.

How do I create a switch?

To create a switch, use the UISwitch class, as shown in Listing 10.
Listing 10: Creating a switch
CGRect frame = CGRectMake(0.0, 0.0, 60.0, 26.0);
UISwitch *switchControl = [[UISwitch alloc] initWithFrame:frame];
[switchControl addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
[switchControl setBackgroundColor:[UIColor clearColor]];
For more information, see UISwitch Class Reference.

How do I create a text field?

To create a text field, use the UITextField class, as shown in Listing 11.
Listing 11: Creating a text field
CGRect textFieldFrame = CGRectMake(0.0, 0.0, 100.0, 30.0);
UITextField *textField = [[UITextField alloc] initWithFrame:textFieldFrame];
[textField setBorderStyle:UITextFieldBorderStyleBezel];
[textField setTextColor:[UIColor blackColor]];
[textField setFont:[UIFont systemFontOfSize:20]];
[textField setDelegate:self];
[textField setPlaceholder:@"<enter text>"];
[textField setBackgroundColor:[UIColor whiteColor]];
textField.keyboardType = UIKeyboardTypeDefault;
For more information, see UITextField Class Reference.

How do I create a text view?

To create a text view, use the UITextView class, as shown in Listing 12.
Listing 12: Creating a text view
CGRect textFieldFrame = CGRectMake(0.0, 0.0, 200.0, 200.0);
UITextView *textView = [[UITextView alloc] initWithFrame:textFieldFrame];
[textView setTextColor:[UIColor blackColor]];
[textView setFont:[UIFont systemFontOfSize:20]];
[textView setDelegate:self];
[textView setBackgroundColor:[UIColor whiteColor]];
textView.keyboardType = UIKeyboardTypeDefault;
For more information, see UITextView Class Reference.

How do I create a web view?

To create a web view, use the UIWebView class, as shown in Listing 13.
Listing 13: Creating a web view
CGRect webFrame = CGRectMake(0.0, 0.0, 200.0, 200.0);
UIWebView *webView = [[UIWebView alloc] initWithFrame:webFrame];
[webView setBackgroundColor:[UIColor whiteColor]];
For more information, see UIWebView Class Reference.

How do I create a view for images?

To create a view for images, use the UIImageView class, as shown in Listing 14.
Listing 14: Creating a view for images
UIImage *image = [UIImage imageNamed:@"image.png"];
UIImageView *theImageView = [[UIImageView alloc] initWithImage:image];
For more information, see UIImageView Class Reference.

How do I create a slider?

To create a slider, use the UISlider class, as shown in Listing 15.
Listing 15: Creating a slider
CGRect frame = CGRectMake(0.0, 0.0, 200.0, 10.0);
UISlider *slider = [[UISlider alloc] initWithFrame:frame];
[slider addTarget:self action:@selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
[slider setBackgroundColor:[UIColor clearColor]];
slider.minimumValue = 0.0;
slider.maximumValue = 50.0;
slider.continuous = YES;
slider.value = 25.0;
For more information, see UISlider Class Reference.

How do I create a segmented control?

To create a segmented control, use the UISegmentedControl class, as shown in Listing 16.
Listing 16: Creating a segmented control
NSArray *arrayOfImages = [NSArray arrayWithObjects: [UIImage imageNamed:@"segment1_Image.png"],
                                                    [UIImage imageNamed:@"segment2_Image.png"],
                                                    [UIImage imageNamed:@"segment3_Image.png"],
                                                    [UIImage imageNamed:@"segment4_Image.png"], nil];

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems: arrayOfImages];
CGRect frame = CGRectMake(0.0, 120.0, 300.0, 44.0);
[segmentedControl setFrame:frame];
[segmentedControl addTarget:self action:@selector(action:) forControlEvents:UIControlEventValueChanged];
For more information, see UISegmentedControl Class Reference.

How do I create a page control?

To create a page control, use the UIPageControl class, as shown in Listing 17.
Listing 17: Creating a page control
CGRect frame = CGRectMake(0.0, 0.0, 200.0, 40.0);
UIPageControl *pageControl = [[UIPageControl alloc] initWithFrame:frame];
[pageControl addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
[pageControl setBackgroundColor:[UIColor clearColor]];
pageControl.numberOfPages = 10;
For more information, see UIPageControl Class Reference.

How do I create a table view?

To create a table view, use the UITableViewclass, as shown in Listing 18.
Listing 18: Creating a table view
UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] 
                                                      style:UITableViewStylePlain];

tableView.delegate = self;
tableView.dataSource = self;
tableView.rowHeight = 54;
[tableView reloadData];
For more information, see UITableView Class Reference. See also the TableViewSuite sample application.

How do I add buttons to the UINavigationController?

If your application has a UIViewController object that uses a UINavigationController object, you can add custom buttons in your loadView method. See Listing 19.
Listing 19: Adding buttons to the UINavigationController object
// add our custom add button as the nav bar's custom right view
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                                                                           target:self 
                                                                           action:@selector(addAction:)];
self.navigationItem.customRightItem = addButton;
[addButton release];
For more information, see UINavigationController Class Reference.

How do I display an alert view, action sheet, or modal view?

Alerts, action sheets, and modal views are types of views that appear when something requires the user's attention or when an application needs to offer additional choices or functionality to the user. iPhone Human Interface Guidelines provides examples of what each view looks like, along with guidelines for when to use each type.
Use the UIAlertView class to inform users about a problem or a change in the current situation. For example, Mail shows an alert view when it is unable to connect to the user's mail server. See UIAlertView Class Reference.
Use the UIActionSheet class to provide users with additional choices related to the action they are taking. For example, Safari uses an action sheet to provide users with the options to add a link to bookmarks, add a link to the Home screen, or mail a link. See UIActionSheet Class Reference.
Use the UIViewController class when you want to provide more extensive functionality in the context of the current task, or as a way to perform a subtask directly related to the user's workflow. For example, Mail provides a modal view that allows a user to compose a new mail message. For a modal view, you use the presentModalViewController:animated: method of UIViewController to display view controller as a modal child of another view controller. See the UIViewController Class Reference.
You can see examples of how to implement several of these views by looking at the UICatalog sample application.

iPhone Programming Tutorial – Local Notifications


Way back when, when everyone was still complaining about Apple’s lack of support for (3rd party) multitasking, there was a simple solution put in place. This solution was known as push notifications.
Push notifications solved many of the issues associated with background processing.  For example, when quitting the AIM application, the server could keep you logged in and send you a push notification when a new message arrived.  You could then tap on a View button that would launch the app.
This solution is great and all, but it still requires that you have an active internet connection.  As of iOS4, Apple has introduced a new type of notification that can be scheduled to fire within the device itself.  It requires no complicated server programming, or additional configuration with iTunes.  I am talking about Local Notifications.
Local notifications can be scheduled on the user’s iDevice to fire at any given time; you can even set them to be recurring.  Today, we will explore these notifications and I will provide you with a simple example of how to schedule, view, and handle local notifications.  Here is a quick screenshot of the project that we are going to create (note I am using the iPhone 4  simulator).
The project will allow a user to schedule a location notification to fire off at a given date.  Using the text field, they are also able to specify some text for the notification.  The table view below displays a list of all of the currently scheduled location notifications within the application.
So, by now (if you are an avid iCodeBlog reader), you are already a killer iPhone dev and I can rush through the stuff that is not related to the notifications.  I will try to provide links to tutorials about sections that I rush through as well.

1. Create a View-Based Application

We will be using this as our starting point.  Check out this tutorial if you are unfamiliar with doing this.  Name the project Notifier.

2. Create All Properties and Dummy IBActions

This is usually a good first step when tackling an application like this.  Let’s get everything set up in the .h and .m files so we only have to visit Interface Builder Once.  Here is what our NotifierViewController.h file looks like.
@interface NotifierViewController : UIViewController&lt;UITableViewDelegate,UITableViewDataSource&gt; {
 IBOutlet UITableView *tableview;
 IBOutlet UIDatePicker *datePicker;
 IBOutlet UITextField *eventText;
}
 
@property (nonatomic, retain) IBOutlet UITableView *tableview;
@property (nonatomic, retain) IBOutlet UIDatePicker *datePicker;
@property (nonatomic, retain) IBOutlet UITextField *eventText;
 
- (IBAction) scheduleAlarm:(id) sender;
 
@end
Seems clear enough.  We have 3 UI elements that we care about and one action.  One thing to note is, your class should implement the UITableViewDelegate and UITableViewDataSource protocols.  This is because we will be displaying a tableview containing all of the scheduled alarms.
Now, do all of the necessary steps in your .m file.  This includes memory management for the IBOutlets and creating a dummy method for the scheduleAlarm IBAction.  Your .m file should look something like this. Note: I have omitted import statements because my syntax highlighter wasn’t digging them.
@implementation NotifierViewController
 
@synthesize datePicker,tableview, eventText;
 
- (IBAction) scheduleAlarm:(id) sender {
 
}
 
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
 
- (void)viewDidUnload {
 datePicker = nil;
 tableview = nil;
 eventText = nil;
}
 
- (void)dealloc {
    [super dealloc];
}
 
@end
Now it’s time to build our interface.  Open Interface builder and construct an interface like this.
If you want my super sweet green button image, here it is:
After creating the interface, make sure you hook up all of the UI components to their corresponding IBOutlets and hook up the touchUpInside: method of the button the your scheduleAlarm: IBAction.  For more info on hooking up IBOutlets, check out this tutorial.

3. Implement UITableViewDelegate and UITableViewDataSource Delegate methods to List Currently Scheduled Local Notifications

It may seem weird to implement the code to display the notifications before the code that creates them, however I like this approach better.  This way, once we schedule the notifications, they automagically appear in our table.  Add the following code to your .m file.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // We only have one section
    return 1;
}
 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of notifications
    return [[[UIApplication sharedApplication] scheduledLocalNotifications] count];
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
    static NSString *CellIdentifier = @"Cell";
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }
 
    // Get list of local notifications
    NSArray *notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
    UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];
 
    // Display notification info
    [cell.textLabel setText:notif.alertBody];
    [cell.detailTextLabel setText:[notif.fireDate description]];
 
    return cell;
}
OK, finally some “real” code.  Most of this code should seem pretty straight forward.  If not, check out this tutorial on UITableViews.
So, the new code here is dealing with retrieving a list of scheduled notifications.  Calling the scheduledLocalNotifications method of UIApplication will return an NSArray of all notifications scheduled by the current app.  We just index into this array and grab each notification.
Finally, we are displaying the alertBody (text that displays when the notification fires) and the fireDate (date and time when the notification will display) in the tableview cell.

4. Scheduling Notifications

And now for the moment you’ve been waiting for… OK, probably not, but definitely the most exciting (least boring) part of this tutorial.  Let’s implement that scheduleAlarm: IBAction that you framed out earlier.  Update your .m file to contain the following code.
- (IBAction) scheduleAlarm:(id) sender {
    [eventText resignFirstResponder];
 
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
 
    // Get the current date
    NSDate *pickerDate = [self.datePicker date];
 
    // Break the date up into components
    NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit )
               fromDate:pickerDate];
    NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit )
               fromDate:pickerDate];
    // Set up the fire time
    NSDateComponents *dateComps = [[NSDateComponents alloc] init];
    [dateComps setDay:[dateComponents day]];
    [dateComps setMonth:[dateComponents month]];
    [dateComps setYear:[dateComponents year]];
    [dateComps setHour:[timeComponents hour]];
 // Notification will fire in one minute
    [dateComps setMinute:[timeComponents minute]];
 [dateComps setSecond:[timeComponents second]];
    NSDate *itemDate = [calendar dateFromComponents:dateComps];
    [dateComps release];
 
    UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil)
        return;
    localNotif.fireDate = itemDate;
    localNotif.timeZone = [NSTimeZone defaultTimeZone];
 
 // Notification details
    localNotif.alertBody = [eventText text];
 // Set the action button
    localNotif.alertAction = @"View";
 
    localNotif.soundName = UILocalNotificationDefaultSoundName;
    localNotif.applicationIconBadgeNumber = 1;
 
 // Specify custom data for the notification
    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:@"someValue" forKey:@"someKey"];
    localNotif.userInfo = infoDict;
 
 // Schedule the notification
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
    [localNotif release];
 
 [self.tableview reloadData];
}
So, most of the explanation is in the comments.  I’ll talk you through some of the less obvious stuff.  The first tricky area is dealing with the NSCalendar.  We just use the NSCalendar object to break up the date into components.  Note: This demo does not require that we break the date up into components.  You could have just as easily fed the date from the date picker into the notification fireDate.  The reason that I’m showing you how to break it down is, you may have some sort of custom date logic to work with and this makes things much easier in the future.
Another important bit of code is where we set the alertBody or the notification.  In this example we set it to the text that the user entered into the text field.  You can set this to whatever you like.
The other thing I want to mention is the infoDict in the code.  This dictionary is your chance to associate some additional information with the alert.  For example, if you are using this alert in a game like We Rule to notify you when a crop is ready.  You might want to set a key and value that contains the id of the crop that has completed.  For now, we just set some arbitrary values and you can ignore them if you like.
After actually scheduling the notification, we just reload the tableview to get it to display immediately.

5. Handling Notifications After They Fire

The last piece of this puzzle is determining what to do when a notification fires.  Fortunately, this step is very easy and handled inside of the appDelegate.  When a notification fires, there are one of two situations. 1. The app is running and 2. The app is not running (or running in the “background”) .
Open up your app delegate .m file and add the following code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 
    // Override point for customization after application launch.
 
    // Add the view controller's view to the window and display.
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
 
    application.applicationIconBadgeNumber = 0;
 
    // Handle launching from a notification
    UILocalNotification *localNotif =
    [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotif) {
        NSLog(@"Recieved Notification %@",localNotif);
    }
 
    return YES;
}
 
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
    // Handle the notificaton when the app is running
    NSLog(@"Recieved Notification %@",notif);
}
The first thing we see here is the application badge number is getting set to 0.  Whenever a notification fires, it will increase the badge count on the application.  Next, we handle the case when the application launches from a notification.   This happens when the user presses the view button on the notification.  For now, we just NSLog the data, but you should handle the notification how you see fit for your app.
Finally, we implement the didReceiveLocalNotification method.  This method is required if you want to handle notifications at all in your app.  You will see this method fire when the app is running and you receive a local notification.  When the app is running, you will not see the UIAlertView show up with the notification data.