4

I created a simple app to learn how to use NSWorkspaceWillSleepNotification and NSWorkspaceDidWakeNotification. My goal is to call a method when the computer sleeps and wakes. The app I created will change each label accordingly. After building the app, I launch it from my desktop. After the application is launched, I put the computer to sleep. When the computer wakes the labels in the application do not change. I added IBAction buttons to the window to make sure that the labels would change. When buttons are pressed the labels do indeed change. But I want something like this to happen automatically upon sleep and wake. What am I doing wrong?

#import "Controller.h"

@implementation Controller

- (void)fileNotifications {

    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self 
                                                           selector: @selector(makeSleep:) 
                                                               name: NSWorkspaceWillSleepNotification 
                                                             object: nil];

    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self 
                                                           selector: @selector(makeWake:) 
                                                               name: NSWorkspaceDidWakeNotification 
                                                             object: nil];
}

- (IBAction)makeSleep:(id)sender {
    [sleepLabel setStringValue:@"Computer Slept!"];
}

- (IBAction)makeWake:(id)sender {
    [wakeLabel setStringValue:@"Computer Woke!"];
}


@end
wigging
  • 8,492
  • 12
  • 75
  • 117
  • 1
    While your code most likely won't crash you should use `- (void)makeSleep:(NSNotification *)notification;` instead of `- (IBAction)makeSleep:(id)sender`. as notification observation callback methods serve a completely different purpose than **IBActions**. The fact that this works is merely thanks to the fact that they share the same selector pattern (that is a method with a single id/object argument). – Regexident Apr 06 '12 at 01:51

1 Answers1

2

Instead of [[NSWorkspace sharedWorkspace] notificationCenter] try using [NSNotificationCenter defaultCenter]

like this:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(makeSleep:) NSWorkspaceWillSleepNotification object:nil ];

and

[[NSNotificationCenter defaultCenter] addObserver:self @selector(makeWake:) NSWorkspaceDidWakeNotification object:nil ];

The above is incorrect, see https://developer.apple.com/library/mac/qa/qa1340/_index.html

Using [[NSWorkspace sharedWorkspace] notificationCenter] is necessary.

You should add observers upon - (void)awakeFromNib method.

charles
  • 11,212
  • 3
  • 31
  • 46
xyz
  • 2,277
  • 2
  • 25
  • 41
  • Ok my problem was I needed to put the `NSWorkspace` in the `awakeFromNib` method. Everything works now. Thanks for the hint. I didn't need to change anything else. – wigging Mar 02 '12 at 16:15
  • 4
    When registering for wake and sleep notifications, one absolutely should use the shared workspace's notification center. Since your answer was accepted, you should edit it so you don't confuse other people looking for help. – Loyal Tingley Aug 15 '12 at 04:09
  • 1
    This is plain wrong. It is explicitly stated in the developer sample on Apple's website that one should use the NSWorkspace notification center as opposed to the default center for these notifications. See https://developer.apple.com/library/mac/qa/qa1340/_index.html – Janus Varmarken Aug 01 '15 at 06:37