Fundamentals of NSNotificationCenter in Swift

The goal of this post is to help you grasp the fundamentals of usingNSNotificationCenter in your Swift iOS app. The topic isn’t necessarily new, and there’s no difference except syntax between Objective-C and Swift implementations involving NSNotificationCenter. Even still, I’m hoping to add to the understanding of this useful tool by giving a fully-working example on GitHub, and by sharing the insight that’s clicked in my own brain as I explain the example.

First things first: What is this thing?

When I first heard NSNotificationCenter, I thought “push notifications”. However, NSNotificationCenter has nothing to do with sending or receiving push notifications in iOS. Rather, it is a communication tool internal to your app. It provides a way for one instance of a class/struct to notify one or more otherclass/struct instances about something. The goal in doing this is to enable those 1+ other class or struct instances to take appropriate action based the communication they receive. An common analogy comes to mind: think “radio tower”. NSNotificationCenter is the central hub that acts as a broadcaster of notifications. If that still seems vague, hang tight – seeing the example below should help it all come together for you.

Should I use it?

Before diving into the basic workflow, it’s worth asking, “Should I useNSNotificationCenter, or is there some other option that’s more appropriate for my app’s internal communication needs?”

It is often the case that there is more than one way to solve a problem in software development, and it’s no different with NSNotificationCenter. There is more than one way to accomplish instance-to-instance communication at run-time. I’ve written about two such forms of communication in my post titledNSNotificationCenter vs Delegation – An Analysis. It may be worth reading up on, just to make sure you’re using the right tool for the right kind of communication.

Basic Workflow

NSNotificationCenter.defaultCenter() is at the center of it all when it comes to this discussion.

The basic workflow of using NSNotificationCenter goes something like this:

  1. Since NSNotificationCenter is in the business of broadcasting notifications, the first thing to do is to specify a way to uniquely identify a notification. This is most easily accomplished by defining a constant string value (using let syntax in Swift) at a globally-visible scope. The string constant you define here will serve as a “notification key”. If you have several notification keys that you need to define, perhaps creating a new .swift file called “NSNotificationCenterKeys.swift” is a clean way to do this.
  2. Steps 2 and 3 of the workflow go hand-in-hand. Without implementing the one, implementing the other doesn’t make much sense… Step 2 is to *post* a notification to NSNotificationCenter.defaultCenter() identified by the key that was created in step 1. In radio terms, the class or struct instance desiring to post a notification asks the default notification center to broadcast the notification key defined in step 1… this class or struct instance chooses the right situations to request that the notification key be sent out based on business logic specific to the project’s requirements.
  3. Step 3 is to set up 1+ class or struct instances to be *listeners*, or more properly, *observers* of a particular notification. Such an observer will be able to tell that it’s “heard” the notification, because it will be “listening for” a notification that uses the same key that was created in step 1, which is the key used in step 2 to *post* the notification. In radio terms, the listener is tuned in to the default notification center’s station that’s identified by that special key defined in step 1 and posted in step 2. So you see now why steps 2 and 3 go hand-in-hand. With no posts to the notification center on that station, tuning in will do no good. Likewise, posting a notification but having no listeners accomplishes nothing.
  4. Finally, what should the observing instance *do* once it’s detected the notification? Well, when signing up to be an observer, the instance must also specify the name of a function that will be called upon receipt of the notification it’s listening for. Whatever action or routine is appropriate to perform at that time is what that function’s implementation should contain.

Visualizing NSNotificationCenter by Example

If you’re like me, you need less talk and *more example, *so I’ve created a simple XCode project that you can grab over at GitHub. Running the project will allow you to click through a series of tabs in a tab view controller, post a notification, and see the results. It looks much like this:

NS Notification Center Example

Working back through the basic workflow with this example you can find the following key aspects of implementing a NSNotificationCenter solution (lines of code to pay special attention to will be highlighted).

Steps 1 and 2:

I’ve chosen my FirstViewController class to be the one that defines the global constant with a unique notification key and tells the default notification center to post that notification when the “Notify!” button is tapped:

Steps 3 and 4:

Both of these steps are implemented in very similar ways in mySecondViewController and ThirdViewController classes. The code should speak for itself:

Finally, to reiterate the explanation in visual form and for easy reference, I’ve annotated a screen shot taken from the project’s code:

NSNotification Center Example Explanation

Removing an observer

One final requirement for working with NSNotificationCenter is to remove an observer when it no longer needs to listen for notifications. When might this situation arise?

  • When the observer is no longer referenced and thus deallocated from memory, it should tell the default notification center that it can be removed
  • When some condition occurs in your application that renders it no longer relevant for an instance to listen for notifications

The first situation is the most common, and is for sure the scenario that we want to protect against, so that the default notification center doesn’t continue to manage observers that are no longer capable of actively listening. To satisfy the requirement of removing an observer when an instance is deallocated, we could provide something like the following deinit method:

For the second bullet point, you can simply write the same line of code that’s highlighted in the above snippet, wherever it makes sense for you to tell the default notification center when it’s appropriate to stop sending messages to the instance in question.

Summary

NSNotificationCenter is particularly useful when there are multiple class or struct instances that need to take action based on something that happens elsewhere in your application. For this type of scenario, NSNotificationCentercan be a great tool to wield as you develop apps in Swift for iOS.

You might also enjoy…
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s