NSNotificationCenter Tutorial – using the notification center in your iPhone app.

In this tutorial we will be using the NSNotificationCenter to help us load some xml into a UITextView. We’ll be using the same xml feed that we used in the parsing xml tutorial. A lot of this tutorial is just building the app that we’ll use in the tutorial and has nothing to do with the NSNotificationCenter itself. Because of this I will be going through that part pretty quickly without much explanation.

Hope you find this helpful, if you have any questions feel free to ask.

Simulator Shot

1.) Create a new View-based Application and name it NotificationCenterTutorial.

2.) Open up NotificationCenterTutorialViewController.h. We are going to add an IBOutlet for a UITextView, a variable for our own XMLParser we’ll create, and two actions.

#import 
#import "XMLParser.h"

@interface NotificationCenterTutorialViewController : UIViewController 
{
	UITextView				*textView;
	XMLParser				*xmlParser;
}

@property (nonatomic, retain) IBOutlet	UITextView		*textView;
@property (nonatomic, retain)			XMLParser		*xmlParser;

- (IBAction) populateTextView;
- (IBAction) buttonClicked;

@end

3.) Open up NotificationCenterTutorialViewController.m. First we’ll synthesize our variables we created in the header file. Then we’ll implement our actions. I’ve stripped this file to just the basics to make it easy for us. Here’s what it looks like at this point.

@implementation NotificationCenterTutorialViewController

@synthesize textView;
@synthesize xmlParser;


- (void)viewDidLoad 
{
    [super viewDidLoad];

}


- (IBAction) buttonClicked
{
	xmlParser = [[XMLParser alloc] loadXML:@"http://api.twitter.com/1/statuses/user_timeline/KentFranks.xml"];
}

- (IBAction) populateTextView
{
	textView.text = xmlParser.dataReceived;
}


- (void)dealloc 
{
    [super dealloc];
}

@end

4.) We need to create our XMLParser object, so right click on classes and create a new Objective-C class with NSObject as it’s subclass. Name this file XMLParser.

Create new object

5.) In XMLParser.h we’re going to create two variables and an action and implement the NSXMLParserDelegate protocol.

#import 

@interface XMLParser : NSObject 
{

	NSMutableString *dataReceived;
	NSXMLParser		*parser;
}

@property (nonatomic, retain) NSMutableString *dataReceived;

-(id) loadXML:(NSString *)urlString;


@end

6.) In XMLParser.m we’ll synthesize our variable, implement our loadXML action and three connection actions from the NSXMLParserDelegate protocol.

#import "XMLParser.h"

@implementation XMLParser
@synthesize dataReceived;

- (id) loadXML:(NSString *)urlString
{
	NSLog(@"***** loadXML *****");
	NSURL *url = [NSURL URLWithString:urlString];
	
	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0];   
	
	NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
	
	if (theConnection) 
	{
		NSLog(@"***** theConnection was successful *****");
	} 
	else 
	{
		NSLog(@"***** theConnection was unsuccessful *****");
	}
	return self;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{
	NSLog(@"***** didReceiveResponse *****");
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
	NSLog(@"***** didReceiveData *****");
	dataReceived = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
	NSLog(@"***** dataReceived = %@ *****", dataReceived);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{
	NSLog(@"***** connectionDidFinishLoading *****");
	[connection release];
	
	[[NSNotificationCenter defaultCenter] postNotificationName:@"xmlFinishedLoading" object:nil];
}

@end

I’m running through this pretty quick and without much detail because we’re just trying to get an app together that can demonstrate the NSNotificationCenter, and none of this has anything to do with that yet.

7.) Now let’s create our user interface. Double click NotificationCenterTutorialViewController.xib in the Resources folder and open it up in Interface Builder.

8.) Add a UIButton to the top and a UITextView to the rest of the view. I have also changed the background color and gave a little margin around the UITextView. Here’s what mine looks like, just make sure yours is somewhat similar.

UI view

Link the textView to the IBOutlet we created in our view controller header file. And the button to the IBAction buttonClicked.

Connections Inspector

9.) Save everything in Interface Builder and close it. Back in Xcode we can click build and run now and look in the console and we’ll see that we’re getting XML back from our call to my twitter account.

Console

We want to display that XML in the UITextView we created.

10.) If you look in XMLParser you’ll see we have a NSMutableString named dataReceived and we’re setting that variable in the didReceiveData method.

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
	NSLog(@"***** didReceiveData *****");
	dataReceived = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
	NSLog(@"***** dataReceived = %@ *****", dataReceived);
}

We’re going to put that dataRecieved string into our UITextField.

