G.Abhisek
G.Abhisek

Reputation: 1094

NSNotificationCenter addobserver not calling the selector method in SWIFT

I know that this question has been asked quite many times but I am damn tired of searching for this error but couldn't make it.

I have a scenario in which I am moving from one viewController to another i.e (VC1->VC2). I am using NSNotificationCenter to pass some data to the other VC.

VC1 -

@IBAction func sendNotfctn(sender: AnyObject)
    {
        NSNotificationCenter.defaultCenter().postNotificationName("MY NOTIFICATION", object: self)
         performSegueWithIdentifier("Go", sender: self)//Here I move to VC2. 
    }

VC2

override func viewDidLoad()
    {
        super.viewDidLoad()


        NSNotificationCenter.defaultCenter().addObserver(self, selector: "actOnMyNotification:", name: "MY NOTIFICATION", object: nil)

        // Do any additional setup after loading the view.
    }
func actOnMyNotification(notification:NSNotification)
    {
        print("I recived the notification!")
    }

But my selector method is not called. What problem or what error am I making?

Version used - XCode 7.2, SWIFT - 2.1.1

Update -

I have VC1 - VC2(embedded in navigation controller). The segue i am using is connected from VC1 to Navigation controller of VC2. So I can't use segue passing for that.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if segue.identifier == "Go"
    {
        let destVC = segue.destinationViewController as! VC1//this line is not possible for my above said case
    }
}

If any alternatives please suggest.

Upvotes: 1

Views: 7430

Answers (4)

backslash-f
backslash-f

Reputation: 8183

You sent the notification before the second view controller could add itself as observer.

If the goal is to send data to the next ViewController, I suggest using prepareForSegue.

You mentioned that your second ViewController is embedded in a Navigation Controller. That's ok. You can use something like this:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if segue.identifier == "YOUR_IDENTIFIER" {

        // The destination ViewController is a NavigationController.
        // The top ViewController of the NavigationController is your target.
        // In this example we are just setting a String in the destination ViewController.
        if let navigationController = segue.destinationViewController as? UINavigationController {

            if let myTargetViewController = navigationController.topViewController as? MyTargetViewController {
                myTargetViewController.myStringVar = "My string value."
            }
        }
    }
}

You can also be fancy and write the same thing like this:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if let navigationController = segue.destinationViewController as? UINavigationController,
        myTargetViewController = navigationController.topViewController as? MyTargetViewController
        where segue.identifier == "YOUR_IDENTIFIER" {

        myTargetViewController.myStringVar = "My string value."
    }
}

As explained here.

Cheers!

Upvotes: 2

charush nair
charush nair

Reputation: 53

In your code you are adding observer in the VC2 viewdidload and it will get called only after you call performsegue.So, till you call perform segue your notification has no observer. The solution is

@IBAction func sendNotfctn(sender: AnyObject)
{
 performSegueWithIdentifier("Go", sender: self)//Here I move to VC2. 
 NSNotificationCenter.defaultCenter().postNotificationName("MY NOTIFICATION", object: self)
}

in VC1

Upvotes: -1

Sahil
Sahil

Reputation: 9226

You can send data to second view controller in this way

in first VC

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if segue.identifier == "Go"
  {
    let destVC = segue.destinationViewController as! SecondViewController // this must be your destintationviewcontroller name
   destVC.name = "hello"
 }
}

in secondVC

class SecondViewController: UIViewController {
  var name: String?

   override func viewDidLoad()
   {
    super.viewDidLoad()
    print(self.name) // prints Hello
 }
}

Upvotes: 0

Iyyappan Ravi
Iyyappan Ravi

Reputation: 3245

In you send Object is value send object, but you set self value, i think its a error, ok below code its working for me,

VC 1:

@IBAction func sendNotfctn(sender: AnyObject)
    {
         NSNotificationCenter.defaultCenter().postNotificationName("PostNotificationName", object: nil)
    }

VC 2:

override func viewDidLoad()
    {
        super.viewDidLoad()

        NSNotificationCenter.defaultCenter().removeObserver(self)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "actOnMyNotification:", name:"PostNotificationName", object: nil)

        // Do any additional setup after loading the view.
    }

func actOnMyNotification(notification:NSNotification)
    {

       print("I recived the notification!")
     }

hope its helpful

Upvotes: 1

Related Questions