Swift
NotificationCenter
NSNotificationCenter
iOS Development
Data Passing

How to pass data using NotificationCenter in swift 3.0 and NSNotificationCenter in swift 2.0?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

NotificationCenter lets one part of an iOS app broadcast an event without knowing which other parts are listening. To pass data with that event, you attach a userInfo dictionary. Swift 3 changed the API names compared with Swift 2, but the underlying model stayed the same: post a notification, observe it elsewhere, and extract typed values from the payload carefully.

Post a Notification With Data

In Swift 3 and later, define a notification name once and send the payload in userInfo.

swift
1import Foundation
2
3extension Notification.Name {
4    static let profileDidChange = Notification.Name("profileDidChange")
5}
6
7NotificationCenter.default.post(
8    name: .profileDidChange,
9    object: nil,
10    userInfo: [
11        "userId": 42,
12        "displayName": "Ava"
13    ]
14)

The dictionary is flexible, which is useful, but it also means the sender and receiver must agree on key names and value types.

Observe and Read the Payload

The receiver extracts values from notification.userInfo.

swift
1import UIKit
2
3final class ProfileViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6        NotificationCenter.default.addObserver(
7            self,
8            selector: #selector(handleProfileChange(_:)),
9            name: .profileDidChange,
10            object: nil
11        )
12    }
13
14    @objc private func handleProfileChange(_ notification: Notification) {
15        guard
16            let userInfo = notification.userInfo,
17            let userId = userInfo["userId"] as? Int,
18            let displayName = userInfo["displayName"] as? String
19        else {
20            return
21        }
22
23        print(userId, displayName)
24    }
25
26    deinit {
27        NotificationCenter.default.removeObserver(self)
28    }
29}

Because userInfo is loosely typed, defensive casting is part of the pattern.

Swift 2 Used NSNotificationCenter

Swift 2 used older Foundation naming, but the idea was identical.

swift
1NSNotificationCenter.defaultCenter().postNotificationName(
2    "profileDidChange",
3    object: nil,
4    userInfo: [
5        "userId": 42,
6        "displayName": "Ava"
7    ]
8)

Observation looked similar, just with older method names:

swift
1NSNotificationCenter.defaultCenter().addObserver(
2    self,
3    selector: #selector(handleProfileChange(_:)),
4    name: "profileDidChange",
5    object: nil
6)

So the migration issue is mostly API naming, not a different communication technique.

Block-Based Observation

For some cases, the closure-based API is cleaner than selector-based observation.

swift
1var token: NSObjectProtocol?
2
3token = NotificationCenter.default.addObserver(
4    forName: .profileDidChange,
5    object: nil,
6    queue: .main
7) { notification in
8    if let name = notification.userInfo?["displayName"] as? String {
9        print(name)
10    }
11}

If you use this form, store the token and remove it when appropriate. Otherwise the observer can outlive the object that created it.

When NotificationCenter Is the Right Tool

Notifications are best for broadcast-style events such as:

  • login state changed
  • theme changed
  • sync completed
  • cache refreshed

They are not ideal for tightly coupled one-to-one communication. If one object already knows exactly which other object needs the data, a delegate, closure, or direct method call is usually clearer.

Keep the Payload Contract Stable

As the app grows, ad hoc string keys become fragile. Shared key constants or a small wrapper around the payload contract help prevent silent failures caused by typos.

That is especially useful when several modules post or observe the same notification.

Also remember that notification handlers may not always arrive on the main thread unless you request a main queue or dispatch explicitly. That matters for any observer that updates UIKit state.

Common Pitfalls

  • Using notifications for tightly coupled communication that should be direct.
  • Passing inconsistent or poorly documented userInfo keys.
  • Assuming payload values are type-safe without casting them carefully.
  • Forgetting to remove long-lived observers or stored block tokens.

Summary

  • Pass data through notifications with the userInfo dictionary.
  • In Swift 3 and later, prefer typed Notification.Name constants.
  • Swift 2 used NSNotificationCenter, but the data-passing model was the same.
  • Cast payload values defensively and document the key contract.
  • Use notifications for broadcast events, not as a universal data-passing mechanism.

Course illustration
Course illustration

All Rights Reserved.