1.30. Listening for Notifications Sent from NSNotificationCenter

Problem

You want to listen for different system and custom notifications broadcast using NSNotificationCenter.

Solution

Add your observer object to the notification center using the addObserver:selector:name:object: instance method of NSNotificationCenter before a notification is broadcast. To stop observing a notification, use the removeObserver:name:object: instance method of NSNotificationCenter and pass your observer object, then the name of the notification that you want to stop observing and the object that you originally subscribed to (this will be explained in detail in the Discussion section of this recipe).

Discussion

Any object can broadcast a notification and any object within the same app can opt into listening for notifications with specific names. Two notifications with the same name can be broadcast, but they must come from two different objects. For instance, you can have a notification with the name of DOWNLOAD_COMPLETED that gets fired from two classes, one being a download manager that downloads images from the Internet and another being a download manager that downloads data from an accessory connected to the iOS device. An observer might be interested only in the notifications of this name coming from a specific object; for instance, the download manager that downloads data from the accessory. You can specify this source object (broadcaster) when you start listening for notifications, using the object parameter of the addObserver:selector:name:object: method of the notification center.

Here is a brief description of each of the parameters that the addObserver:selector:name:object: accepts:

addObserver

The object that will receive the notifications (observer).

selector

The selector (method) to be called on the observer when the notification is broadcasted and received by the observer. This method takes a single argument of type NSNotification.

name

The name of the notification to observe.

object

Optionally specifies the source of the broadcast notification. If this parameter is nil, notifications of the specified name will be received by the observer regardless of which object broadcasts them. If this parameter is set, only the notifications of the specified name that are broadcast by the given object will be observed.

In Recipe 1.29 we learned how to post notifications. Let’s now try observing the notification that we learned to post there:

#import "AppDelegate.h"

@implementation AppDelegate

/* The notification name */
const NSString *ResultOfAppendingTwoStringsNotification =
                @"ResultOfAppendingTwoStringsNotification";

/* Keys inside the dictionary that our notification sends */
const NSString
  *ResultOfAppendingTwoStringsFirstStringInfoKey = @"firstString";

const NSString
  *ResultOfAppendingTwoStringsSecondStringInfoKey = @"secondString";

const NSString
  *ResultOfAppendingTwoStringsResultStringInfoKey = @"resultString";

- (void) broadcastNotification{

  NSString *firstName = @"Anthony";
  NSString *lastName = @"Robbins";
  NSString *fullName = [firstName stringByAppendingString:lastName];

  NSArray *objects = [[NSArray alloc] initWithObjects:
                      firstName,
                      lastName,
                      fullName,
                      nil];  NSArray *keys = [[NSArray alloc] initWithObjects:
                   ResultOfAppendingTwoStringsFirstStringInfoKey,
                   ResultOfAppendingTwoStringsSecondStringInfoKey,
                   ResultOfAppendingTwoStringsResultStringInfoKey,
                   nil];

  NSDictionary *userInfo = [[NSDictionary alloc] initWithObjects:objects
                                                         forKeys:keys];

  NSNotification *notificationObject =
  [NSNotification
   notificationWithName:(NSString *)ResultOfAppendingTwoStringsNotification
   object:self
   userInfo:userInfo];

  [[NSNotificationCenter defaultCenter] postNotification:notificationObject];

}

- (void) appendingIsFinished:(NSNotification *)paramNotification{

  NSLog(@"Notification is received.");
  NSLog(@"Notification Object = %@", [paramNotification object]);
  NSLog(@"Notification User-Info Dict = %@", [paramNotification userInfo]);

}

- (BOOL)            application:(UIApplication *)application
  didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{


  /* Listen for the notification */
  [[NSNotificationCenter defaultCenter]
   addObserver:self
   selector:@selector(appendingIsFinished:)
   name:(NSString *)ResultOfAppendingTwoStringsNotification
   object:self];

  [self broadcastNotification];

  self.window = [[UIWindow alloc] initWithFrame:
                 [[UIScreen mainScreen] bounds]];
  self.window.backgroundColor = [UIColor whiteColor];
  [self.window makeKeyAndVisible];
  return YES;

}

- (void)applicationWillTerminate:(UIApplication *)application{
  /* We no longer observe ANY notifications */
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

When you run this app, you will see something similar to the following printed to the console window:

Notification is received.
Notification Object = <AppDelegate: 0x7408490>
Notification User-Info Dict = {
    firstString = Anthony;
    resultString = AnthonyRobbins;
    secondString = Robbins;
}

As you can see, we are using the removeObserver: method of our notification center to remove our object as an observer of all notifications. There are different ways of removing your objects from the chain of observers. Either you can quit cold-turkey, as we have done here—that is, remove your object completely from observing any notification—or you can remove your object from observing specific notifications at any time during the lifetime of your application. If you want to specify the notifications you are removing your object from observing, simply call the removeObserver:name:object: method of your notification center and specify the name of the notification from which you are unsubscribing, as well as (optionally) the object that was sending the notifications.

See Also

Recipe 1.29

Get iOS 6 Programming Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.