iosswiftnsnotification

Unable to find sender of NSNotification


I am receiving an NSNotification event for UIKeyboardWillShowNotification Can anyone tell me how can I find out from where this NSNotification is being sent? Preferably in swift

I can see the name of the notification but not from where it is generated

NSNotificationCenter.defaultCenter().addObserverForName(nil,object: nil,queue: nil)                                                            
    {
      note in
      if(note.name.containsString("keyboard") ){
         print(note)
      }                                                                    
    }

Solution

  • It's irrelevant “from where this NSNotification is being sent”. What matters is what the notification means and when it is sent. It means the keyboard is about to animate onto the screen, and it is sent at the start of the animation. This means that if you want to move some views so they're not hidden by the keyboard, you can listen for this notification to know when to move them. And if you want to animate that movement in sync with the keyboard animation, you can start your animation when you receive this notification.

    All that said, if you really want to understand “from where”, you can put a breakpoint in your notification handler and then look at the stack trace when the notification handler is called. Example:

    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: nil) { (note) in
                // put a breakpoint on the next line
                Swift.print(note)
            }
        }
    
    
    }
    

    I put a text field into my storyboard. I ran the app in the Xcode 8.2 beta 2 simulator, simulating an iPhone 7 Plus running iOS 10.2. I tapped the text field. Here's the stack trace at the breakpoint:

    #0  0x0000000106b4a184 in ViewController.(viewDidLoad() -> ()).(closure #1) at /Users/mayoff/TestProjects/test/test/ViewController.swift:18
    #1  0x0000000106b4a2a9 in thunk ()
    #2  0x0000000106c380da in -[__NSObserver _doit:] ()
    #3  0x0000000109db45ec in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ ()
    #4  0x0000000109db44eb in _CFXRegistrationPost ()
    #5  0x0000000109db4252 in ___CFXNotificationPost_block_invoke ()
    #6  0x0000000109d77282 in -[_CFXNotificationRegistrar find:object:observer:enumerator:] ()
    #7  0x0000000109d7631b in _CFXNotificationPost ()
    #8  0x0000000106bf081b in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
    #9  0x000000010806ee76 in -[UIInputWindowController postStartNotifications:withInfo:] ()
    #10 0x0000000108071117 in __77-[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:]_block_invoke.871 ()
    #11 0x00000001076b4432 in +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] ()
    #12 0x00000001076b48bf in +[UIView(UIViewAnimationWithBlocks) _animateWithDuration:delay:options:animations:start:completion:] ()
    #13 0x0000000108070b44 in -[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:] ()
    #14 0x0000000108078b2b in -[UIInputWindowController setInputViewSet:] ()
    #15 0x0000000108070158 in -[UIInputWindowController performOperations:withAnimationStyle:] ()
    #16 0x0000000107ce335d in -[UIPeripheralHost(UIKitInternal) setInputViews:animationStyle:] ()
    #17 0x0000000107814837 in -[UIResponder(UIResponderInputViewAdditions) reloadInputViews] ()
    #18 0x000000010781144e in -[UIResponder becomeFirstResponder] ()
    #19 0x00000001076aaafb in -[UIView(Hierarchy) becomeFirstResponder] ()
    #20 0x00000001081097c8 in -[UITextField becomeFirstResponder] ()
    #21 0x0000000107b42f4f in -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] ()
    #22 0x0000000107b46767 in -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) oneFingerTap:] ()
    #23 0x0000000107b34431 in -[UIGestureRecognizerTarget _sendActionWithGestureRecognizer:] ()
    #24 0x0000000107b3c1d0 in _UIGestureRecognizerSendTargetActions ()
    #25 0x0000000107b39c9f in _UIGestureRecognizerSendActions ()
    #26 0x0000000107b38f2b in -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] ()
    #27 0x0000000107b24fa6 in _UIGestureEnvironmentUpdate ()
    #28 0x0000000107b249eb in -[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] ()
    #29 0x0000000107b23bce in -[UIGestureEnvironment _updateGesturesForEvent:window:] ()
    #30 0x000000010766ab6d in -[UIWindow sendEvent:] ()
    #31 0x00000001076178fb in -[UIApplication sendEvent:] ()
    #32 0x0000000107e0374d in __dispatchPreprocessedEventFromEventQueue ()
    #33 0x0000000107dfc483 in __handleEventQueue ()
    #34 0x0000000109dbb761 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
    #35 0x0000000109da098c in __CFRunLoopDoSources0 ()
    #36 0x0000000109d9fe76 in __CFRunLoopRun ()
    #37 0x0000000109d9f884 in CFRunLoopRunSpecific ()
    #38 0x000000010bd50a6f in GSEventRunModal ()
    #39 0x00000001075f9bb8 in UIApplicationMain ()
    #40 0x0000000106b4ba8f in main at /Users/mayoff/TestProjects/test/test/AppDelegate.swift:12
    #41 0x000000010adc668d in start ()
    #42 0x000000010adc668d in start ()
    

    From this we can see that an instance of UIInputWindowController (a class private to UIKit) appears to be responsible for animating the keyboard's position, and it posts the notification.