1.29. Sending Notifications with NSNotificationCenter

Problem

You want to broadcast an event in your app and allow any object that is willing to
listen to it to take action, depending on the notification that you are
broadcasting.

Solution

Use the postNotificationName:object:userInfo: method
of the default notification center of type NSNotificationCenter to post a notification
that carries an object (usually the object that fires the notification)
and a user-info dictionary that can carry extra information about the
notification and/or the object that fires the notification.

Discussion

Notification centers are dispatch centrals for notification objects.
For instance, when the keyboard pops up anywhere while
the user is inside your app, iOS will send a notification to your app.
Any object inside your app willing to listen to this notification can
add itself to the default notification center as an
observer for that particular notification. Once
your object’s lifetime comes to an end, it must remove itself from the
notification center’s dispatch table. As a result, a notification is a
message that gets broadcasted to observers through a notification
center. A notification center is an instance of NSNotificationCenter class. We retrieve the
default notification center object using the defaultCenter class method of NSNotificationCenter.

Notifications are objects of type NSNotification. A notification object has a
name (specified as NSString) and can
carry two key pieces of information:

Note

You can specify the name of your notifications yourself. You don’t have to use an API
for that. Just make sure that your notification names are unique
enough that they won’t clash with a system notification.

Sender Object

This is the instance of the object that fires the notification. The observer
can access this object using the object instance method of the NSNotification class.

User-Info Dictionary

This is an optional dictionary that the sender object can
create and send alongside a notification object. This dictionary
usually contains more information about the notification. For
instance, when a keyboard is about to get displayed in iOS for any
component inside your app, iOS sends the UIKeyboardWillShowNotification
notification to the default notification center. The
user-info dictionary of this notification contains values such as
the rectangle of the keyboard before and after animation and the animation duration
of the keyboard. Using this data, an observer can make a decision
as to, for instance, what to do with UI components that
potentially will be obstructed once the keyboard gets displayed on
the screen.

Warning

Notifications are a great way of implementing decoupled code. By that I mean, using
notifications, you can get rid of completion handlers and delegation.
However, there is one potential caveat about notifications: they are
not delivered immediately. They are dispatched by notification
centers, and the implementation of NSNotificationCenter is hidden from
application programmers. Delivery might sometimes be delayed by a few
milliseconds or, in extreme cases (which I have never encountered), a
few seconds. As a result, it is up to you to decide where to and where
not to use notifications.

In order to construct a notification of type NSNotification, use the notificationWithName:object:userInfo: class
method of the NSNotificationClass, as
we will soon see.

Note

It is best to suffix your notification names with the word Notification. For instance, it is permitted
to give your notification a name similar to ResultOfAppendingTwoStrings. However, it is
better to give the name ResultOfAppendingTwoStringsNotification, as
that clearly says what this name belongs to.

Let’s have a look at an example. We’ll simply take a first name
and a last name, append them to create one string (first name + last
name) and then broadcast the result using the default notification
center. We will do that in the implementation of our app delegate as
soon as the user launches our app:

Of course, you don’t have to specify an object or a user-info dictionary for every
notification that you wish to broadcast. However, if you are working
with a team of developers on the same app or if you are writing a static
library, I suggest that you fully document your notifications and
clearly mention whether your notifications carry an object and/or an
user-info dictionary with them. If they do, you must say what object
each notification carries and what keys and values are inside the
user-info dictionary. If you are planning on not sending an object or a
user-info dictionary, then I suggest you use the postNotificationName:object: instance method
of NSBundle. Specify a string that
represents the name of your notification as the first parameter, and nil
as the second parameter, which is the object that should be carried with
the notification. Here is an example:

#import "AppDelegate.h"@implementationAppDelegate/* The notification name */constNSString*NetworkConnectivityWasFoundNotification=@"NetworkConnectivityWasFoundNotification";-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions{[[NSNotificationCenterdefaultCenter]postNotificationName:(NSString*)NetworkConnectivityWasFoundNotificationobject:nil];self.window=[[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]];self.window.backgroundColor=[UIColorwhiteColor];[self.windowmakeKeyAndVisible];returnYES;}

The best content for your career. Discover unlimited learning
on demand for around $1/day.