Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NotificationCenter to pass data in Swift

I am working on a test project in Swift 3. I am trying to pass textField string from one class to another class using NotificationCenter. I am trying to workout the answer from this link: pass NSString variable to other class with NSNotification and how to pass multiple values with a notification in swift

I tried few answers from the above link but nothing worked.

My code:

//First VC

import UIKit


extension Notification.Name {        
public static let myNotificationKey = Notification.Name(rawValue: "myNotificationKey")    
}


class ViewController: UIViewController {

@IBOutlet weak var textView: UITextView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


@IBAction func sendData(_ sender: AnyObject) {

    let userInfo = [ "text" : textView.text ]
    NotificationCenter.default.post(name: .myNotificationKey, object: nil, userInfo: userInfo)

}

}

//SecondVC

 import Foundation
 import  UIKit

 class viewTwo: UIViewController {

@IBOutlet weak var result: UILabel!



override func viewDidLoad() {


}


override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(self.notificationReceived(_:)), name: .myNotificationKey, object: nil)
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(self, name: .myNotificationKey, object: nil)
}

func notificationReceived(_ notification: Notification) {
    guard let text = notification.userInfo?["text"] as? String else { return }
    print ("text: \(text)")

    result.text = text
}

enter image description here}

I am not sure whats wrong with the code. Above, code originally marked as a answered which, I found from the first link. Code been converted to Swift.

like image 815
Joe Avatar asked Oct 13 '16 08:10

Joe


People also ask

How do I use NotificationCenter in Swift?

Note: You need to mark this function with @objc. That attribute makes your Swift function available in the Objective-C runtime. The NotificationCenter is part of the Objective-C runtime, so in order for it to call your function, you'll need to add that @objc attribute.

What is Nsnotification in Swift?

A notification dispatch mechanism that enables the broadcast of information to registered observers. iOS 2.0+ iPadOS 2.0+ macOS 10.0+ Mac Catalyst 13.0+ tvOS 9.0+ watchOS 2.0+


4 Answers

Pass text using userInfo which is a optional Dictionary of type [AnyHashable:Any]? in Swift 3.0 and it is [NSObject : AnyObject]? in swift 2.0

@IBAction func sendData(_ sender: UIButton) {

// post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: ["text": textValue.text])

print(textValue) // textValue printing

}

in viewDidLoad

// Register to receive notification

NotificationCenter.default.addObserver(self, selector: #selector(self. incomingNotification(_:)), name:  NSNotification.Name(rawValue: "notificationName"), object: nil)

and in incomingNotification

func incomingNotification(_ notification: Notification) {
if let text = notification.userInfo?["text"] as? String {
   print(text)
  // do something with your text   
}


}
like image 187
Sahil Avatar answered Oct 12 '22 22:10

Sahil


Don't use object parameter to pass data. It is meant to filter notifications with the same name, but from a particular object. So if you pass some object when you post a notification and another object when you addObserver, you won't receive it. If you pass nil, you basically turn off this filter.

You should use userInfo parameter instead.

First, it is better to define notification's name as extension for Notification.Name. This approach is much safer and more readable:

extension Notification.Name {        
    public static let myNotificationKey = Notification.Name(rawValue: "myNotificationKey")    
}

Post notification:

let userInfo = [ "text" : text ]
NotificationCenter.default.post(name: .myNotificationKey, object: nil, userInfo: userInfo)

Subscribe:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(self.notificationReceived(_:)), name: .myNotificationKey, object: nil)
}

Unsubscribe:

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(self, name: .myNotificationKey, object: nil)
}

Method to be called:

func notificationReceived(_ notification: Notification) {
    guard let text = notification.userInfo?["text"] as? String else { return }
    print ("text: \(text)")
}
like image 36
alexburtnik Avatar answered Oct 12 '22 22:10

alexburtnik


In your sendData method pass textField.text into Notification object and in your incomingNotification do this:

guard let theString = notification.object as? String else {
    print("something went wrong")
    return 
}

resultLabel.text = theString

You can also use blocks to pass data between controllers.

like image 2
Maksym Musiienko Avatar answered Oct 12 '22 22:10

Maksym Musiienko


Use dispatchQueue because your notification is posting before your view load. Therefore just give delay in your notification Post.

@IBAction func sendData(_ sender: AnyObject) {

    let userInfo = [ "text" : textView.text ]
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
 NotificationCenter.default.post(name: .myNotificationKey, object: nil, userInfo: userInfo)        }

}
like image 1
Hamza Saeed Avatar answered Oct 12 '22 22:10

Hamza Saeed