11.) Go into NotificationCenterTutorialViewController.m and find the buttonClicked method. We’ll try to call our populateTextView from here.

- (IBAction) buttonClicked
{
	xmlParser = [[XMLParser alloc] loadXML:@"http://api.twitter.com/1/statuses/user_timeline/KentFranks.xml"];
	[self populateTextView];
}

12.) Just to see when our populateTextView method is getting called let’s add a log statement to it.

- (IBAction) populateTextView
{
	NSLog(@"populateTextView");
	textView.text = xmlParser.dataReceived;
}

13.) Now run the app again and look in the console. You’ll see that the populateTextView gets called after the connection was made, but before didReceiveData was called, and out UITextView was never populated. This is because our connection and the call to get the XML is asynchronous.

We call loadXML and it goes into the XMLParser and we see that the connection was successful, but before the didReceiveResponse or didReceiveData methods are done, our code has gone on and called populateTextView. The problem is when it get’s called the XML hasn’t been returned yet so there is nothing to populate the UITextView with.

Console showing we called method

14.) What we need is a way to hold off on calling populateTextView until after didReceiveData is finished doing it’s business. This is where the NSNotificationCenter comes in. We are basically going to be having our XMLParser object tell our view controller when it is okay to call populateTextView.

It’s a two step process to accomplish this.

15.) In our viewController implementation file (NotificationCenterTutorialViewController.m) we are going to add a notification observer to the viewDidLoad method.

- (void)viewDidLoad 
{
    [super viewDidLoad];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(populateTextView) name:@"xmlFinishedLoading" object:nil];

}

The notification center makes our view controller an observer for a notification named xmlFinishedLoading and when it get’s this notification it is going to call the method populateTextView.

16.) In XMLParser.m we are going to use the connectionDidFinishLoading to kick off the notification that our view controller will be listening for.

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{
	NSLog(@"***** connectionDidFinishLoading *****");
	[connection release];
	
	[[NSNotificationCenter defaultCenter] postNotificationName:@"xmlFinishedLoading" object:nil];
}

All this does is fire off a notification named xmlFinishedLoading, so any object set to listen for this notification will get it and can act accordingly.

17.) Back in NotificationCenterTutorialViewController.m let’s delete the line in button clicked that was calling our populateTextView method since we are now calling it when we receive the notification.

- (IBAction) buttonClicked
{
	xmlParser = [[XMLParser alloc] loadXML:@"http://api.twitter.com/1/statuses/user_timeline/KentFranks.xml"];
}

18.) Save everything and run it and see the result.

Simulator Shot

Now our text view gets populated because we wait for the xml to be returned before we populate it.

That’s it, pretty easy stuff once we got the app itself built to test it.

Here’s the code.



This entry was posted in Uncategorized and tagged , , , , , , , , . Bookmark the permalink.

18 Responses to NSNotificationCenter Tutorial – using the notification center in your iPhone app.

  1. Pingback: NSNotificationCenter Tutorial for iphone sdk | Iphone Development

  2. Doug says:

    Thank you, thank you, thank you!

  3. Pingback: Array in RootViewController is not equal to the Array in XML Parser - iPhone Dev SDK Forum

  4. venky says:

    thank you its really useful to me

  5. Objectionable-C says:

    A clean and insightful tutorial. This was most excellent in helping me understand that concept. Thank you for taking the time!

  6. verm says:

    Nicely explained.

  7. Prajwal says:

    Good tutorial, just what I wanted. Clear explanation of NSNotifications

  8. Farlo says:

    Excellent tutorial. You saved me some serious time!

  9. David says:

    Awesome. Easy to find. Almost easy to comprehend. :) Thanks for taking the time to post this concise tutorial.

  10. ramesh says:

    you have made the thing which even apple couldnt make it clear..impossible post..thank you very much

  11. HH says:

    Great tutorial (over my head at this stage) but can you help me…I can’t get my text view to save the user’s changes? I am looking for some very basic information. The app is using iOS 5 / storyboard. Already created an outlet, set the text view delegate but my code to dismiss the keyboard is not working.

  12. Gina says:

    Thank you so much. Your tutorials have been a great resource. I loved this one. Easy to understand and to the point.

  13. Federico says:

    Tanks very much!! You saved me more time!

  14. Laxman says:

    Really very useful, Thank you so much. If you were near me I would bring you bear and some snacks.

  15. Arihant says:

    Excellent tutorial! I just love your work. Just want to say keep it up! I’ll be looking forward to more tutorials!

  16. Alan says:

    Thank you so much. I was looking for a simple tutorial about NSNotificationCenter and now I can implement with no problems the login/logout in my system. This tutorial is really useful.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>