Pass data with iOS Notifications - Swift 3.0

We all have used Notifications on iOS. (I would not call them NSNotifications though, since this post is about Swift 3.0). I used them long ago when I was yet a newcomer. They were easy way to transport information among different parts of program. Although easy, Notifications can have adverse side effects if not handled well. They send global notifications in sense that it affects every part of your program, which may not be good indication.

Thus, as time progressed, I made transition to delegates, and after some time when I got hang of it, I made transition to blocks. Delegates and blocks are good in sense that they help us keep the context minimal and limited to areas where it matters most. However, today we are going to talk about iOS Notifications. How to use them, pass data and how we can differentiate between notifications received from variety of sources and filter them out if necessary.

With quick spread and everyone in the town now using it, For the sake of this tutorial I will assume that you all are using Swift 3.0

  • Registering for notifications
let userUpdateNotification = Notification.Name("userUpdate")
NotificationCenter.default.addObserver(self, selector: #selector(updateUser(not:)), name: userUpdateNotification, object: nil)
  

As you can see from example, name of the notification is no longer of type String. It is rather a struct of type Notification.Name as of Swift 3.0

  • Posting Notification

.
NotificationCenter.default.post(name: NSNotification.Name("userUpdate"), object: self, userInfo: ["name": "Jim"])

Where,

A. NSNotification.Name("userUpdate") is the struct identifying the specific notification by name.


B. For the argument object, you can simply pass the object responsible for sending out notification


C. userInfo is a payload which can be used to pass between sender and observer of notifications. It is a dictionary of type [AnyHashable : Any]

You can very well utilize both userInfo and object inside an object observing for notifications.

  • userInfo - Sometimes observer and notifier are so disconnected from each other that it's almost impossible to form a communication bridge between them to pass the information. In that case userInfo can well be utilized to bundle information and pass it over to observer. Since it is simply a Dictionary, we can pack any piece of data in the key-value fashion

  • object - An observer can receive notification from any object. However, in some cases we need to consider notifications only from specific sources. Observer can utilize object parameter to consider notifications from specific sources and ignore rest based on the type object represents. (Provided sender of notification sends notification with non-nil object parameter)

Following example demonstrates how we can utilize both these parameters. Assume the function updateUser(not:) gets called every time our observer receives a notification with name userUpdate from the object of type AuthorizedUser


func updateUser(not: Notification) {
    let sender = not.object
    // We only want to process notifications when sent by the object of type AuthorizedUser
    guard (sender as? AuthorizedUser) != nil else {
        return
    }

    // userInfo is the payload send by sender of notification
    if let userInfo = not.userInfo {
       // Safely unwrap the name sent out by the notification sender
        if let userName = userInfo["name"] as? String {
            print(userName)
        }
    }
}

This should be it as long as Notifications in Swift 3.0 are concerned. If you have any more questions about this blog post or anything that touches programming, iOS, Swift, Mobile app development, do not hesitate to reach to me. As always, thanks for taking time to read the post!

Happy New Year!!!