cocoabits / MASShortcut

Modern framework for managing global keyboard shortcuts compatible with Mac App Store. More details:
http://blog.shpakovski.com/2012/07/global-keyboard-shortcuts-in-cocoa.html
BSD 2-Clause "Simplified" License
1.52k stars 220 forks source link

MASShortcutBinder "this class is not key value coding-compliant for the key ..." #64

Closed pedrovieira closed 9 years ago

pedrovieira commented 9 years ago

I've recently switched from MASShortcut 1.0 to 2.0 and now I've been experiencing this bug:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MASShortcutBinder 0x60800004cfc0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key Shortcut Open Last.'

Here's the code I'm currently using (which worked before I updated from MASShortcut registerGlobalShortcutWithUserDefaultsKey:handler: to MASShortcutBinder bindShortcutWithDefaultsKey: toAction:):

[[MASShortcutBinder sharedBinder] bindShortcutWithDefaultsKey:kPrefsShortcutOpenLastFmUserURLKey toAction:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            // do something
        });
    }];

When debugging, my program completely crashes at this point giving the following error message on the console:

    0   CoreFoundation                      0x00007fff9227166c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff925b576e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff92271209 -[NSException raise] + 9
    3   Foundation                          0x00007fff8adc23dd -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 226
    4   MASShortcut                         0x000000010014ae9a -[MASShortcutBinder valueForUndefinedKey:] + 186
    5   Foundation                          0x00007fff8acdfbf8 -[NSObject(NSKeyValueCoding) valueForKey:] + 385
    6   Foundation                          0x00007fff8acf862e -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 255
    7   AppKit                              0x00007fff83d87e0d -[NSObjectParameterBinder _updateObject:observedController:observedKeyPath:context:] + 622
    8   AppKit                              0x00007fff83d7f293 -[NSObject(NSKeyValueBindingCreation) bind:toObject:withKeyPath:options:] + 758
    9   MASShortcut                         0x000000010014a705 -[MASShortcutBinder bindShortcutWithDefaultsKey:toAction:] + 309
    10  Muzzy                               0x0000000100013e6d __38-[AppDelegate listenToGlobalShortcuts]_block_invoke + 365
    11  libdispatch.dylib                   0x000000010016e2bb _dispatch_call_block_and_release + 12
    12  libdispatch.dylib                   0x0000000100168d43 _dispatch_client_callout + 8
    13  libdispatch.dylib                   0x0000000100177d9f _dispatch_main_queue_callback_4CF + 1370
    14  CoreFoundation                      0x00007fff921c4c79 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
    15  CoreFoundation                      0x00007fff9218130f __CFRunLoopRun + 2159
    16  CoreFoundation                      0x00007fff92180858 CFRunLoopRunSpecific + 296
    17  HIToolbox                           0x00007fff8b4bfaef RunCurrentEventLoopInMode + 235
    18  HIToolbox                           0x00007fff8b4bf86a ReceiveNextEventCommon + 431
    19  HIToolbox                           0x00007fff8b4bf6ab _BlockUntilNextEventMatchingListInModeWithFilter + 71
    20  AppKit                              0x00007fff83cfcf81 _DPSNextEvent + 964
    21  AppKit                              0x00007fff83cfc730 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 194
    22  AppKit                              0x00007fff83cf0593 -[NSApplication run] + 594
    23  AppKit                              0x00007fff83cdba14 NSApplicationMain + 1832
    24  Muzzy                               0x000000010000a6d2 main + 34
    25  libdyld.dylib                       0x00007fff870d25c9 start + 1
    26  ???                                 0x0000000000000003 0x0 + 3

Any ideas on what's making this crash? It's so weird because I am listening to more shortcuts the same way as above, with other shortcut constant identifiers, and it's passing my debugging without a problem. Only this one is making my app crash.

pedrovieira commented 9 years ago

Apparently the issue had to do with the defaults key string which had a "." on it, like: "Shortcut Open Last.fm". Removing the dot from the string made it work without any problems. Although I managed to fix my error, this should be fixable because the 1.x version of MASShortcut didn't have this kind of issue.

zoul commented 9 years ago

I think I have fixed the issue. Can you please test with the latest version?

zoul commented 9 years ago

Hm, not really, the current test case is passing because it’s broken. Let me take another look.

zoul commented 9 years ago

The problem is that dots in user defaults keys are apparently not 100 % supported by Cocoa.

I have written a test project that binds a user defaults key to a text field. With a plain user defaults key such as foo everything works as expected – the defaults value is propagated to the text field, both initially and when I change the defaults using [[NSUserDefaults standardUserDefaults] setObject:… forKey:…].

Now, when I change the key name to contain a dot (foo.bar), the value is propagated to the text field initially, when the app starts, but subsequent changes to user defaults are not reflected in the text field (though they are written to disk). This is true both for bindings created in the Interface Builder and bindings created in code using bind:toObject:withKeyPath:options:.

In other words, I think you should change your defaults key names to something identifier-like (openLastFm). I have no idea how this could be fixed in MASShortcut – sorry.