aboutsummaryrefslogtreecommitdiffstats
path: root/Framework
diff options
context:
space:
mode:
authorTomáš Znamenáček2014-08-07 10:47:34 +0200
committerTomáš Znamenáček2015-01-07 15:42:21 +0100
commit942bbe849ed245d8b2e9afcb0a61d66b23beaef9 (patch)
tree2cc9e066d84355099d2334bceac6fa1fb7f5d1b8 /Framework
parent756601488fe195b0b14a8ac9c3c418140d5845f0 (diff)
downloadMASShortcut-942bbe849ed245d8b2e9afcb0a61d66b23beaef9.tar.bz2
Added a custom transformer to store shortcuts as dictionaries.
The MASDictionaryTransformer class is used to save shortcuts to user defaults (and load them back) using a simple dictionary. The value stored in the user defaults looks like this: $ defaults read com.shpakovski.mac.Demo { MASDemoShortcut = { keyCode = 15; modifierFlags = 1048576; }; … } This storage format has got the distinct advantage of being compatible with the format used by Shortcut Recorder. In order to use it, you have to set proper binding options for MASShortcutBinder and the recorder control (MASShortcutView).
Diffstat (limited to 'Framework')
-rw-r--r--Framework/MASDictionaryTransformer.h2
-rw-r--r--Framework/MASDictionaryTransformer.m42
-rw-r--r--Framework/MASDictionaryTransformerTests.m25
-rw-r--r--Framework/MASShortcutBinderTests.m13
-rw-r--r--Framework/Shortcut.h1
5 files changed, 82 insertions, 1 deletions
diff --git a/Framework/MASDictionaryTransformer.h b/Framework/MASDictionaryTransformer.h
new file mode 100644
index 0000000..94c5bc9
--- /dev/null
+++ b/Framework/MASDictionaryTransformer.h
@@ -0,0 +1,2 @@
+@interface MASDictionaryTransformer : NSValueTransformer
+@end
diff --git a/Framework/MASDictionaryTransformer.m b/Framework/MASDictionaryTransformer.m
new file mode 100644
index 0000000..f0d9b2e
--- /dev/null
+++ b/Framework/MASDictionaryTransformer.m
@@ -0,0 +1,42 @@
+#import "MASDictionaryTransformer.h"
+#import "MASShortcut.h"
+
+static NSString *const MASKeyCodeKey = @"keyCode";
+static NSString *const MASModifierFlagsKey = @"modifierFlags";
+
+@implementation MASDictionaryTransformer
+
++ (BOOL) allowsReverseTransformation
+{
+ return YES;
+}
+
+- (NSDictionary*) reverseTransformedValue: (MASShortcut*) shortcut
+{
+ return @{
+ MASKeyCodeKey: @([shortcut keyCode]),
+ MASModifierFlagsKey: @([shortcut modifierFlags])
+ };
+}
+
+- (MASShortcut*) transformedValue: (NSDictionary*) dictionary
+{
+ // We have to be defensive here as the value may come from user defaults.
+ if (![dictionary isKindOfClass:[NSDictionary class]]) {
+ return nil;
+ }
+
+ id keyCodeBox = [dictionary objectForKey:MASKeyCodeKey];
+ id modifierFlagsBox = [dictionary objectForKey:MASModifierFlagsKey];
+
+ SEL integerValue = @selector(integerValue);
+ if (![keyCodeBox respondsToSelector:integerValue] || ![modifierFlagsBox respondsToSelector:integerValue]) {
+ return nil;
+ }
+
+ return [MASShortcut
+ shortcutWithKeyCode:[keyCodeBox integerValue]
+ modifierFlags:[modifierFlagsBox integerValue]];
+}
+
+@end
diff --git a/Framework/MASDictionaryTransformerTests.m b/Framework/MASDictionaryTransformerTests.m
new file mode 100644
index 0000000..78dfa25
--- /dev/null
+++ b/Framework/MASDictionaryTransformerTests.m
@@ -0,0 +1,25 @@
+#import "Shortcut.h"
+
+@interface MASDictionaryTransformerTests : XCTestCase
+@end
+
+@implementation MASDictionaryTransformerTests
+
+- (void) testErrorHandling
+{
+ MASDictionaryTransformer *transformer = [MASDictionaryTransformer new];
+ XCTAssertNil([transformer transformedValue:nil],
+ @"Decoding a shortcut from a nil dictionary returns nil.");
+ XCTAssertNil([transformer transformedValue:(id)@"foo"],
+ @"Decoding a shortcut from a invalid-type dictionary returns nil.");
+ XCTAssertNil([transformer transformedValue:@{}],
+ @"Decoding a shortcut from an empty dictionary returns nil.");
+ XCTAssertNil([transformer transformedValue:@{@"keyCode":@"foo"}],
+ @"Decoding a shortcut from a wrong-typed dictionary returns nil.");
+ XCTAssertNil([transformer transformedValue:@{@"keyCode":@1}],
+ @"Decoding a shortcut from an incomplete dictionary returns nil.");
+ XCTAssertNil([transformer transformedValue:@{@"modifierFlags":@1}],
+ @"Decoding a shortcut from an incomplete dictionary returns nil.");
+}
+
+@end
diff --git a/Framework/MASShortcutBinderTests.m b/Framework/MASShortcutBinderTests.m
index 9259e9d..199eb2f 100644
--- a/Framework/MASShortcutBinderTests.m
+++ b/Framework/MASShortcutBinderTests.m
@@ -1,4 +1,4 @@
-#import "MASShortcutBinder.h"
+#import "Shortcut.h"
static NSString *const SampleDefaultsKey = @"sampleShortcut";
@@ -77,4 +77,15 @@ static NSString *const SampleDefaultsKey = @"sampleShortcut";
@"Bind after unbinding.");
}
+- (void) testTransformerDeserialization
+{
+ MASShortcut *shortcut = [MASShortcut shortcutWithKeyCode:5 modifierFlags:1048576];
+ NSDictionary *storedShortcut = @{@"keyCode": @5, @"modifierFlags": @1048576};
+ [_defaults setObject:storedShortcut forKey:SampleDefaultsKey];
+ [_binder setBindingOptions:@{NSValueTransformerBindingOption:[MASDictionaryTransformer new]}];
+ [_binder bindShortcutWithDefaultsKey:SampleDefaultsKey toAction:^{}];
+ XCTAssertTrue([_monitor isShortcutRegistered:shortcut],
+ @"Deserialize shortcut from user defaults using a custom transformer.");
+}
+
@end
diff --git a/Framework/Shortcut.h b/Framework/Shortcut.h
index dce07a5..df33f17 100644
--- a/Framework/Shortcut.h
+++ b/Framework/Shortcut.h
@@ -2,4 +2,5 @@
#import "MASShortcutValidator.h"
#import "MASShortcutMonitor.h"
#import "MASShortcutBinder.h"
+#import "MASDictionaryTransformer.h"
#import "MASShortcutView.h"