8

Are the new notifications not currently working in Swift 3?

I am doing:

NotificationCenter.default().post(name: DidTouchParticleView, object: self.particle as? AnyObject)

In a custom view's touchesBegan() and I need to send the particle object to the view controller if there is one. So I do this:

NotificationCenter.default().addObserver(forName: DidTouchParticleView, 
                                         object: self,
                                         queue: OperationQueue.main(),
                                         using: presentParticleDisplayView(notification:))

In a view controller's viewDidLoad(). I am certain that that particular view controller is the one presented when I tap my custom view, however, the function presentParticleDisplayView(notification:) is never called.

Also, DidTouchParticleView is defined globally like this:

let DidTouchParticleView = NSNotification.Name("didTouchParticleView")

Is this due to the beta, or am I doing something wrong?

Forge
  • 6,538
  • 6
  • 44
  • 64
Youssef Moawad
  • 2,846
  • 5
  • 28
  • 50
  • In the current beta, and in Swift 3 going forward, the parentheses after `default()` are removed; it is `NotificationCenter.default`. – matt Jul 11 '16 at 15:08

2 Answers2

13

It sounds like you may be intending to call addObserver(_:selector:name:object:), where the second parameter message (the selector:) is sent to the first parameter (the target).

Instead, you are calling the wrong method, addObserver(forName:object:queue:using:), which works quite differently.

Also, as to the second part of your question:

let DidTouchParticleView = NSNotification.Name("didTouchParticleView")

That is correct (almost); it should be

let DidTouchParticleView = Notification.Name("didTouchParticleView")

All notification names are now Notification.Name instances. The proper way to do this is to say:

extension Notification.Name {
    static let didTouchParticleView = Notification.Name("didTouchParticleView")
}

You can then refer to the notification's name as .didTouchParticleView throughout your code.

matt
  • 515,959
  • 87
  • 875
  • 1,141
1

You're watching for yourself to post the notification (object: self). You probably mean something like object: particle or possibly object: nil in the addObserver call (but then be careful to make sure it's the right particle in the handler). Re-read the docs for this method and note carefully what the object parameter is for.

Note that this version of addObserver returns an observer object. You must store that so you can later call removeObserver with it.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Changing `object` to nil solves it. However, how does it know what has become the observer? Before, in Swift 2, there used to be `addObserver:` that takes an object as the observer. – Youssef Moawad Jul 11 '16 at 15:15
  • 1
    @YoussefSami No, you didn't understand what was going in before. The `object` was _never_ the observer. The observer is _returned_ from the call. Don't confuse this with `addObserver(_:selector:name:object:)`, where the first parameter _is_ the observer. See now my edited answer. – matt Jul 11 '16 at 15:20
  • @matt Yes, that's the one to which I was referring. So how does the Notification Center now know to which object to send the notification? – Youssef Moawad Jul 11 '16 at 15:25
  • @YoussefSami It's the same as it always was. The first parameter is the target to which the selector will be sent. As I said, see my edited answer. – matt Jul 11 '16 at 15:40