Upgrade pods: Alamofire GCDWebServer MASShortcut

This commit is contained in:
Qiu Yuzhou
2019-09-10 14:23:26 +08:00
parent c593564059
commit 075949cdcb
97 changed files with 3392 additions and 2975 deletions

View File

@ -0,0 +1,19 @@
extern NSString *const MASDictionaryTransformerName;
/**
Converts shortcuts for storage in user defaults.
User defaults cant stored custom types directly, they have to
be serialized to `NSData` or some other supported type like an
`NSDictionary`. In Cocoa Bindings, the conversion can be done
using value transformers like this one.
Theres a built-in transformer (`NSKeyedUnarchiveFromDataTransformerName`)
that converts any `NSCoding` types to `NSData`, but with shortcuts
it makes sense to use a dictionary instead the defaults look better
when inspected with the `defaults` command-line utility and the
format is compatible with an older sortcut library called Shortcut
Recorder.
*/
@interface MASDictionaryTransformer : NSValueTransformer
@end

View File

@ -0,0 +1,51 @@
#import "MASDictionaryTransformer.h"
#import "MASShortcut.h"
NSString *const MASDictionaryTransformerName = @"MASDictionaryTransformer";
static NSString *const MASKeyCodeKey = @"keyCode";
static NSString *const MASModifierFlagsKey = @"modifierFlags";
@implementation MASDictionaryTransformer
+ (BOOL) allowsReverseTransformation
{
return YES;
}
// Storing nil values as an empty dictionary lets us differ between
// not available, use default value and explicitly set to none.
// See http://stackoverflow.com/questions/5540760 for details.
- (NSDictionary*) reverseTransformedValue: (MASShortcut*) shortcut
{
if (shortcut == nil) {
return [NSDictionary dictionary];
} else {
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

View File

@ -0,0 +1,67 @@
#import "MASShortcutMonitor.h"
/**
Binds actions to user defaults keys.
If you store shortcuts in user defaults (for example by binding
a `MASShortcutView` to user defaults), you can use this class to
connect an action directly to a user defaults key. If the shortcut
stored under the key changes, the action will get automatically
updated to the new one.
This class is mostly a wrapper around a `MASShortcutMonitor`. It
watches the changes in user defaults and updates the shortcut monitor
accordingly with the new shortcuts.
*/
@interface MASShortcutBinder : NSObject
/**
A convenience shared instance.
You may use it so that you dont have to manage an instance by hand,
but its perfectly fine to allocate and use a separate instance instead.
*/
+ (instancetype) sharedBinder;
/**
The underlying shortcut monitor.
*/
@property(strong) MASShortcutMonitor *shortcutMonitor;
/**
Binding options customizing the access to user defaults.
As an example, you can use `NSValueTransformerNameBindingOption` to customize
the storage format used for the shortcuts. By default the shortcuts are converted
from `NSData` (`NSKeyedUnarchiveFromDataTransformerName`). Note that if the
binder is to work with `MASShortcutView`, both object have to use the same storage
format.
*/
@property(copy) NSDictionary *bindingOptions;
/**
Binds given action to a shortcut stored under the given defaults key.
In other words, no matter what shortcut you store under the given key,
pressing it will always trigger the given action.
*/
- (void) bindShortcutWithDefaultsKey: (NSString*) defaultsKeyName toAction: (dispatch_block_t) action;
/**
Disconnect the binding between user defaults and action.
In other words, the shortcut stored under the given key will no longer trigger an action.
*/
- (void) breakBindingWithDefaultsKey: (NSString*) defaultsKeyName;
/**
Register default shortcuts in user defaults.
This is a convenience frontent to `[NSUserDefaults registerDefaults]`.
The dictionary should contain a map of user defaults keys to appropriate
keyboard shortcuts. The shortcuts will be transformed according to
`bindingOptions` and registered using `registerDefaults`.
*/
- (void) registerDefaultShortcuts: (NSDictionary*) defaultShortcuts;
@end

View File

@ -0,0 +1,121 @@
#import "MASShortcutBinder.h"
#import "MASShortcut.h"
@interface MASShortcutBinder ()
@property(strong) NSMutableDictionary *actions;
@property(strong) NSMutableDictionary *shortcuts;
@end
@implementation MASShortcutBinder
#pragma mark Initialization
- (id) init
{
self = [super init];
[self setActions:[NSMutableDictionary dictionary]];
[self setShortcuts:[NSMutableDictionary dictionary]];
[self setShortcutMonitor:[MASShortcutMonitor sharedMonitor]];
[self setBindingOptions:@{NSValueTransformerNameBindingOption: NSKeyedUnarchiveFromDataTransformerName}];
return self;
}
- (void) dealloc
{
for (NSString *bindingName in [_actions allKeys]) {
[self unbind:bindingName];
}
}
+ (instancetype) sharedBinder
{
static dispatch_once_t once;
static MASShortcutBinder *sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
#pragma mark Registration
- (void) bindShortcutWithDefaultsKey: (NSString*) defaultsKeyName toAction: (dispatch_block_t) action
{
NSAssert([defaultsKeyName rangeOfString:@"."].location == NSNotFound,
@"Illegal character in binding name (“.”), please see http://git.io/x5YS.");
NSAssert([defaultsKeyName rangeOfString:@" "].location == NSNotFound,
@"Illegal character in binding name (“ ”), please see http://git.io/x5YS.");
[_actions setObject:[action copy] forKey:defaultsKeyName];
[self bind:defaultsKeyName
toObject:[NSUserDefaultsController sharedUserDefaultsController]
withKeyPath:[@"values." stringByAppendingString:defaultsKeyName]
options:_bindingOptions];
}
- (void) breakBindingWithDefaultsKey: (NSString*) defaultsKeyName
{
[_shortcutMonitor unregisterShortcut:[_shortcuts objectForKey:defaultsKeyName]];
[_shortcuts removeObjectForKey:defaultsKeyName];
[_actions removeObjectForKey:defaultsKeyName];
[self unbind:defaultsKeyName];
}
- (void) registerDefaultShortcuts: (NSDictionary*) defaultShortcuts
{
NSValueTransformer *transformer = [_bindingOptions valueForKey:NSValueTransformerBindingOption];
if (transformer == nil) {
NSString *transformerName = [_bindingOptions valueForKey:NSValueTransformerNameBindingOption];
if (transformerName) {
transformer = [NSValueTransformer valueTransformerForName:transformerName];
}
}
NSAssert(transformer != nil, @"Cant register default shortcuts without a transformer.");
[defaultShortcuts enumerateKeysAndObjectsUsingBlock:^(NSString *defaultsKey, MASShortcut *shortcut, BOOL *stop) {
id value = [transformer reverseTransformedValue:shortcut];
[[NSUserDefaults standardUserDefaults] registerDefaults:@{defaultsKey:value}];
}];
}
#pragma mark Bindings
- (BOOL) isRegisteredAction: (NSString*) name
{
return !![_actions objectForKey:name];
}
- (id) valueForUndefinedKey: (NSString*) key
{
return [self isRegisteredAction:key] ?
[_shortcuts objectForKey:key] :
[super valueForUndefinedKey:key];
}
- (void) setValue: (id) value forUndefinedKey: (NSString*) key
{
if (![self isRegisteredAction:key]) {
[super setValue:value forUndefinedKey:key];
return;
}
MASShortcut *newShortcut = value;
MASShortcut *currentShortcut = [_shortcuts objectForKey:key];
// Unbind previous shortcut if any
if (currentShortcut != nil) {
[_shortcutMonitor unregisterShortcut:currentShortcut];
}
// Just deleting the old shortcut
if (newShortcut == nil) {
[_shortcuts removeObjectForKey:key];
return;
}
// Bind new shortcut
[_shortcuts setObject:newShortcut forKey:key];
[_shortcutMonitor registerShortcut:newShortcut withAction:[_actions objectForKey:key]];
}
@end