diff options
| author | mo khan <mo@mokhan.ca> | 2013-07-14 15:17:39 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2013-07-14 15:17:39 -0600 |
| commit | 6ff632a1444a214ba61597ae9e1a034e5f1f6073 (patch) | |
| tree | f11725593b3fcb7d266e16d76b57755cd3e39af1 /Pods/BlocksKit | |
| parent | b4051750b51ad5b9ee0574fa5ceaa71649c19e95 (diff) | |
add more pods
Diffstat (limited to 'Pods/BlocksKit')
67 files changed, 6776 insertions, 0 deletions
diff --git a/Pods/BlocksKit/BlocksKit/A2BlockDelegate.h b/Pods/BlocksKit/BlocksKit/A2BlockDelegate.h new file mode 100644 index 0000000..50c448d --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/A2BlockDelegate.h @@ -0,0 +1,103 @@ +// +// A2BlockDelegate.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** The A2BlockDelegate category extends features provided by A2DynamicDelegate + to create custom block properties in a category on a delegating object and + dynamically map them to delegate (`UIAlertViewDelegate`), data source + (`UITableViewDataSource`), or other delegated protocol + (`NSErrorRecoveryAttempting`) methods. + + A2BlockDelegate also supports replacing the delegate of a given class with an + automatic - though optional - version of these block-based properties, while + still allowing for traditional method-based delegate implementations. + + Simply call one of the methods in the category on a class to add a block + property to that class, preferably during a `+load` method in a category. + + To interplay between classes that support delegation but are extended to have + block properties through delegate replacement extended to have block + properties, one should implement an `A2Dynamic<ProtocolName>` subclass of + `A2DynamicDelegate`. This behavior is documented in detail in the class + documentation for A2DynamicDelegate, and examples exist in BlocksKit. + */ +@interface NSObject (A2BlockDelegate) + +/** @name Linking Block Properties */ + +/** Synthesizes multiple properties and links them to the appropriate selector + in the data source protocol. + + A2DynamicDelegate assumes a protocol name `FooBarDataSource` for instances of + class `FooBar`. The method will generate appropriate `setHandler:` and + `handler` implementations for each property name and selector name string pair. + + @param selectorsForPropertyNames A dictionary with property names as keys and + selector strings as objects. + */ ++ (void) linkDataSourceMethods: (NSDictionary *) selectorsForPropertyNames; + +/** Synthesizes multiple properties and links them to the appropriate selector + in the delegate protocol. + + A2DynamicDelegate assumes a protocol name `FooBarDelegate` for instances of + class `FooBar`. The method will generate appropriate `setHandler:` and + `handler` implementations for each property name and selector name string pair. + + @param selectorsForPropertyNames A dictionary with property names as keys and + selectors strings as objects. + */ ++ (void) linkDelegateMethods: (NSDictionary *) selectorsForPropertyNames; + +/** Synthesizes multiple properties and links them to the appropriate selector + in the given protocol. + + The method will generate appropriate `setHandler:` and `handler` + implementations for each property name and selector name string pair. + + @param protocol A protocol that declares all of the given selectors. Must not + be NULL. + @param selectorsForPropertyNames A dictionary with property names as keys and + selector strings as objects. + */ ++ (void) linkProtocol: (Protocol *) protocol methods: (NSDictionary *) selectorsForPropertyNames; + +/** @name Delegate replacement properties */ + +/** Registers a dynamic data source replacement using the property name + `dataSource` and the protocol name `FooBarDataSource` for an instance of + `FooBar`. */ ++ (void) registerDynamicDataSource; + +/** Registers a dynamic delegate replacement using the property name `delegate` + and the protocol name `FooBarDelegate` for an instance of `FooBar`. */ ++ (void) registerDynamicDelegate; + +/** Registers a dynamic data source replacement using the given property name + and the protocol name `FooBarDataSource` for an instance of `FooBar`. + + @param dataSourceName The name of the class' data source property. Must not be + nil. + */ ++ (void) registerDynamicDataSourceNamed: (NSString *) dataSourceName; + +/** Registers a dynamic delegate replacement using the given property name and + the protocol name `FooBarDelegate` for an instance of `FooBar`. + + @param delegateName The name of the class' delegate property. Must not be nil. + */ ++ (void) registerDynamicDelegateNamed: (NSString *) delegateName; + +/** Registers a dynamic protocol implementation replacement + using the given property name and the given protocol. + + @param delegateName The name of the class' delegation protocol property, such + as `safeDelegate`. Must not be nil. + @param protocol A properly encoded protocol. Must not be NULL. + */ ++ (void) registerDynamicDelegateNamed: (NSString *) delegateName forProtocol: (Protocol *) protocol; + +@end diff --git a/Pods/BlocksKit/BlocksKit/A2BlockDelegate.m b/Pods/BlocksKit/BlocksKit/A2BlockDelegate.m new file mode 100755 index 0000000..b3e7c93 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/A2BlockDelegate.m @@ -0,0 +1,249 @@ +// +// A2BlockDelegate.m +// A2DynamicDelegate +// +// Created by Alexsander Akers on 11/30/11. +// Copyright (c) 2011 Pandamonia LLC. All rights reserved. +// + +#import "A2BlockDelegate.h" +#import "A2DynamicDelegate.h" +#import "NSObject+AssociatedObjects.h" +#import "NSDictionary+BlocksKit.h" +#import <objc/message.h> + +#pragma mark - Declarations and macros + +extern Protocol *a2_dataSourceProtocol(Class cls); +extern Protocol *a2_delegateProtocol(Class cls); + +static BOOL bk_object_isKindOfClass(id obj, Class testClass) +{ + BOOL isKindOfClass = NO; + Class cls = object_getClass(obj); + while (cls && !isKindOfClass) + { + isKindOfClass = (cls == testClass); + cls = class_getSuperclass(cls); + } + + return isKindOfClass; +} + +@interface A2DynamicDelegate () + +@property (nonatomic, weak, readwrite) id realDelegate; + +@end + +#pragma mark - Functions + +static SEL getterForProperty(Class cls, NSString *propertyName) +{ + SEL getter = NULL; + + objc_property_t property = class_getProperty(cls, propertyName.UTF8String); + if (property) + { + char *getterName = property_copyAttributeValue(property, "G"); + if (getterName) getter = sel_getUid(getterName); + free(getterName); + } + + if (!getter) + { + getter = NSSelectorFromString(propertyName); + } + + return getter; +} + +static SEL setterForProperty(Class cls, NSString *propertyName) +{ + SEL setter = NULL; + + objc_property_t property = class_getProperty(cls, propertyName.UTF8String); + if (property) + { + char *setterName = property_copyAttributeValue(property, "S"); + if (setterName) setter = sel_getUid(setterName); + free(setterName); + } + + if (!setter) + { + unichar firstChar = [propertyName characterAtIndex: 0]; + NSString *coda = [propertyName substringFromIndex: 1]; + + setter = NSSelectorFromString([NSString stringWithFormat: @"set%c%@:", toupper(firstChar), coda]); + } + + return setter; +} + +static inline SEL prefixedSelector(SEL selector) { + return NSSelectorFromString([@"a2_" stringByAppendingString: NSStringFromSelector(selector)]); +} + +#pragma mark - + +@implementation NSObject (A2BlockDelegate) + +#pragma mark Helper + ++ (NSMutableDictionary *) bk_delegateNameMap +{ + NSMutableDictionary *propertyMap = [self associatedValueForKey: _cmd]; + + if (!propertyMap) + { + propertyMap = [NSMutableDictionary dictionary]; + [self associateValue: propertyMap withKey: _cmd]; + } + + return propertyMap; +} + +#pragma mark Linking block properties + ++ (void) linkDataSourceMethods: (NSDictionary *) dictionary +{ + [self linkProtocol: a2_dataSourceProtocol(self) methods: dictionary]; +} + ++ (void) linkDelegateMethods: (NSDictionary *) dictionary +{ + [self linkProtocol: a2_delegateProtocol(self) methods: dictionary]; +} + ++ (void) linkProtocol: (Protocol *) protocol methods: (NSDictionary *) dictionary +{ + [dictionary each:^(NSString *propertyName, NSString *selectorName) { + objc_property_t property = class_getProperty(self, propertyName.UTF8String); + NSCAssert2(property, @"Property \"%@\" does not exist on class %s", propertyName, class_getName(self)); + + char *dynamic = property_copyAttributeValue(property, "D"); + NSCAssert2(dynamic, @"Property \"%@\" on class %s must be backed with \"@dynamic\"", propertyName, class_getName(self)); + free(dynamic); + + char *copy = property_copyAttributeValue(property, "C"); + NSCAssert2(copy, @"Property \"%@\" on class %s must be defined with the \"copy\" attribute", propertyName, class_getName(self)); + free(copy); + + SEL selector = NSSelectorFromString(selectorName); + SEL getter = getterForProperty(self, propertyName); + SEL setter = setterForProperty(self, propertyName); + + if (class_respondsToSelector(self, setter) || class_respondsToSelector(self, getter)) + return; + + NSString *delegateProperty = nil; + Class cls = self; + while (!delegateProperty.length && cls != [NSObject class]) { + delegateProperty = [cls bk_delegateNameMap][NSStringFromProtocol(protocol)]; + cls = [cls superclass]; + } + + IMP getterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject){ + return [[delegatingObject dynamicDelegateForProtocol: protocol] blockImplementationForMethod: selector]; + }); + IMP setterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject, id block){ + A2DynamicDelegate *dynamicDelegate = [delegatingObject dynamicDelegateForProtocol: protocol]; + + if (delegateProperty.length) { + SEL a2_setter = prefixedSelector(setterForProperty(delegatingObject.class, delegateProperty)); + SEL a2_getter = prefixedSelector(getterForProperty(delegatingObject.class, delegateProperty)); + + if ([delegatingObject respondsToSelector:a2_setter]) { + id originalDelegate = objc_msgSend(delegatingObject, a2_getter); + if (!bk_object_isKindOfClass(originalDelegate, [A2DynamicDelegate class])) + objc_msgSend(delegatingObject, a2_setter, dynamicDelegate); + } + } + + [dynamicDelegate implementMethod: selector withBlock: block]; + }); + + + const char *getterTypes = "@@:"; + BOOL success = class_addMethod(self, getter, getterImplementation, getterTypes); + NSCAssert1(success, @"Could not implement getter for \"%@\" property.", propertyName); + + const char *setterTypes = "v@:@"; + success = class_addMethod(self, setter, setterImplementation, setterTypes); + NSCAssert1(success, @"Could not implement setter for \"%@\" property.", propertyName); + }]; +} + +#pragma mark Dynamic Delegate Replacement + ++ (void) registerDynamicDataSource +{ + [self registerDynamicDelegateNamed: @"dataSource" forProtocol: a2_dataSourceProtocol(self)]; +} ++ (void) registerDynamicDelegate +{ + [self registerDynamicDelegateNamed: @"delegate" forProtocol: a2_delegateProtocol(self)]; +} + ++ (void) registerDynamicDataSourceNamed: (NSString *) dataSourceName +{ + [self registerDynamicDelegateNamed: dataSourceName forProtocol: a2_dataSourceProtocol(self)]; +} ++ (void) registerDynamicDelegateNamed: (NSString *) delegateName +{ + [self registerDynamicDelegateNamed: delegateName forProtocol: a2_delegateProtocol(self)]; +} + ++ (void) registerDynamicDelegateNamed: (NSString *) delegateName forProtocol: (Protocol *) protocol +{ + NSString *protocolName = NSStringFromProtocol(protocol); + NSMutableDictionary *propertyMap = [self bk_delegateNameMap]; + if (propertyMap[protocolName]) + return; + + SEL getter = getterForProperty(self, delegateName); + SEL a2_getter = prefixedSelector(getter); + SEL setter = setterForProperty(self, delegateName); + SEL a2_setter = prefixedSelector(setter); + + IMP getterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject){ + return [[delegatingObject dynamicDelegateForProtocol: protocol] realDelegate]; + }); + + IMP setterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject, id delegate){ + A2DynamicDelegate *dynamicDelegate = [delegatingObject dynamicDelegateForProtocol: protocol]; + + if ([delegatingObject respondsToSelector:a2_setter]) { + id originalDelegate = objc_msgSend(delegatingObject, a2_getter, delegate); + if (!bk_object_isKindOfClass(originalDelegate, [A2DynamicDelegate class])) + objc_msgSend(delegatingObject, a2_setter, dynamicDelegate); + } + + if ([delegate isEqual: dynamicDelegate]) + delegate = nil; + + dynamicDelegate.realDelegate = delegate; + }); + + const char *getterTypes = "@@:"; + const char *setterTypes = "v@:@"; + + if (!class_addMethod(self, getter, getterImplementation, getterTypes)) { + class_addMethod(self, a2_getter, getterImplementation, getterTypes); + Method method = class_getInstanceMethod(self, getter); + Method a2_method = class_getInstanceMethod(self, a2_getter); + method_exchangeImplementations(method, a2_method); + } + + if (!class_addMethod(self, setter, setterImplementation, setterTypes)) { + class_addMethod(self, a2_setter, setterImplementation, setterTypes); + Method method = class_getInstanceMethod(self, setter); + Method a2_method = class_getInstanceMethod(self, a2_setter); + method_exchangeImplementations(method, a2_method); + } + + propertyMap[protocolName] = delegateName; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/A2BlockInvocation.h b/Pods/BlocksKit/BlocksKit/A2BlockInvocation.h new file mode 100644 index 0000000..7ac2525 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/A2BlockInvocation.h @@ -0,0 +1,209 @@ +// +// A2BlockInvocation.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** An `A2BlockInvocation` is an Objective-C block call rendered static, that + is, it is an action turned into an object. `A2BlockInvocation` objects are used + to store and forward closure invocations between objects, primarily by the + `A2DynamicDelegate` system. + + An `A2BlockInvocation` object encapsulates all the elements of an Objective-C + block invocation, including arguments and the return value. Each of these can + be set directly, and the return value is set automatically when the object is + dispatched. + + An `A2BlockInvocation` object can be repeatedly dispatched. Its arguments can + be modified between dispatches for varying results, making it useful for + repeating calls with many arguments. This flexibility makes `A2BlockInvocation` + extremely powerful, because blocks can be used to capture scope and + `A2BlockInvocation` can be used to save them for later. + + Like `NSInvocation`, `A2BlockInvocation` does not support invocations of + methods with variadic arguments or union arguments. + + This class does not retain the arguments for the contained call by default. If + those objects might disappear between the time you create your invocation and + the time you use it, you should call the retainArguments method to have the + invocation object retain them itself. + + `A2BlockInvocation` is powered by [libffi](http://sourceware.org/libffi/), + which serves as a way to call functions like `NSInvocation` calls methods. + This is the only way to do this for now. Get used to it. + */ +@interface A2BlockInvocation : NSObject + +/** @name Creating A2BlockInvocation Objects */ + +/** Returns an `A2BlockInvocation` object able to construct calls using a given + block and a given method signature. + + The new object must have its arguments set with setArgument:atIndex: before it + can be invoked. + + The method signature given must be compatible with the signature of the block. + Generally, this means being all the same except for the removal of the + selector argument, for the block is the first parameter of the block's + function just like `self` is the first parameter of a method. An example method + that returns a string and has an integer argument would have a block signature + of `NSString *(^)(int)`, and an Objective-C method signature `@@i`. + + @param block An Objective-C block literal. + @param methodSignature An Objective-C method signature matching the block. + @return An initialized block invocation object. +*/ +- (id) initWithBlock: (id) block methodSignature: (NSMethodSignature *)methodSignature; + +/** @name Getting the Block and Method Signatures */ + +/** Returns the reciever's method signature. Appropriate for use in + `methodSignatureForSelector:`, and reflects the method *with* a selector. */ +@property (nonatomic, strong, readonly) NSMethodSignature *methodSignature; + +/** Returns the reciever's block signature. Intended for use in compatibility + comparison, and generally not useful. */ +@property (nonatomic, strong, readonly) NSMethodSignature *blockSignature; + +/** Returns the reciever's block. Can be used to call it manually, if you + know its signature. */ +@property (nonatomic, copy, readonly) id block; + +/** @name Configuring a Block Invocation Object */ + +/** If the receiver hasn’t already done so, retains all object arguments of the + receiver and copies all of its C-string arguments. + + Before this method is invoked, argumentsRetained returns NO; after, it returns + YES. + + For efficiency, newly created block invocations don’t retain or copy their + arguments, nor do they retain their targets or copy C strings. You should + instruct a block invocation to retain its arguments if you intend to cache it, + since the arguments may otherwise be released before the NSInvocation is + invoked. + + Note that objects referenced in the scope of the block are generally retained. + + @see argumentsRetained + */ +- (void) retainArguments; + +/** Returns YES if the receiver has retained its arguments, NO otherwise. + + @see retainArguments + */ +- (BOOL) argumentsRetained; + +/** Gets the receiver's return value. + + Use the `NSMethodSignature` method `-methodReturnLength` to determine the size + needed for the buffer: + + NSUInteger length = [[myInvocation methodSignature] methodReturnLength]; + buffer = (void *)malloc(length); + [invocation getReturnValue:buffer]; + + When the return value is an object (or a pointer), pass a pointer to the + variable (or memory) into which the object should be placed: + + id anObject; + NSArray *anArray; + [invocation1 getReturnValue:&anObject]; + [invocation2 getReturnValue:&anArray]; + + If the block invocation object has never been invoked, the result of this + method is undefined and is not recommended. + + @param retLoc An untyped buffer into which the receiver copies its return + value. It should be large enough to accommodate the value. See the discussion + for more information. + @see setReturnValue: + */ +- (void) getReturnValue: (void *) retLoc; + +/** Sets the receiver’s return value. + + This value is normally set when you send an invoke message. + + @param retLoc An untyped buffer whose contents are copied as the receiver's + return value. + @see invoke + @see getReturnValue: + */ +- (void) setReturnValue: (void *) retLoc; + +/** Returns by indirection the receiver's argument at a specified index. + + This method copies the argument stored at index into the storage pointed to by + buffer. The size of buffer must be large enough to accommodate the argument value. + + When the argument value is an object, pass a pointer to the variable + (or memory) into which the object should be placed: + + NSArray *anArray; + [invocation getArgument:&anArray atIndex:3]; + + This method raises NSInvalidArgumentException if idx is greater than the + actual number of arguments for the selector. + + @param argumentLocation An untyped buffer to hold the returned argument. See + the discussion relating to argument values that are objects. + @param idx An integer specifying the index of the argument to get, starting + at 0 representing the first argument of the underlying block. + @see setArgument:atIndex: + */ +- (void) getArgument: (void *) argumentLocation atIndex: (NSInteger) idx; + +/** Sets an argument of the receiver. + + This method copies the contents of buffer as the argument at index. The number + of bytes copied is determined by the argument size. + + When the argument value is an object, pass a pointer to the variable + (or memory) from which the object should be copied: + + NSArray *anArray; + [invocation setArgument:&anArray atIndex:3]; + + This method raises NSInvalidArgumentException if the value of index is greater + than the actual number of arguments for the selector. + + @param argumentLocation An untyped buffer containing an argument to be assigned + to the receiver. See the discussion relating to arguments that are objects. + @param idx An integer specifying the index of the argument, starting at 0 + representing the first argument of the underlying block. + */ +- (void) setArgument: (void *) argumentLocation atIndex: (NSInteger) idx; + +/** Unsets all arguments in the block invocation, including releasing any + objects if argumentsRetained is YES. */ +- (void) clearArguments; + +/** @name Dispatching an Invocation */ + +/** Calls the receiver's block (with arguments) and sets the return value. + + You must set the receiver's argument values before calling this method. + + @see setArgument:atIndex: + @see getReturnValue: + */ +- (void) invoke; + +/** Calls the receiver's block with the arguments from the given invocation, + and sets the return value both on the receiving invocation and the given + invocation. + + Copying arguments will exclude the target and selector of the given invocation. + Otherwise, this method raises NSInvalidArgumentException if the number of + arguments in both invocations are not appropriately matched. + + @param inv An instance of NSInvocation with values for its arguments set. + @see setArgument:atIndex: + @see getReturnValue: + */ +- (void) invokeUsingInvocation: (NSInvocation *) inv; + +@end diff --git a/Pods/BlocksKit/BlocksKit/A2BlockInvocation.m b/Pods/BlocksKit/BlocksKit/A2BlockInvocation.m new file mode 100644 index 0000000..02b9d31 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/A2BlockInvocation.m @@ -0,0 +1,516 @@ +// +// A2BlockInvocation.m +// A2DynamicDelegate +// +// Created by Zachary Waldowski on 10/3/12. +// Copyright (c) 2012 Pandamonia LLC. All rights reserved. +// + +#import "A2BlockInvocation.h" +#import <objc/runtime.h> + +#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) + #import <ffi/ffi.h> +#else + #import <CoreGraphics/CoreGraphics.h> + #import <ffi.h> +#endif + +#pragma mark Block Internals + +typedef NS_ENUM(int, BKBlockFlags) { + BKBlockFlagsHasCopyDisposeHelpers = (1 << 25), + BKBlockFlagsHasConstructor = (1 << 26), + BKBlockFlagsIsGlobal = (1 << 28), + BKBlockFlagsReturnsStruct = (1 << 29), + BKBlockFlagsHasSignature = (1 << 30) +}; + +typedef struct _BKBlock { + void *isa; + BKBlockFlags flags; + int reserved; + void (*invoke)(void); + struct { + unsigned long int reserved; + unsigned long int size; + // requires BKBlockFlagsHasCopyDisposeHelpers + void (*copy)(void *dst, const void *src); + void (*dispose)(const void *); + // requires BKBlockFlagsHasSignature + const char *signature; + const char *layout; + } *descriptor; + // imported variables +} *BKBlockRef; + +static NSMethodSignature *a2_blockGetSignature(id block) { + BKBlockRef layout = (__bridge void *)block; + + if (!(layout->flags & BKBlockFlagsHasSignature)) + return nil; + + void *desc = layout->descriptor; + desc += 2 * sizeof(unsigned long int); + + if (layout->flags & BKBlockFlagsHasCopyDisposeHelpers) + desc += 2 * sizeof(void *); + + if (!desc) + return nil; + + const char *signature = (*(const char **)desc); + return [NSMethodSignature signatureWithObjCTypes: signature]; +} + +static void (*a2_blockGetInvoke(void *block))(void) { + BKBlockRef layout = block; + return layout->invoke; +} + +#pragma mark - Core Graphics FFI types + +static const ffi_type *_ffi_type_elements_nsrange[] = { &ffi_type_ulong, &ffi_type_ulong, NULL }; +static ffi_type ffi_type_nsrange = { sizeof(NSRange), __alignof(NSRange), FFI_TYPE_STRUCT, (ffi_type **)_ffi_type_elements_nsrange }; + +#if CGFLOAT_IS_DOUBLE + static const ffi_type *_ffi_type_elements_cgpoint[] = { &ffi_type_double, &ffi_type_double, NULL }; + static const ffi_type *_ffi_type_elements_cgsize[] = { &ffi_type_double, &ffi_type_double, NULL }; +#else + static const ffi_type *_ffi_type_elements_cgpoint[] = { &ffi_type_float, &ffi_type_float, NULL }; + static const ffi_type *_ffi_type_elements_cgsize[] = { &ffi_type_float, &ffi_type_float, NULL }; +#endif + +static ffi_type ffi_type_cgpoint = { sizeof(CGPoint), __alignof(CGPoint), FFI_TYPE_STRUCT, (ffi_type **)_ffi_type_elements_cgpoint }; +static ffi_type ffi_type_cgsize = { sizeof(CGSize), __alignof(CGSize), FFI_TYPE_STRUCT, (ffi_type **)_ffi_type_elements_cgsize }; + +static const ffi_type *_ffi_type_elements_cgrect[] = { &ffi_type_cgpoint, &ffi_type_cgsize, NULL }; +static ffi_type ffi_type_cgrect = { sizeof(CGRect), __alignof(CGRect), FFI_TYPE_STRUCT, (ffi_type **)_ffi_type_elements_cgrect }; + +static ffi_type ffi_type_selector = { sizeof(SEL), __alignof(SEL), FFI_TYPE_POINTER, NULL }; +static ffi_type ffi_type_class = { sizeof(Class), __alignof(Class), FFI_TYPE_POINTER, NULL }; +static ffi_type ffi_type_id = { sizeof(id), __alignof(id), FFI_TYPE_POINTER, NULL }; +static ffi_type ffi_type_charptr = { sizeof(char *), __alignof(char *), FFI_TYPE_POINTER, NULL }; + +#pragma mark - Helper functions + +static inline const char *a2_skipStructName(const char *type) { + if (*type == _C_STRUCT_B) type++; + + if (*type == _C_UNDEF) + { + type++; + } + else if (isalpha(*type) || *type == '_') + { + while (isalnum(*type) || *type == '_') + { + type++; + } + } + else + { + return type; + } + + if (*type == '=') type++; + + return type; +} + +static inline NSUInteger a2_getStructSize(const char *encodingType) { + if (*encodingType != _C_STRUCT_B) return -1; + while (*encodingType != _C_STRUCT_E && *encodingType++ != '='); // skip "<name>=" + + NSUInteger ret = 0; + while (*encodingType != _C_STRUCT_E) + { + encodingType = NSGetSizeAndAlignment(encodingType, NULL, NULL); + ret++; + } + + return ret; +} + +static inline NSUInteger a2_sizeForType(ffi_type *type) { + size_t size = type->size, align = type->alignment; + return (size % align != 0) ? size + (align - size % align) : size; +} + +static ffi_type *a2_typeForSignature(const char *argumentType, void *(^allocate)(size_t)) { + switch (*argumentType) { + case _C_CLASS: return &ffi_type_class; break; + case _C_SEL: return &ffi_type_selector; break; + case _C_ID: return &ffi_type_id; break; + case _C_CHARPTR: return &ffi_type_charptr; break; + case _C_ATOM: + case _C_PTR: + return &ffi_type_pointer; break; + case _C_BOOL: + case _C_UCHR: + return &ffi_type_uchar; break; + case _C_CHR: return &ffi_type_schar; break; + case _C_SHT: return &ffi_type_sshort; break; + case _C_USHT: return &ffi_type_ushort; break; + case _C_INT: return &ffi_type_sint; break; + case _C_UINT: return &ffi_type_uint; break; + case _C_LNG: return &ffi_type_slong; break; + case _C_ULNG: return &ffi_type_ulong; break; + case _C_LNG_LNG: return &ffi_type_sint64; break; + case _C_ULNG_LNG: return &ffi_type_uint64; break; + case _C_FLT: return &ffi_type_float; break; + case _C_DBL: return &ffi_type_double; break; + case _C_VOID: return &ffi_type_void; break; + case _C_BFLD: + case _C_ARY_B: + { + NSUInteger size, align; + NSGetSizeAndAlignment(argumentType, &size, &align); + + if (size > 0) + { + if (size == 1) + return &ffi_type_uchar; + else if (size == 2) + return &ffi_type_ushort; + else if (size <= 4) + return &ffi_type_uint; + else if (size > sizeof(void *)) + return &ffi_type_pointer; + else + { + ffi_type *type = allocate(sizeof(ffi_type)); + type->size = size; + type->alignment = (unsigned short)align; + type->type = FFI_TYPE_STRUCT; + type->elements = allocate((size + 1) * sizeof(ffi_type *)); + for (NSUInteger i = 0; i < size; i++) + type->elements[i] = &ffi_type_uchar; + type->elements[size] = NULL; + return type; + } + + break; + } + } + case _C_STRUCT_B: + { + if (!strcmp(argumentType, @encode(NSRange))) + { + return &ffi_type_nsrange; break; + } + else if (!strcmp(argumentType, @encode(CGSize))) + { + return &ffi_type_cgsize; break; + } + else if (!strcmp(argumentType, @encode(CGPoint))) + { + return &ffi_type_cgpoint; break; + } + else if (!strcmp(argumentType, @encode(CGRect))) + { + return &ffi_type_cgrect; break; + } +#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) + else if (!strcmp(argumentType, @encode(NSSize))) + { + return &ffi_type_cgsize; break; + } + else if (!strcmp(argumentType, @encode(NSPoint))) + { + return &ffi_type_cgpoint; break; + } + else if (!strcmp(argumentType, @encode(NSRect))) + { + return &ffi_type_cgrect; break; + } +#endif + + NSUInteger size, align; + NSGetSizeAndAlignment(argumentType, &size, &align); + + ffi_type *type = allocate(sizeof(ffi_type)); + type->size = size; + type->alignment = (unsigned short)align; + type->type = FFI_TYPE_STRUCT; + type->elements = allocate((a2_getStructSize(argumentType) + 1) * sizeof(ffi_type *)); + + size_t index = 0; + argumentType = a2_skipStructName(argumentType); + while (*argumentType != _C_STRUCT_E) + { + type->elements[index] = a2_typeForSignature(argumentType, allocate); + argumentType = NSGetSizeAndAlignment(argumentType, NULL, NULL); + index++; + } + + type->elements[index] = NULL; + return type; + break; + } + default: + { + NSCAssert(0, @"Unknown type in sig"); + return &ffi_type_void; + break; + } + } +} + +@interface A2BlockInvocation () { + BOOL _argumentsRetained; + BOOL _validReturn; + void **_argumentFrame; + void *_returnValue; + size_t _returnLength; + void *_block; +} + +@property (nonatomic, strong, readwrite, setter = a2_setMethodSignature:) NSMethodSignature *methodSignature; +@property (nonatomic, strong, readwrite, setter = a2_setBlockSignature:) NSMethodSignature *blockSignature; +@property (nonatomic, strong) NSMutableArray *allocations; +@property (nonatomic, strong) NSMutableDictionary *arguments; +@property (nonatomic) ffi_cif interface; + +@end + +@implementation A2BlockInvocation + +- (id) initWithBlock: (id) block methodSignature: (NSMethodSignature *)methodSignature +{ + NSParameterAssert(block); + NSMethodSignature *blockSignature = a2_blockGetSignature(block); + NSCAssert1(blockSignature, @"Incompatible block: %@", block); + + if ((self = [super init])) { + NSMutableArray *allocations = [NSMutableArray new]; + + void *(^allocate)(size_t) = ^(size_t howmuch){ + void *buffer = calloc(howmuch, 1); + [allocations addObject: [NSData dataWithBytesNoCopy: buffer length: howmuch]]; + return buffer; + }; + + ffi_type *returnType = a2_typeForSignature(blockSignature.methodReturnType, allocate); + if (returnType->type != FFI_TYPE_VOID) { + _returnLength = a2_sizeForType(returnType); + _returnValue = allocate(_returnLength); + } + + unsigned int argCount = (unsigned int)blockSignature.numberOfArguments; + + ffi_type **methodArgs = allocate(argCount * sizeof(ffi_type *)); + _argumentFrame = allocate(argCount * sizeof(void *)); + + methodArgs[0] = &ffi_type_pointer; + + for (NSUInteger i = 1; i < argCount; i++) + { + methodArgs[i] = a2_typeForSignature([blockSignature getArgumentTypeAtIndex: i], allocate); + _argumentFrame[i] = allocate(a2_sizeForType(methodArgs[i])); + } + + ffi_cif cif; + ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, argCount, returnType, methodArgs); + NSCAssert2(status == FFI_OK, @"%@ - Unable to create function interface for block: %@", [self class], [self block]); + + _block = (void *) Block_copy((__bridge void *) block); + self.methodSignature = methodSignature; + self.blockSignature = blockSignature; + self.allocations = allocations; + self.arguments = [NSMutableDictionary dictionaryWithCapacity:cif.nargs-1]; + self.interface = cif; + + _argumentFrame[0] = &_block; + } + return self; +} + +- (id) block +{ + return (__bridge id) _block; +} + +- (void) clearArguments +{ + for (int i = 0; i < self.interface.nargs - 1; i++) + [self setArgument: 0 atIndex: i]; +} +- (void) dealloc +{ + [self setReturnValue: nil]; + Block_release(_block); +} + +- (void) retainArguments +{ + if (!_argumentsRetained) + { + ffi_cif cif = self.interface; + + for (NSUInteger i = 1; i < cif.nargs; i++) + { + if (cif.arg_types[i] == &ffi_type_id) + { + id argument = *(__unsafe_unretained id *)_argumentFrame[i]; + if (argument) self.arguments[@(i)] = argument; + } + else if (cif.arg_types[i] == &ffi_type_charptr) + { + char *old = *(char **)_argumentFrame[i]; + if (!old) continue; + NSNumber *key = @(i); + NSData *currentData = self.arguments[key]; + if (currentData.bytes == old) continue; + + char *new = strdup(old); + currentData = [NSData dataWithBytesNoCopy:new length:strlen(new) freeWhenDone:YES]; + self.arguments[key] = currentData; + const char *newPtr = currentData.bytes; + memcpy(_argumentFrame[i], &newPtr, a2_sizeForType(&ffi_type_charptr)); + } + } + + _argumentsRetained = YES; + } +} +- (BOOL) argumentsRetained +{ + return _argumentsRetained; +} + +- (void) getReturnValue: (void *) retLoc +{ + if (!_validReturn) return; + memcpy(retLoc, _returnValue, _returnLength); +} +- (void) setReturnValue: (void *) retLoc +{ + ffi_type *returnType = self.interface.rtype; + if (returnType == &ffi_type_void) + return; + else if (returnType == &ffi_type_id) + { + if (_validReturn) + *(__autoreleasing id *) _returnValue = nil; + else + *(__unsafe_unretained id *) _returnValue = nil; + + if (retLoc) + { + *(__strong id *) _returnValue = *(__unsafe_unretained id *)retLoc; + _validReturn = YES; + } + else + { + *(__unsafe_unretained id *) _returnValue = nil; + _validReturn = NO; + } + } + else + { + if (retLoc) + { + memcpy(_returnValue, retLoc, _returnLength); + _validReturn = YES; + } + else + _validReturn = NO; + } +} + +- (void) getArgument: (void *) buffer atIndex: (NSInteger) idx +{ + idx++; + ffi_cif cif = self.interface; + NSParameterAssert(idx >= 0 && idx < cif.nargs); + memcpy(buffer, _argumentFrame[idx], a2_sizeForType(cif.arg_types[idx])); +} +- (void) setArgument: (void *) buffer atIndex: (NSInteger) idx +{ + idx++; + ffi_cif cif = self.interface; + NSParameterAssert(idx >= 0 && idx < cif.nargs); + + if (_argumentsRetained) + { + ffi_type *type = cif.arg_types[idx]; + if (type == &ffi_type_id) + { + NSNumber *key = @(idx); + [self.arguments removeObjectForKey: key]; + + if (buffer) + { + id new = *(__unsafe_unretained id *)buffer; + if (new) self.arguments[key] = new; + } + } + else if (type == &ffi_type_charptr) + { + NSNumber *key = @(idx); + [self.arguments removeObjectForKey: key]; + + if (buffer) + { + char *new = *(char**)buffer; + if (new) + { + NSMutableData *wrap = [NSMutableData dataWithBytes:new length:strlen(new)]; + self.arguments[key] = wrap; + new = wrap.mutableBytes; + buffer = &new; + } + } + } + } + + if (buffer) + memcpy(_argumentFrame[idx], buffer, a2_sizeForType(cif.arg_types[idx])); + else + memset(_argumentFrame[idx], 0, a2_sizeForType(cif.arg_types[idx])); +} + +- (void) invoke +{ + ffi_cif cif = self.interface; + void *returnValue = malloc(_returnLength); + ffi_call(&cif, a2_blockGetInvoke(_block), returnValue, _argumentFrame); + [self setReturnValue: returnValue]; + free(returnValue); +} +- (void) invokeUsingInvocation: (NSInvocation *) inv +{ + if (![inv isMemberOfClass: [NSInvocation class]]) + return; + + NSParameterAssert(inv.methodSignature.numberOfArguments - 1 == self.interface.nargs); + + [inv retainArguments]; + + for (int i = 0; i < self.interface.nargs - 1; i++) + { + ffi_type *type = self.interface.arg_types[i]; + if (!type) break; + + size_t argSize = a2_sizeForType(type); + void *thisArgument = malloc(argSize); + if (!thisArgument) break; + + [inv getArgument: thisArgument atIndex: i + 2]; + [self setArgument: thisArgument atIndex: i]; + free(thisArgument); + } + + [self invoke]; + + if (_returnLength) + { + void *returnValue = malloc(_returnLength); + [self getReturnValue: returnValue]; + [inv setReturnValue: returnValue]; + free(returnValue); + } +} + +@end diff --git a/Pods/BlocksKit/BlocksKit/A2DynamicDelegate.h b/Pods/BlocksKit/BlocksKit/A2DynamicDelegate.h new file mode 100644 index 0000000..f9ac811 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/A2DynamicDelegate.h @@ -0,0 +1,138 @@ +// +// A2DynamicDelegate.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** A2DynamicDelegate implements a class's delegate, data source, or other + delegated protocol by associating protocol methods with a block implementation. + + - (IBAction) annoyUser + { + // Create an alert view + UIAlertView *alertView = [[UIAlertView alloc] + initWithTitle: @"Hello World!" + message: @"This alert's delegate is implemented using blocks. That's so cool!" + delegate: nil + cancelButtonTitle: @"Meh." + otherButtonTitles: @"Woo!", nil]; + + // Get the dynamic delegate + A2DynamicDelegate *dd = alertView.dynamicDelegate; + + // Implement -alertViewShouldEnableFirstOtherButton: + [dd implementMethod: @selector(alertViewShouldEnableFirstOtherButton:) withBlock: ^(UIAlertView *alertView) { + NSLog(@"Message: %@", alertView.message); + return YES; + }]; + + // Implement -alertView:willDismissWithButtonIndex: + [dd implementMethod: @selector(alertView:willDismissWithButtonIndex:) withBlock: ^(UIAlertView *alertView, NSInteger buttonIndex) { + NSLog(@"You pushed button #%d (%@)", buttonIndex, [alertView buttonTitleAtIndex: buttonIndex]); + }]; + + // Set the delegate + alertView.delegate = dd; + + [alertView show]; + [alertView release]; + } + + A2DynamicDelegate is designed to be 'plug and play'. + */ +@interface A2DynamicDelegate : NSProxy + +/** + * The designated initializer for the A2DynamicDelegate proxy. + * + * An instance of A2DynamicDelegate should generally not be created by the user, + * but instead by calling a method in NSObject(A2DynamicDelegate). Since + * delegates are usually weak references on the part of the delegating object, a + * dynamic delegate would be deallocated immediately after its declaring scope + * ends. NSObject(A2DynamicDelegate) creates a strong reference. + * + * @param protocol A protocol to which the dynamic delegate should conform. + * @return An initialized delegate proxy. + */ +- (id)initWithProtocol:(Protocol *)protocol; + +/** The protocol delegating the dynamic delegate. */ +@property (nonatomic, readonly) Protocol *protocol; + +/** A dictionary of custom handlers to be used by custom responders + in a A2Dynamic(Protocol Name) subclass of A2DynamicDelegate, like + `A2DynamicUIAlertViewDelegate`. */ +@property (nonatomic, strong, readonly) NSMutableDictionary *handlers; + +/** When replacing the delegate using the A2BlockDelegate extensions, the object + responding to classical delegate method implementations. */ +@property (nonatomic, weak, readonly) id realDelegate; + +/** @name Block Instance Method Implementations */ + +/** The block that is to be fired when the specified + selector is called on the reciever. + + @param selector An encoded selector. Must not be NULL. + @return A code block, or nil if no block is assigned. + */ +- (id) blockImplementationForMethod: (SEL) selector; + +/** Assigns the given block to be fired when the specified + selector is called on the reciever. + + [tableView.dynamicDataSource implementMethod:@selector(numberOfSectionsInTableView:) + withBlock:NSInteger^(UITableView *tableView){ + return 2; + }]; + + @warning Starting with A2DynamicDelegate 2.0, a block will + not be checked for a matching signature. A block can have + less parameters than the original selector and will be + ignored, but cannot have more. + + @param selector An encoded selector. Must not be NULL. + @param block A code block with the same signature as selector. + */ +- (void) implementMethod: (SEL) selector withBlock: (id) block; + +/** Disassociates any block so that nothing will be fired + when the specified selector is called on the reciever. + + @param selector An encoded selector. Must not be NULL. + */ +- (void) removeBlockImplementationForMethod: (SEL) selector; + +/** @name Block Class Method Implementations */ + +/** The block that is to be fired when the specified + selector is called on the delegating object's class. + + @param selector An encoded selector. Must not be NULL. + @return A code block, or nil if no block is assigned. + */ +- (id) blockImplementationForClassMethod: (SEL) selector; + +/** Assigns the given block to be fired when the specified + selector is called on the reciever. + + @warning Starting with A2DynamicDelegate 2.0, a block will + not be checked for a matching signature. A block can have + less parameters than the original selector and will be + ignored, but cannot have more. + + @param selector An encoded selector. Must not be NULL. + @param block A code block with the same signature as selector. + */ +- (void) implementClassMethod: (SEL) selector withBlock: (id) block; + +/** Disassociates any blocks so that nothing will be fired + when the specified selector is called on the delegating + object's class. + + @param selector An encoded selector. Must not be NULL. + */ +- (void) removeBlockImplementationForClassMethod: (SEL) selector; + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/A2DynamicDelegate.m b/Pods/BlocksKit/BlocksKit/A2DynamicDelegate.m new file mode 100755 index 0000000..9847559 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/A2DynamicDelegate.m @@ -0,0 +1,289 @@ +// +// A2DynamicDelegate.m +// A2DynamicDelegate +// +// Created by Alexsander Akers on 11/26/11. +// Copyright (c) 2011 Pandamonia LLC. All rights reserved. +// + +#import "A2DynamicDelegate.h" +#import "A2BlockInvocation.h" +#import <objc/message.h> + +Protocol *a2_dataSourceProtocol(Class cls); +Protocol *a2_delegateProtocol(Class cls); + +static BOOL a2_methodSignaturesCompatible(NSMethodSignature *methodSignature, NSMethodSignature *blockSignature) +{ + if (strcmp(methodSignature.methodReturnType, blockSignature.methodReturnType)) + return NO; + + NSUInteger numberOfArguments = methodSignature.numberOfArguments; + for (NSUInteger i = 2; i < numberOfArguments; i++) { + if (strcmp([methodSignature getArgumentTypeAtIndex: i], [blockSignature getArgumentTypeAtIndex: i - 1])) + return NO; + } + return YES; +} + +@interface A2DynamicClassDelegate : A2DynamicDelegate + +@property (nonatomic) Class proxiedClass; + +#pragma mark - Unavailable Methods + +- (id) blockImplementationForClassMethod: (SEL) selector NS_UNAVAILABLE; + +- (void) implementClassMethod: (SEL) selector withBlock: (id) block NS_UNAVAILABLE; +- (void) removeBlockImplementationForClassMethod: (SEL) selector NS_UNAVAILABLE; + +@end + +#pragma mark - + +@interface A2DynamicDelegate () + +@property (nonatomic, readwrite) Protocol *protocol; +@property (nonatomic, strong) A2DynamicClassDelegate *classProxy; +@property (nonatomic, strong, readonly) NSMutableDictionary *blockInvocations; +@property (nonatomic, weak, readwrite) id realDelegate; + +- (BOOL) isClassProxy; + +@end + +@implementation A2DynamicDelegate + +- (A2DynamicClassDelegate *) classProxy +{ + if (!_classProxy) + { + _classProxy = [[A2DynamicClassDelegate alloc] initWithProtocol: self.protocol]; + _classProxy.proxiedClass = object_getClass(self); + } + + return _classProxy; +} + +- (BOOL) isClassProxy +{ + return NO; +} + +- (Class) class +{ + Class myClass = object_getClass(self); + if (myClass == [A2DynamicDelegate class] || [myClass superclass] == [A2DynamicDelegate class]) + return (Class) self.classProxy; + return [super class]; +} + +- (id) initWithProtocol:(Protocol *)protocol +{ + _protocol = protocol; + _handlers = [NSMutableDictionary dictionary]; + _blockInvocations = [NSMutableDictionary dictionary]; + return self; +} + +- (NSMethodSignature*) methodSignatureForSelector: (SEL) aSelector +{ + NSString *key = NSStringFromSelector(aSelector); + if (self.blockInvocations[key]) + return [self.blockInvocations[key] methodSignature]; + else if ([self.realDelegate methodSignatureForSelector: aSelector]) + return [self.realDelegate methodSignatureForSelector: aSelector]; + else if (class_respondsToSelector(object_getClass(self), aSelector)) + return [object_getClass(self) methodSignatureForSelector: aSelector]; + return [[NSObject class] methodSignatureForSelector: aSelector]; +} + ++ (NSString *) description +{ + return @"A2DynamicDelegate"; +} +- (NSString *) description +{ + return [NSString stringWithFormat: @"<A2DynamicDelegate: %p; protocol = %@>", self, NSStringFromProtocol(self.protocol)]; +} + +- (void) forwardInvocation: (NSInvocation *) outerInv +{ + A2BlockInvocation *innerInv = self.blockInvocations[NSStringFromSelector(outerInv.selector)]; + if (innerInv) + [innerInv invokeUsingInvocation: outerInv]; + else if ([self.realDelegate respondsToSelector: outerInv.selector]) + [outerInv invokeWithTarget: self.realDelegate]; +} + +#pragma mark - + +- (BOOL) conformsToProtocol: (Protocol *) aProtocol +{ + return protocol_isEqual(aProtocol, self.protocol) || [super conformsToProtocol: aProtocol]; +} +- (BOOL) respondsToSelector: (SEL) selector +{ + return self.blockInvocations[NSStringFromSelector(selector)] || class_respondsToSelector(object_getClass(self), selector) || [self.realDelegate respondsToSelector: selector]; +} + +- (void) doesNotRecognizeSelector: (SEL) aSelector +{ + [NSException raise: NSInvalidArgumentException format: @"-[%s %@]: unrecognized selector sent to instance %p", object_getClassName(self), NSStringFromSelector(aSelector), self]; +} + +#pragma mark - Block Instance Method Implementations + +- (id) blockImplementationForMethod: (SEL) selector +{ + return [self.blockInvocations[NSStringFromSelector(selector)] block]; +} + +- (void) implementMethod: (SEL) selector withBlock: (id) block +{ + NSCAssert(selector, @"Attempt to implement or remove NULL selector"); + BOOL isClassMethod = self.isClassProxy; + NSString *key = NSStringFromSelector(selector); + + if (!block) + { + [self.blockInvocations removeObjectForKey: key]; + return; + } + + struct objc_method_description methodDescription = protocol_getMethodDescription(self.protocol, selector, YES, !isClassMethod); + if (!methodDescription.name) methodDescription = protocol_getMethodDescription(self.protocol, selector, NO, !isClassMethod); + if (!methodDescription.name) return; + + NSMethodSignature *protoSig = [NSMethodSignature signatureWithObjCTypes: methodDescription.types]; + A2BlockInvocation *inv = [[A2BlockInvocation alloc] initWithBlock: block methodSignature: protoSig]; + + NSCAssert3(a2_methodSignaturesCompatible(inv.methodSignature, inv.blockSignature), @"Attempt to implement %s selector with incompatible block (selector: %c%s)", isClassMethod ? "class" : "instance", "-+"[!!isClassMethod], sel_getName(selector)); + + self.blockInvocations[key] = inv; +} +- (void) removeBlockImplementationForMethod: (SEL) selector +{ + [self implementMethod: selector withBlock: NULL]; +} + +#pragma mark - Block Class Method Implementations + +- (id) blockImplementationForClassMethod: (SEL) selector +{ + return [self.classProxy blockImplementationForMethod: selector]; +} + +- (void) implementClassMethod: (SEL) selector withBlock: (id) block +{ + [self.classProxy implementMethod: selector withBlock: block]; +} +- (void) removeBlockImplementationForClassMethod: (SEL) selector +{ + [self.classProxy implementMethod: selector withBlock: NULL]; +} + +@end + +#pragma mark - + +@implementation A2DynamicClassDelegate +{ + Class _proxiedClass; +} + +- (BOOL) isClassProxy +{ + return YES; +} +- (BOOL) isEqual: (id) object +{ + return [super isEqual: object] || [_proxiedClass isEqual: object]; +} +- (BOOL) respondsToSelector: (SEL) aSelector +{ + return self.blockInvocations[NSStringFromSelector(aSelector)] || [_proxiedClass respondsToSelector: aSelector]; +} + +- (Class) class +{ + return _proxiedClass; +} + +- (id) initWithClass: (Class) proxy +{ + if ((self = [super initWithProtocol: NULL])) + { + _proxiedClass = proxy; + } + + return self; +} + +- (NSMethodSignature *) methodSignatureForSelector: (SEL) aSelector +{ + NSString *key = NSStringFromSelector(aSelector); + if (self.blockInvocations[key]) + return [self.blockInvocations[key] methodSignature]; + else if ([_proxiedClass methodSignatureForSelector: aSelector]) + return [_proxiedClass methodSignatureForSelector: aSelector]; + return [[NSObject class] methodSignatureForSelector: aSelector]; +} + +- (NSString *) description +{ + return [_proxiedClass description]; +} + +- (NSUInteger) hash +{ + return [_proxiedClass hash]; +} + +- (void) forwardInvocation: (NSInvocation *) invoc +{ + if (self.blockInvocations[NSStringFromSelector(invoc.selector)]) + [super forwardInvocation: invoc]; + else + [invoc invokeWithTarget: _proxiedClass]; +} + +#pragma mark - Unavailable Methods + +- (id) blockImplementationForClassMethod: (SEL) selector +{ + [self doesNotRecognizeSelector: _cmd]; + return nil; +} + +- (void) implementClassMethod: (SEL) selector withBlock: (id) block +{ + [self doesNotRecognizeSelector: _cmd]; +} +- (void) removeBlockImplementationForClassMethod: (SEL) selector +{ + [self doesNotRecognizeSelector: _cmd]; +} + +@end + +#pragma mark - Helper functions + +Protocol *a2_dataSourceProtocol(Class cls) +{ + NSString *className = NSStringFromClass(cls); + NSString *protocolName = [className stringByAppendingString: @"DataSource"]; + Protocol *protocol = objc_getProtocol(protocolName.UTF8String); + + NSCAssert2(protocol, @"Specify protocol explicitly: could not determine data source protocol for class %@ (tried <%@>)", className, protocolName); + return protocol; +} +Protocol *a2_delegateProtocol(Class cls) +{ + NSString *className = NSStringFromClass(cls); + NSString *protocolName = [className stringByAppendingString: @"Delegate"]; + Protocol *protocol = objc_getProtocol(protocolName.UTF8String); + + NSCAssert2(protocol, @"Specify protocol explicitly: could not determine delegate protocol for class %@ (tried <%@>)", className, protocolName); + return protocol; +}
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/BKGlobals.h b/Pods/BlocksKit/BlocksKit/BKGlobals.h new file mode 100755 index 0000000..401da3a --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/BKGlobals.h @@ -0,0 +1,66 @@ +// +// BKGlobals.h +// BlocksKit +// + +#import <dispatch/dispatch.h> +#import <Foundation/Foundation.h> + +#import "A2BlockDelegate.h" +#import "NSObject+A2DynamicDelegate.h" + +#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#define BK_HAS_UIKIT 0 +#define BK_HAS_APPKIT 1 +#elif (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +#define BK_HAS_UIKIT 1 +#define BK_HAS_APPKIT 0 +#else +#define BK_HAS_UIKIT 0 +#define BK_HAS_APPKIT 0 +#endif + +#ifndef DEPRECATED_ATTRIBUTE_M +#if __has_attribute(deprecated) +#define DEPRECATED_ATTRIBUTE_M(...) __attribute__((deprecated(__VA_ARGS__))) +#else +#define DEPRECATED_ATTRIBUTE_M(...) DEPRECATED_ATTRIBUTE +#endif +#endif + +#import <Foundation/Foundation.h> + +#if BK_HAS_APPKIT +#import <Cocoa/Cocoa.h> +#endif + +#if BK_HAS_UIKIT +#import <UIKit/UIKit.h> +#import <MessageUI/MessageUI.h> + +typedef void (^BKGestureRecognizerBlock)(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location); +typedef void (^BKTouchBlock)(NSSet* set, UIEvent* event); +#endif + +typedef void (^BKBlock)(void); // compatible with dispatch_block_t +typedef void (^BKSenderBlock)(id sender); +typedef void (^BKSenderKeyPathBlock)(id obj, NSString *keyPath); +typedef void (^BKKeyValueBlock)(id key, id obj); +typedef void (^BKIndexBlock)(NSUInteger index); +typedef void (^BKTimerBlock)(NSTimeInterval time); +typedef void (^BKResponseBlock)(NSURLResponse *response); + +typedef void (^BKObservationBlock)(id obj, NSDictionary *change); +typedef void (^BKMultipleObservationBlock)(id obj, NSString *keyPath, NSDictionary *change); + +typedef BOOL (^BKValidationBlock)(id obj); +typedef BOOL (^BKKeyValueValidationBlock)(id key, id obj); +typedef BOOL (^BKIndexValidationBlock)(NSUInteger index); + +typedef id (^BKReturnBlock)(void); +typedef id (^BKTransformBlock)(id obj); +typedef id (^BKKeyValueTransformBlock)(id key, id obj); +typedef id (^BKAccumulationBlock)(id sum, id obj); +typedef id (^BKIndexMapBlock)(NSUInteger index); + +typedef NSUInteger (^BKIndexTransformBlock)(NSUInteger index); diff --git a/Pods/BlocksKit/BlocksKit/BKMacros.h b/Pods/BlocksKit/BlocksKit/BKMacros.h new file mode 100755 index 0000000..88591e7 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/BKMacros.h @@ -0,0 +1,60 @@ +// +// BKMacros.h +// BlocksKit +// +// Includes code by Michael Ash. <https://github.com/mikeash>. +// + +#import "NSArray+BlocksKit.h" +#import "NSSet+BlocksKit.h" +#import "NSDictionary+BlocksKit.h" +#import "NSIndexSet+BlocksKit.h" + +#ifndef __BLOCKSKIT_MACROS__ +#define __BLOCKSKIT_MACROS__ + +#define __BK_EACH_WRAPPER(...) (^{ __block CFMutableDictionaryRef MA_eachTable = nil; \ + (void)MA_eachTable; \ + __typeof__(__VA_ARGS__) MA_retval = __VA_ARGS__; \ + if(MA_eachTable) \ + CFRelease(MA_eachTable); \ + return MA_retval; \ + }()) + +#define BK_EACH(collection, ...) __BK_EACH_WRAPPER([collection each:^(id obj) { __VA_ARGS__ }]; +#define BK_APPLY(collection, ...) __BK_EACH_WRAPPER([collection apply:^(id obj) { __VA_ARGS__ }]; +#define BK_MAP(collection, ...) __BK_EACH_WRAPPER([collection map: ^id (id obj) { return (__VA_ARGS__); }]) +#define BK_SELECT(collection, ...) __BK_EACH_WRAPPER([collection select: ^BOOL (id obj) { return (__VA_ARGS__) != 0; }]) +#define BK_REJECT(collection, ...) __BK_EACH_WRAPPER([collection select: ^BOOL (id obj) { return (__VA_ARGS__) == 0; }]) +#define BK_MATCH(collection, ...) __BK_EACH_WRAPPER([collection match: ^BOOL (id obj) { return (__VA_ARGS__) != 0; }]) +#define BK_REDUCE(collection, initial, ...) __BK_EACH_WRAPPER([collection reduce: (initial) block: ^id (id a, id b) { return (__VA_ARGS__); }]) + +#ifndef EACH +#define EACH BK_EACH +#endif + +#ifndef APPLY +#define APPLY BK_APPLY +#endif + +#ifndef MAP +#define MAP BK_MAP +#endif + +#ifndef SELECT +#define SELECT BK_SELECT +#endif + +#ifndef REJECT +#define REJECT BK_REJECT +#endif + +#ifndef MATCH +#define MATCH BK_MATCH +#endif + +#ifndef REDUCE +#define REDUCE BK_REDUCE +#endif + +#endif
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/BlocksKit.h b/Pods/BlocksKit/BlocksKit/BlocksKit.h new file mode 100755 index 0000000..14f80d9 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/BlocksKit.h @@ -0,0 +1,65 @@ +// +// BlocksKit +// +// The Objective-C block utilities you always wish you had. +// +// Copyright (c) 2011-2012 Pandamonia LLC. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#import "BKGlobals.h" + +#import "BKMacros.h" + +#import "NSObject+BlocksKit.h" +#import "NSObject+AssociatedObjects.h" +#import "NSObject+BlockObservation.h" + +#import "NSArray+BlocksKit.h" +#import "NSMutableArray+BlocksKit.h" +#import "NSSet+BlocksKit.h" +#import "NSMutableSet+BlocksKit.h" +#import "NSDictionary+BlocksKit.h" +#import "NSMutableDictionary+BlocksKit.h" +#import "NSIndexSet+BlocksKit.h" +#import "NSMutableIndexSet+BlocksKit.h" +#import "NSOrderedSet+BlocksKit.h" +#import "NSMutableOrderedSet+BlocksKit.h" + +#import "NSInvocation+BlocksKit.h" +#import "NSTimer+BlocksKit.h" + +#import "NSURLConnection+BlocksKit.h" +#import "NSCache+BlocksKit.h" + +#if BK_HAS_UIKIT +#import "UIAlertView+BlocksKit.h" +#import "UIActionSheet+BlocksKit.h" +#import "UIBarButtonItem+BlocksKit.h" +#import "UIControl+BlocksKit.h" +#import "UIGestureRecognizer+BlocksKit.h" +#import "UIPopoverController+BlocksKit.h" +#import "UIView+BlocksKit.h" +#import "UIWebView+BlocksKit.h" +#import "MFMailComposeViewController+BlocksKit.h" +#import "MFMessageComposeViewController+BlocksKit.h" +#else +// AppKit extensions +#endif diff --git a/Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.h b/Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.h new file mode 100644 index 0000000..ca498a2 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.h @@ -0,0 +1,30 @@ +// +// MFMailComposeViewController+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** MFMailComposeViewController with block callbacks. + + If you provide a completion handler to an instance of + MFMailComposeViewController but do not implement a delegate callback for + mailComposeController:didFinishWithResult:error:, the mail compose view + controller will automatically be dismissed if it was launched modally. + + Created by [Igor Evsukov](https://github.com/evsukov89) and contributed to + BlocksKit. + + @warning UIWebView is only available on a platform with UIKit. + */ +@interface MFMailComposeViewController (BlocksKit) + +/** The block fired on the dismissal of the mail composition interface. + + This block callback is an analog for the + mailComposeController:didFinishWithResult:error: method + of MFMailComposeViewControllerDelegate. +*/ +@property (nonatomic, copy) void(^completionBlock)(MFMailComposeViewController *, MFMailComposeResult, NSError *); + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.m b/Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.m new file mode 100644 index 0000000..34ac3a1 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.m @@ -0,0 +1,51 @@ +// +// MFMailComposeViewController+BlocksKit.m +// BlocksKit +// + +#import "MFMailComposeViewController+BlocksKit.h" + +#pragma mark Custom delegate + +@interface A2DynamicMFMailComposeViewControllerDelegate : A2DynamicDelegate +@end + +@implementation A2DynamicMFMailComposeViewControllerDelegate + +- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error { + id realDelegate = self.realDelegate; + BOOL shouldDismiss = (realDelegate && [realDelegate respondsToSelector:@selector(mailComposeController:didFinishWithResult:error:)]); + + if (shouldDismiss) + [realDelegate mailComposeController:controller didFinishWithResult:result error:error]; + + void(^block)(MFMailComposeViewController *, MFMailComposeResult, NSError *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(controller, result, error); + + if (!shouldDismiss) { + #if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000 + [controller dismissModalViewControllerAnimated:YES]; + #else + [controller dismissViewControllerAnimated:YES completion:nil]; + #endif + + } +} + +@end + +#pragma mark Category + +@implementation MFMailComposeViewController (BlocksKit) + +@dynamic completionBlock; + ++ (void)load { + @autoreleasepool { + [self registerDynamicDelegateNamed:@"mailComposeDelegate" forProtocol:@protocol(MFMailComposeViewControllerDelegate)]; + [self linkDelegateMethods: @{ @"completionBlock": @"mailComposeController:didFinishWithResult:error:" }]; + } +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.h b/Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.h new file mode 100644 index 0000000..148e9bb --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.h @@ -0,0 +1,30 @@ +// +// MFMessageComposeViewController+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** MFMessageComposeViewController with block callback in addition to delegation. + + If you provide a completion handler to an instance of + MFMessageComposeViewController but do not implement a delegate callback for + messageComposeViewController:didFinishWithResult:error:, the message compose + view controller will automatically be dismissed if it was launched modally. + + Created by [Igor Evsukov](https://github.com/evsukov89) and contributed to + BlocksKit. + + @warning UIWebView is only available on a platform with UIKit. +*/ +@interface MFMessageComposeViewController (BlocksKit) + +/** The block fired on the dismissal of the SMS composition interface. + + This block callback is an analog for the + messageComposeViewController:didFinishWithResult: method + of MFMessageComposeViewControllerDelegate. + */ +@property (nonatomic, copy) void(^completionBlock)(MFMessageComposeViewController *, MessageComposeResult); + +@end diff --git a/Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.m b/Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.m new file mode 100644 index 0000000..1179cfa --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.m @@ -0,0 +1,49 @@ +// +// MFMessageComposeViewController+BlocksKit.m +// BlocksKit +// + +#import "MFMessageComposeViewController+BlocksKit.h" + +#pragma mark Custom delegate + +@interface A2DynamicMFMessageComposeViewControllerDelegate : A2DynamicDelegate +@end + +@implementation A2DynamicMFMessageComposeViewControllerDelegate + +- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result { + id realDelegate = self.realDelegate; + BOOL shouldDismiss = (realDelegate && [realDelegate respondsToSelector:@selector(messageComposeViewController:didFinishWithResult:)]); + if (shouldDismiss) + [realDelegate messageComposeViewController:controller didFinishWithResult:result]; + + void(^block)(MFMessageComposeViewController *, MessageComposeResult) = [self blockImplementationForMethod:_cmd]; + if (block) + block(controller, result); + + if (!shouldDismiss) { + #if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000 + [controller dismissModalViewControllerAnimated:YES]; + #else + [controller dismissViewControllerAnimated:YES completion:nil]; + #endif + } +} + +@end + +#pragma mark - Category + +@implementation MFMessageComposeViewController (BlocksKit) + +@dynamic completionBlock; + ++ (void)load { + @autoreleasepool { + [self registerDynamicDelegateNamed:@"messageComposeDelegate" forProtocol:@protocol(MFMessageComposeViewControllerDelegate)]; + [self linkDelegateMethods: @{ @"completionBlock": @"messageComposeViewController:didFinishWithResult:" }]; + } +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSArray+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSArray+BlocksKit.h new file mode 100755 index 0000000..b699c82 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSArray+BlocksKit.h @@ -0,0 +1,163 @@ +// +// NSArray+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSArray. + + Both inspired by and resembling Smalltalk syntax, these utilities + allows for iteration of an array in a concise way that + saves quite a bit of boilerplate code for filtering or finding + objects or an object. + + Includes code by the following: + +- [Robin Lu](https://github.com/robin) +- [Michael Ash](https://github.com/mikeash) +- [Aleks Nesterow](https://github.com/nesterow) +- [Zach Waldowski](https://github.com/zwaldowski) + + @see NSDictionary(BlocksKit) + @see NSSet(BlocksKit) + */ +@interface NSArray (BlocksKit) + +/** Loops through an array and executes the given block with each object. + + @param block A single-argument, void-returning code block. + */ +- (void)each:(BKSenderBlock)block; + +/** Enumerates through an array concurrently and executes + the given block once for each object. + + Enumeration will occur on appropriate background queues. This + will have a noticeable speed increase, especially on dual-core + devices, but you *must* be aware of the thread safety of the + objects you message from within the block. Be aware that the + order of objects is not necessarily the order each block will + be called in. + + @param block A single-argument, void-returning code block. + */ +- (void)apply:(BKSenderBlock)block; + +/** Loops through an array to find the object matching the block. + + match: is functionally identical to select:, but will stop and return + on the first match. + + @param block A single-argument, `BOOL`-returning code block. + @return Returns the object, if found, or `nil`. + @see select: + */ +- (id)match:(BKValidationBlock)block; + +/** Loops through an array to find the objects matching the block. + + @param block A single-argument, BOOL-returning code block. + @return Returns an array of the objects found. + @see match: + */ +- (NSArray *)select:(BKValidationBlock)block; + +/** Loops through an array to find the objects not matching the block. + + This selector performs *literally* the exact same function as select: but in reverse. + + This is useful, as one may expect, for removing objects from an array. + NSArray *new = [computers reject:^BOOL(id obj) { + return ([obj isUgly]); + }]; + + @param block A single-argument, BOOL-returning code block. + @return Returns an array of all objects not found. + */ +- (NSArray *)reject:(BKValidationBlock)block; + +/** Call the block once for each object and create an array of the return values. + + This is sometimes referred to as a transform, mutating one of each object: + NSArray *new = [stringArray map:^id(id obj) { + return [obj stringByAppendingString:@".png"]); + }]; + + @param block A single-argument, object-returning code block. + @return Returns an array of the objects returned by the block. + */ +- (NSArray *)map:(BKTransformBlock)block; + +/** Arbitrarily accumulate objects using a block. + + The concept of this selector is difficult to illustrate in words. The sum can + be any NSObject, including (but not limited to) a string, number, or value. + + For example, you can concentate the strings in an array: + NSString *concentrated = [stringArray reduce:@"" withBlock:^id(id sum, id obj) { + return [sum stringByAppendingString:obj]; + }]; + + You can also do something like summing the lengths of strings in an array: + NSUInteger value = [[[stringArray reduce:nil withBlock:^id(id sum, id obj) { + return @([sum integerValue] + obj.length); + }]] unsignedIntegerValue]; + + @param initial The value of the reduction at its start. + @param block A block that takes the current sum and the next object to return the new sum. + @return An accumulated value. + */ +- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block; + +/** Loops through an array to find whether any object matches the block. + + This method is similar to the Scala list `exists`. It is functionally + identical to match: but returns a `BOOL` instead. It is not recommended + to use any: as a check condition before executing match:, since it would + require two loops through the array. + + For example, you can find if a string in an array starts with a certain letter: + + NSString *letter = @"A"; + BOOL containsLetter = [stringArray any: ^(id obj) { + return [obj hasPrefix: @"A"]; + }]; + + @param block A single-argument, BOOL-returning code block. + @return YES for the first time the block returns YES for an object, NO otherwise. + */ +- (BOOL)any:(BKValidationBlock)block; + +/** Loops through an array to find whether no objects match the block. + + This selector performs *literally* the exact same function as all: but in reverse. + + @param block A single-argument, BOOL-returning code block. + @return YES if the block returns NO for all objects in the array, NO otherwise. + */ +- (BOOL)none:(BKValidationBlock)block; + +/** Loops through an array to find whether all objects match the block. + + @param block A single-argument, BOOL-returning code block. + @return YES if the block returns YES for all objects in the array, NO otherwise. + */ +- (BOOL) all: (BKValidationBlock)block; + +/** Tests whether every element of this array relates to the corresponding element of another array according to match by block. + + For example, finding if a list of numbers corresponds to their sequenced string values; + NSArray *numbers = @[ @(1), @(2), @(3) ]; + NSArray *letters = @[ @"1", @"2", @"3" ]; + BOOL doesCorrespond = [numbers corresponds: letters withBlock: ^(id number, id letter) { + return [[number stringValue] isEqualToString: letter]; + }]; + + @param list An array of objects to compare with. + @param block A two-argument, BOOL-returning code block. + @return Returns a BOOL, true if every element of array relates to corresponding element in another array. + */ +- (BOOL) corresponds: (NSArray *) list withBlock: (BKKeyValueValidationBlock) block; + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSArray+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSArray+BlocksKit.m new file mode 100755 index 0000000..5de27f6 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSArray+BlocksKit.m @@ -0,0 +1,122 @@ +// +// NSArray+BlocksKit.m +// BlocksKit +// + +#import "NSArray+BlocksKit.h" + +@implementation NSArray (BlocksKit) + +- (void)each:(BKSenderBlock)block { + NSParameterAssert(block != nil); + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + block(obj); + }]; +} + +- (void)apply:(BKSenderBlock)block { + NSParameterAssert(block != nil); + + [self enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + block(obj); + }]; +} + +- (id)match:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + NSUInteger index = [self indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + return block(obj); + }]; + + if (index == NSNotFound) + return nil; + + return self[index]; +} + +- (NSArray *)select:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + return [self objectsAtIndexes:[self indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + return block(obj); + }]]; +} + +- (NSArray *)reject:(BKValidationBlock)block { + return [self select:^BOOL(id obj) { + return !block(obj); + }]; +} + +- (NSArray *)map:(BKTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableArray *result = [NSMutableArray arrayWithCapacity:self.count]; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + id value = block(obj); + if (!value) + value = [NSNull null]; + + [result addObject:value]; + }]; + + return result; +} + +- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block { + NSParameterAssert(block != nil); + + __block id result = initial; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + result = block(result, obj); + }]; + + return result; +} + +- (BOOL)any:(BKValidationBlock)block { + return [self match: block] != nil; +} + +- (BOOL)none:(BKValidationBlock)block { + return [self match: block] == nil; +} + +- (BOOL)all:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + __block BOOL result = YES; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (!block(obj)) { + result = NO; + *stop = YES; + } + }]; + + return result; +} + +- (BOOL) corresponds: (NSArray *) list withBlock: (BKKeyValueValidationBlock) block { + NSParameterAssert(block != nil); + + __block BOOL result = NO; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (idx < list.count) { + id obj2 = list[idx]; + result = block(obj, obj2); + } else { + result = NO; + } + *stop = !result; + }]; + + return result; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSCache+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSCache+BlocksKit.h new file mode 100644 index 0000000..12a7e4e --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSCache+BlocksKit.h @@ -0,0 +1,53 @@ +// +// NSCache+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** NSCache with block adding of objects + + This category allows you to conditionally add objects to + an instance of NSCache using blocks. Both the normal + delegation pattern and a block callback for NSCache's one + delegate method are allowed. + + These methods emulate Rails caching behavior. + + Created by [Igor Evsukov](https://github.com/evsukov89) and contributed to BlocksKit. + */ + +@interface NSCache (BlocksKit) + +/** Returns the value associated with a given key. If there is no + object for that key, it uses the result of the block, saves + that to the cache, and returns it. + + This mimics the cache behavior of Ruby on Rails. The following code: + + @products = Rails.cache.fetch('products') do + Product.all + end + + becomes: + + NSMutableArray *products = [cache objectForKey:@"products" withGetter:^id{ + return [Product all]; + }]; + + @return The value associated with *key*, or the object returned + by the block if no value is associated with *key*. + @param key An object identifying the value. + @param getterBlock A block used to get an object if there is no + value in the cache. + */ +- (id)objectForKey:(id)key withGetter:(BKReturnBlock)getterBlock; + +/** Called when an object is about to be evicted from the cache. + + This block callback is an analog for the cache:willEviceObject: + method of NSCacheDelegate. + */ +@property (nonatomic, copy) void(^willEvictBlock)(NSCache *, id); + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSCache+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSCache+BlocksKit.m new file mode 100644 index 0000000..77dd909 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSCache+BlocksKit.m @@ -0,0 +1,56 @@ +// +// NSCache+BlocksKit.m +// BlocksKit +// + +#import "NSCache+BlocksKit.h" + +#pragma mark Custom delegate + +@interface A2DynamicNSCacheDelegate : A2DynamicDelegate + +@end + +@implementation A2DynamicNSCacheDelegate + +- (void)cache:(NSCache *)cache willEvictObject:(id)obj { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(cache:willEvictObject:)]) + [realDelegate cache:cache willEvictObject:obj]; + + void (^orig)(NSCache *, id) = [self blockImplementationForMethod:_cmd]; + if (orig) + orig(cache, obj); +} + +@end + +#pragma mark Category + +@implementation NSCache (BlocksKit) + +@dynamic willEvictBlock; + ++ (void)load { + @autoreleasepool { + [self registerDynamicDelegate]; + [self linkDelegateMethods: @{ @"willEvictBlock": @"cache:willEvictObject:" }]; + } +} + +#pragma mark Methods + +- (id)objectForKey:(id)key withGetter:(BKReturnBlock)block { + id object = [self objectForKey:key]; + if (object) + return object; + + if (block) { + object = block(); + [self setObject:object forKey:key]; + } + + return object; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSDictionary+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSDictionary+BlocksKit.h new file mode 100755 index 0000000..80c8d9d --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSDictionary+BlocksKit.h @@ -0,0 +1,110 @@ +// +// NSDictionary+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extension for NSDictionary. + + Both inspired by and resembling Smalltalk syntax, this utility + allows iteration of a dictionary in a concise way that + saves quite a bit of boilerplate code. + + Includes code by the following: + +- [Mirko Kiefer](https://github.com/mirkok) +- [Zach Waldowski](https://github.com/zwaldowski) + + @see NSArray(BlocksKit) + @see NSSet(BlocksKit) + */ +@interface NSDictionary (BlocksKit) + +/** Loops through the dictionary and executes the given block using each item. + + @param block A block that performs an action using a key/value pair. + */ +- (void)each:(BKKeyValueBlock)block; + +/** Enumerates through the dictionary concurrently and executes + the given block once for each pair. + + Enumeration will occur on appropriate background queues; + the system will spawn threads as need for execution. This + will have a noticeable speed increase, especially on dual-core + devices, but you *must* be aware of the thread safety of the + objects you message from within the block. + + @param block A block that performs an action using a key/value pair. + */ +- (void)apply:(BKKeyValueBlock)block; + +/** Loops through a dictionary to find the first key/value pair matching the block. + + match: is functionally identical to select:, but will stop and return + the value on the first match. + + @param block A BOOL-returning code block for a key/value pair. + @return The value of the first pair found; + */ +- (id)match:(BKKeyValueValidationBlock)block; + +/** Loops through a dictionary to find the key/value pairs matching the block. + + @param block A BOOL-returning code block for a key/value pair. + @return Returns a dictionary of the objects found. + */ +- (NSDictionary *)select:(BKKeyValueValidationBlock)block; + +/** Loops through a dictionary to find the key/value pairs not matching the block. + + This selector performs *literally* the exact same function as select: but in reverse. + + This is useful, as one may expect, for filtering objects. + NSDictionary *strings = [userData reject:^BOOL(id key, id value) { + return ([obj isKindOfClass:[NSString class]]); + }]; + + @param block A BOOL-returning code block for a key/value pair. + @return Returns a dictionary of all objects not found. + */ +- (NSDictionary *)reject:(BKKeyValueValidationBlock)block; + +/** Call the block once for each object and create a dictionary with the same keys + and a new set of values. + + @param block A block that returns a new value for a key/value pair. + @return Returns a dictionary of the objects returned by the block. + */ +- (NSDictionary *)map:(BKKeyValueTransformBlock)block; + +/** Loops through a dictionary to find whether any key/value pair matches the block. + + This method is similar to the Scala list `exists`. It is functionally + identical to match: but returns a `BOOL` instead. It is not recommended + to use any: as a check condition before executing match:, since it would + require two loops through the dictionary. + + @param block A two-argument, BOOL-returning code block. + @return YES for the first time the block returns YES for a key/value pair, NO otherwise. + */ +- (BOOL)any:(BKKeyValueValidationBlock)block; + +/** Loops through a dictionary to find whether no key/value pairs match the block. + + This selector performs *literally* the exact same function as all: but in reverse. + + @param block A two-argument, BOOL-returning code block. + @return YES if the block returns NO for all key/value pairs in the dictionary, NO otherwise. + */ +- (BOOL)none:(BKKeyValueValidationBlock)block; + +/** Loops through a dictionary to find whether all key/value pairs match the block. + + @param block A two-argument, BOOL-returning code block. + @return YES if the block returns YES for all key/value pairs in the dictionary, NO otherwise. + */ +- (BOOL)all:(BKKeyValueValidationBlock)block; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSDictionary+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSDictionary+BlocksKit.m new file mode 100755 index 0000000..6ffc174 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSDictionary+BlocksKit.m @@ -0,0 +1,95 @@ +// +// NSDictionary+BlocksKit.m +// BlocksKit +// + +#import "NSDictionary+BlocksKit.h" + +@implementation NSDictionary (BlocksKit) + +- (void)each:(BKKeyValueBlock)block { + NSParameterAssert(block != nil); + + [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + block(key, obj); + }]; +} + +- (void)apply:(BKKeyValueBlock)block { + NSParameterAssert(block != nil); + + [self enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id key, id obj, BOOL *stop) { + block(key, obj); + }]; +} + +- (id)match:(BKKeyValueValidationBlock)block { + NSParameterAssert(block != nil); + + return self[[[self keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) { + if (block(key, obj)) { + *stop = YES; + return YES; + } + return NO; + }] anyObject]]; +} + +- (NSDictionary *)select:(BKKeyValueValidationBlock)block { + NSParameterAssert(block != nil); + + NSArray *keys = [[self keysOfEntriesPassingTest:^(id key, id obj, BOOL *stop) { + return block(key, obj); + }] allObjects]; + + NSArray *objects = [self objectsForKeys:keys notFoundMarker:[NSNull null]]; + + return [NSDictionary dictionaryWithObjects:objects forKeys:keys]; +} + +- (NSDictionary *)reject:(BKKeyValueValidationBlock)block { + return [self select:^BOOL(id key, id obj) { + return !block(key, obj); + }]; +} + +- (NSDictionary *)map:(BKKeyValueTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:self.count]; + + [self each:^(id key, id obj) { + id value = block(key, obj); + if (!value) + value = [NSNull null]; + + result[key] = value; + }]; + + return result; +} + +- (BOOL)any:(BKKeyValueValidationBlock)block { + return [self match: block] != nil; +} + +- (BOOL)none:(BKKeyValueValidationBlock)block { + return [self match: block] == nil; +} + +- (BOOL)all:(BKKeyValueValidationBlock)block { + NSParameterAssert(block != nil); + + __block BOOL result = YES; + + [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + if (!block(key, obj)) { + result = NO; + *stop = YES; + } + }]; + + return result; +} + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSIndexSet+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSIndexSet+BlocksKit.h new file mode 100755 index 0000000..4743264 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSIndexSet+BlocksKit.h @@ -0,0 +1,119 @@ +// +// NSIndexSet+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSIndexSet. + + Both inspired by and resembling Smalltalk syntax, these utilities + allows for iteration of an array in a concise way that + saves quite a bit of boilerplate code for filtering or finding + objects or an object. + + Includes code by the following: + +- [Robin Lu](https://github.com/robin) +- [Michael Ash](https://github.com/mikeash) +- [Zach Waldowski](https://github.com/zwaldowski) +- [Kaelin Colclasure]<https://github.com/kaelin> + + @see NSArray(BlocksKit) + @see NSDictionary(BlocksKit) + @see NSSet(BlocksKit) + */ +@interface NSIndexSet (BlocksKit) + +/** Loops through an index set and executes the given block at each index. + + @param block A single-argument, void-returning code block. + */ +- (void)each:(BKIndexBlock)block; + +/** Enumerates each index in an index set concurrently and executes the + given block once per index. + + Enumeration will occur on appropriate background queues. + Be aware that the block will not necessarily be executed + in order for each index. + + @param block A single-argument, void-returning code block. + */ +- (void)apply:(BKIndexBlock)block; + +/** Loops through an array and returns the index matching the block. + + @param block A single-argument, `BOOL`-returning code block. + @return Returns the index if found, `NSNotFound` otherwise. + @see select: + */ +- (NSUInteger)match:(BKIndexValidationBlock)block; + +/** Loops through an index set and returns an all indexes matching the block. + + @param block A single-argument, BOOL-returning code block. + @return Returns an index set of matching indexes found. + @see match: + */ +- (NSIndexSet *)select:(BKIndexValidationBlock)block; + +/** Loops through an index set and returns an all indexes but the ones matching the block. + + This selector performs *literally* the exact same function as select: but in reverse. + + @param block A single-argument, BOOL-returning code block. + @return Returns an index set of all indexes but those matched. + */ +- (NSIndexSet *)reject:(BKIndexValidationBlock)block; + +/** Call the block once for each index and create an index set with the new values. + + @param block A block that returns a new index for an index. + @return An index set of the indexes returned by the block. + */ +- (NSIndexSet *)map:(BKIndexTransformBlock)block; + +/** Call the block once for each index and create an array of the return values. + + This method allows transforming indexes into objects: + int values[10] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 }; + NSIndexSet *idxs = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 10)]; + NSArray *new = [idxs mapIndex:^id(NSUInteger index) { + return [NSNumber numberWithInt:values[index]]); + }]; + + @param block A block that returns an object for an index. + @return Returns an array of the objects returned by the block. + */ +- (NSArray *)mapIndex:(BKIndexMapBlock)block; + +/** Loops through an index set to find whether any of the indexes matche the block. + + This method is similar to the Scala list `exists`. It is functionally + identical to match: but returns a `BOOL` instead. It is not recommended + to use any: as a check condition before executing match:, since it would + require two loops through the index set. + + @param block A single-argument, BOOL-returning code block. + @return YES for the first time the block returns YES for an index, NO otherwise. + */ +- (BOOL)any:(BKIndexValidationBlock)block; + +/** Loops through an index set to find whether all objects match the block. + + @param block A single-argument, BOOL-returning code block. + @return YES if the block returns YES for all indexes in the array, NO otherwise. + */ +- (BOOL)all:(BKIndexValidationBlock)block; + +/** Loops through an index set to find whether no objects match the block. + + This selector performs *literally* the exact same function as all: but in reverse. + + @param block A single-argument, BOOL-returning code block. + @return YES if the block returns NO for all indexes in the array, NO otherwise. + */ +- (BOOL)none:(BKIndexValidationBlock)block; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSIndexSet+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSIndexSet+BlocksKit.m new file mode 100755 index 0000000..117e844 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSIndexSet+BlocksKit.m @@ -0,0 +1,107 @@ +// +// NSIndexSet+BlocksKit.m +// BlocksKit +// + +#import "NSIndexSet+BlocksKit.h" + +@implementation NSIndexSet (BlocksKit) + +- (void)each:(BKIndexBlock)block { + NSParameterAssert(block != nil); + + [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + block(idx); + }]; +} + +- (void)apply:(BKIndexBlock)block { + NSParameterAssert(block != nil); + + [self enumerateIndexesWithOptions:NSEnumerationConcurrent usingBlock:^(NSUInteger idx, BOOL *stop) { + block(idx); + }]; +} + +- (NSUInteger)match:(BKIndexValidationBlock)block { + NSParameterAssert(block != nil); + + return [self indexPassingTest:^BOOL(NSUInteger idx, BOOL *stop) { + return block(idx); + }]; +} + +- (NSIndexSet *)select:(BKIndexValidationBlock)block { + NSParameterAssert(block != nil); + + NSIndexSet *list = [self indexesPassingTest:^BOOL(NSUInteger idx, BOOL *stop) { + return block(idx); + }]; + + if (!list.count) + return nil; + + return list; +} + +- (NSIndexSet *)reject:(BKIndexValidationBlock)block { + return [self select:^BOOL(NSUInteger idx) { + return !block(idx); + }]; +} + +- (NSIndexSet *)map:(BKIndexTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableIndexSet *list = [NSMutableIndexSet indexSet]; + + [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + [list addIndex:block(idx)]; + }]; + + if (!list.count) + return nil; + + return list; +} + +- (NSArray *)mapIndex:(BKIndexMapBlock)block { + NSParameterAssert(block != nil); + + NSMutableArray *result = [NSMutableArray arrayWithCapacity:self.count]; + + [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + id value = block(idx); + if (!value) + value = [NSNull null]; + + [result addObject:value]; + }]; + + return result; +} + +- (BOOL)any:(BKIndexValidationBlock)block { + return [self match: block] != NSNotFound; +} + +- (BOOL)none:(BKIndexValidationBlock)block { + return [self match: block] == NSNotFound; +} + +- (BOOL)all:(BKIndexValidationBlock)block { + NSParameterAssert(block != nil); + + __block BOOL result = YES; + + [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + if (!block(idx)) { + result = NO; + *stop = YES; + } + }]; + + return result; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSInvocation+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSInvocation+BlocksKit.h new file mode 100755 index 0000000..15a8be7 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSInvocation+BlocksKit.h @@ -0,0 +1,30 @@ +// +// NSInvocation+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** BlocksKit extensions for NSInvocation. */ +@interface NSInvocation (BlocksKit) + +/** Generates an `NSInvocation` instance for a given block. + + NSInvocation *invocation = [NSInvocation invocationWithTarget: target block: ^(id myObject){ + [myObject someMethodWithArg:42.0]; + }]; + + This returns an invocation with the appropriate target, selector, and arguments + without creating the buffers yourself. It is only recommended to call a method + on the argument to the block only once. + + Created by [Jonathan Rentzch](https://github.com/rentzsch) as + `NSInvocation-blocks`. + + @param target The object to "grab" the block invocation from. + @param block A code block. + @return A fully-prepared instance of NSInvocation ready to be invoked. + */ ++ (NSInvocation *)invocationWithTarget:(id)target block:(BKSenderBlock)block; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSInvocation+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSInvocation+BlocksKit.m new file mode 100755 index 0000000..89d0759 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSInvocation+BlocksKit.m @@ -0,0 +1,46 @@ +// +// NSInvocation+BlocksKit.m +// BlocksKit +// + +#import "NSInvocation+BlocksKit.h" + +@interface BKInvocationGrabber : NSProxy + ++ (BKInvocationGrabber *)grabberWithTarget:(id)target; + +@property (nonatomic, strong) id target; +@property (nonatomic, strong) NSInvocation *invocation; + +@end + +@implementation BKInvocationGrabber + ++ (BKInvocationGrabber *)grabberWithTarget:(id)target { + BKInvocationGrabber *instance = [BKInvocationGrabber alloc]; + instance.target = target; + return instance; +} + +- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector { + return [self.target methodSignatureForSelector: selector]; +} + +- (void)forwardInvocation:(NSInvocation*)invocation { + [invocation setTarget: self.target]; + self.invocation = invocation; +} + +@end + + +@implementation NSInvocation (BlocksKit) + ++ (NSInvocation *)invocationWithTarget:(id)target block:(BKSenderBlock)block { + NSParameterAssert(block != nil); + BKInvocationGrabber *grabber = [BKInvocationGrabber grabberWithTarget:target]; + block(grabber); + return grabber.invocation; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSMutableArray+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSMutableArray+BlocksKit.h new file mode 100644 index 0000000..cc33c8e --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableArray+BlocksKit.h @@ -0,0 +1,50 @@ +// +// NSMutableArray+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSMutableArray. + + These utilities expound upon the BlocksKit additions to the immutable + superclass by allowing certain utilities to work on an instance of the mutable + class, saving memory by not creating an immutable copy of the results. + + Includes code by the following: + + - [Martin Schürrer](https://github.com/MSch) + - [Zach Waldowski](https://github.com/zwaldowski) + + @see NSArray(BlocksKit) + */ +@interface NSMutableArray (BlocksKit) + +/** Filters a mutable array to the objects matching the block. + + @param block A single-argument, BOOL-returning code block. + @see <NSArray(BlocksKit)>reject: + */ +- (void)performSelect:(BKValidationBlock)block; + +/** Filters a mutable array to all objects but the ones matching the block, + the logical inverse to select:. + + @param block A single-argument, BOOL-returning code block. + @see <NSArray(BlocksKit)>select: + */ +- (void)performReject:(BKValidationBlock)block; + +/** Transform the objects in the array to the results of the block. + + This is sometimes referred to as a transform, mutating one of each object: + [foo performMap:^id(id obj) { + return [dateTransformer dateFromString:obj]; + }]; + + @param block A single-argument, object-returning code block. + @see <NSArray(BlocksKit)>map: + */ +- (void)performMap:(BKTransformBlock)block; + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSMutableArray+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSMutableArray+BlocksKit.m new file mode 100644 index 0000000..12bb7b5 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableArray+BlocksKit.m @@ -0,0 +1,49 @@ +// +// NSMutableArray+BlocksKit.m +// BlocksKit +// + +#import "NSMutableArray+BlocksKit.h" + +@implementation NSMutableArray (BlocksKit) + +- (void)performSelect:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + NSIndexSet *list = [self indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + return !block(obj); + }]; + + if (!list.count) + return; + + [self removeObjectsAtIndexes:list]; +} + +- (void)performReject:(BKValidationBlock)block { + return [self performSelect:^BOOL(id obj) { + return !block(obj); + }]; +} + +- (void)performMap:(BKTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableArray *new = [self mutableCopy]; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + id value = block(obj); + + if (!value) + value = [NSNull null]; + + if ([value isEqual:obj]) + return; + + new[idx] = value; + }]; + + [self setArray: new]; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSMutableDictionary+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSMutableDictionary+BlocksKit.h new file mode 100644 index 0000000..6da8854 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableDictionary+BlocksKit.h @@ -0,0 +1,46 @@ +// +// NSMutableDictionary+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSMutableDictionary. + + These utilities expound upon the BlocksKit additions to the immutable + superclass by allowing certain utilities to work on an instance of the mutable + class, saving memory by not creating an immutable copy of the results. + + Includes code by the following: + + - [Martin Schürrer](https://github.com/MSch) + - [Zach Waldowski](https://github.com/zwaldowski) + + @see NSDictionary(BlocksKit) + */ +@interface NSMutableDictionary (BlocksKit) + +/** Filters a mutable dictionary to the key/value pairs matching the block. + + @param block A BOOL-returning code block for a key/value pair. + @see <NSDictionary(BlocksKit)>reject: + */ +- (void)performSelect:(BKKeyValueValidationBlock)block; + +/** Filters a mutable dictionary to the key/value pairs not matching the block, + the logical inverse to select:. + + @param block A BOOL-returning code block for a key/value pair. + @see <NSDictionary(BlocksKit)>select: + */ +- (void)performReject:(BKKeyValueValidationBlock)block; + +/** Transform each value of the dictionary to a new value, as returned by the + block. + + @param block A block that returns a new value for a given key/value pair. + @see <NSDictionary(BlocksKit)>map: + */ +- (void)performMap:(BKKeyValueTransformBlock)block; + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSMutableDictionary+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSMutableDictionary+BlocksKit.m new file mode 100644 index 0000000..ba61705 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableDictionary+BlocksKit.m @@ -0,0 +1,46 @@ +// +// NSMutableDictionary+BlocksKit.m +// BlocksKit +// + +#import "NSMutableDictionary+BlocksKit.h" + +@implementation NSMutableDictionary (BlocksKit) + +- (void)performSelect:(BKKeyValueValidationBlock)block { + NSParameterAssert(block != nil); + + NSArray *keys = [[self keysOfEntriesWithOptions:NSEnumerationConcurrent passingTest:^BOOL(id key, id obj, BOOL *stop) { + return !block(key, obj); + }] allObjects]; + + [self removeObjectsForKeys:keys]; +} + +- (void)performReject:(BKKeyValueValidationBlock)block { + [self performSelect:^BOOL(id key, id obj) { + return !block(key, obj); + }]; +} + +- (void)performMap:(BKKeyValueTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableDictionary *new = [self mutableCopy]; + + [self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + id value = block(key, obj); + + if (!value) + value = [NSNull null]; + + if ([value isEqual:obj]) + return; + + new[key] = value; + }]; + + [self setDictionary: new]; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSMutableIndexSet+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSMutableIndexSet+BlocksKit.h new file mode 100644 index 0000000..d9c411b --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableIndexSet+BlocksKit.h @@ -0,0 +1,42 @@ +// +// NSMutableIndexSet+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSMutableIndexSet. + + These utilities expound upon the BlocksKit additions to the immutable + superclass by allowing certain utilities to work on an instance of the mutable + class, saving memory by not creating an immutable copy of the results. + + @see NSIndexSet(BlocksKit) + */ +@interface NSMutableIndexSet (BlocksKit) + +/** Filters a mutable index set to the indexes matching the block. + + @param block A single-argument, BOOL-returning code block. + @see <NSIndexSet(BlocksKit)>reject: + */ +- (void)performSelect:(BKIndexValidationBlock)block; + +/** Filters a mutable index set to all indexes but the ones matching the block, + the logical inverse to select:. + + @param block A single-argument, BOOL-returning code block. + @see <NSIndexSet(BlocksKit)>select: + */ +- (void)performReject:(BKIndexValidationBlock)block; + +/** Transform each index of the index set to a new index, as returned by the + block. + + @param block A block that returns a new index for a index. + @see <NSIndexSet(BlocksKit)>map: + */ +- (void)performMap:(BKIndexTransformBlock)block; + + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSMutableIndexSet+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSMutableIndexSet+BlocksKit.m new file mode 100644 index 0000000..d092c65 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableIndexSet+BlocksKit.m @@ -0,0 +1,43 @@ +// +// NSMutableIndexSet+BlocksKit.m +// BlocksKit +// + +#import "NSMutableIndexSet+BlocksKit.h" + +@implementation NSMutableIndexSet (BlocksKit) + +- (void)performSelect:(BKIndexValidationBlock)block { + NSParameterAssert(block != nil); + + + NSIndexSet *list = [self indexesPassingTest:^BOOL(NSUInteger idx, BOOL *stop) { + return !block(idx); + }]; + + if (!list.count) + return; + + [self removeIndexes:list]; +} + +- (void)performReject:(BKIndexValidationBlock)block { + return [self performSelect:^BOOL(NSUInteger idx) { + return !block(idx); + }]; +} + +- (void)performMap:(BKIndexTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableIndexSet *new = [self mutableCopy]; + + [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + [new addIndex:block(idx)]; + }]; + + [self removeAllIndexes]; + [self addIndexes: new]; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSMutableOrderedSet+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSMutableOrderedSet+BlocksKit.h new file mode 100755 index 0000000..5ad06fb --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableOrderedSet+BlocksKit.h @@ -0,0 +1,50 @@ +// +// NSMutableOrderedSet+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSMutableOrderedSet. + + These utilities expound upon the BlocksKit additions to the immutable + superclass by allowing certain utilities to work on an instance of the mutable + class, saving memory by not creating an immutable copy of the results. + + Includes code by the following: + + - [Martin Schürrer](https://github.com/MSch) + - [Zach Waldowski](https://github.com/zwaldowski) + + @see NSOrderedSet(BlocksKit) + */ +@interface NSMutableOrderedSet (BlocksKit) + +/** Filters a mutable ordered set to the objects matching the block. + + @param block A single-argument, BOOL-returning code block. + @see <NSOrderedSet(BlocksKit)>reject: + */ +- (void)performSelect:(BKValidationBlock)block; + +/** Filters a mutable ordered set to all objects but the ones matching the + block, the logical inverse to select:. + + @param block A single-argument, BOOL-returning code block. + @see <NSOrderedSet(BlocksKit)>select: + */ +- (void)performReject:(BKValidationBlock)block; + +/** Transform the objects in the ordered set to the results of the block. + + This is sometimes referred to as a transform, mutating one of each object: + [foo performMap:^id(id obj) { + return [dateTransformer dateFromString:obj]; + }]; + + @param block A single-argument, object-returning code block. + @see <NSOrderedSet(BlocksKit)>map: + */ +- (void)performMap:(BKTransformBlock)block; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSMutableOrderedSet+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSMutableOrderedSet+BlocksKit.m new file mode 100755 index 0000000..824176e --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableOrderedSet+BlocksKit.m @@ -0,0 +1,54 @@ +// +// NSMutableOrderedSet+BlocksKit.m +// BlocksKit +// +// Created by Zachary Waldowski on 10/6/12. +// Copyright (c) 2012 Pandamonia LLC. All rights reserved. +// + +#import "NSMutableOrderedSet+BlocksKit.h" + +@implementation NSMutableOrderedSet (BlocksKit) + +- (void)performSelect:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + NSIndexSet *list = [self indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + return !block(obj); + }]; + + if (!list.count) + return; + + [self removeObjectsAtIndexes:list]; +} + +- (void)performReject:(BKValidationBlock)block { + return [self performSelect:^BOOL(id obj) { + return !block(obj); + }]; +} + +- (void)performMap:(BKTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableIndexSet *newIndexes = [NSMutableIndexSet indexSet]; + NSMutableArray *newObjects = [NSMutableArray arrayWithCapacity: self.count]; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + id value = block(obj); + + if (!value) + value = [NSNull null]; + + if ([value isEqual:obj]) + return; + + [newIndexes addIndex: idx]; + [newObjects addObject: obj]; + }]; + + [self replaceObjectsAtIndexes: newIndexes withObjects: newObjects]; +} + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSMutableSet+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSMutableSet+BlocksKit.h new file mode 100644 index 0000000..604f845 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableSet+BlocksKit.h @@ -0,0 +1,50 @@ +// +// NSMutableSet+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSMutableSet. + + These utilities expound upon the BlocksKit additions to the immutable + superclass by allowing certain utilities to work on an instance of the mutable + class, saving memory by not creating an immutable copy of the results. + + Includes code by the following: + + - [Martin Schürrer](https://github.com/MSch) + - [Zach Waldowski](https://github.com/zwaldowski) + + @see NSSet(BlocksKit) + */ +@interface NSMutableSet (BlocksKit) + +/** Filters a mutable set to the objects matching the block. + + @param block A single-argument, BOOL-returning code block. + @see <NSSet(BlocksKit)>reject: + */ +- (void)performSelect:(BKValidationBlock)block; + +/** Filters a mutable set to all objects but the ones matching the block, + the logical inverse to select:. + + @param block A single-argument, BOOL-returning code block. + @see <NSSet(BlocksKit)>select: + */ +- (void)performReject:(BKValidationBlock)block; + +/** Transform the objects in the set to the results of the block. + + This is sometimes referred to as a transform, mutating one of each object: + [controllers map:^id(id obj) { + return [obj view]; + }]; + + @param block A single-argument, object-returning code block. + @see <NSSet(BlocksKit)>map: + */ +- (void)performMap:(BKTransformBlock)block; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSMutableSet+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSMutableSet+BlocksKit.m new file mode 100644 index 0000000..b3f348c --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSMutableSet+BlocksKit.m @@ -0,0 +1,39 @@ +// +// NSMutableSet+BlocksKit.m +// BlocksKit +// + +#import "NSMutableSet+BlocksKit.h" + +@implementation NSMutableSet (BlocksKit) + +- (void)performSelect:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + NSSet *list = [self objectsPassingTest:^BOOL(id obj, BOOL *stop) { + return block(obj); + }]; + + [self setSet:list]; +} + +- (void)performReject:(BKValidationBlock)block { + [self performSelect:^BOOL(id obj) { + return !block(obj); + }]; +} + +- (void)performMap:(BKTransformBlock)block { + NSParameterAssert(block != nil); + + + NSMutableSet *new = [NSMutableSet setWithCapacity:self.count]; + + [self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { + [new addObject:block(obj)]; + }]; + + [self setSet:new]; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSObject+A2DynamicDelegate.h b/Pods/BlocksKit/BlocksKit/NSObject+A2DynamicDelegate.h new file mode 100644 index 0000000..a581126 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSObject+A2DynamicDelegate.h @@ -0,0 +1,68 @@ +// +// NSObject+A2DynamicDelegate.h +// BlocksKit +// + +#import "BKGlobals.h" +#import "A2DynamicDelegate.h" + +/** The A2DynamicDelegate category to NSObject provides the primary interface + by which dynamic delegates are generated for a given object. */ +@interface NSObject (A2DynamicDelegate) + +/** Creates or gets a dynamic data source for the reciever. + + A2DynamicDelegate assumes a protocol name `FooBarDataSource` + for instances of class `FooBar`. The object is given a strong + attachment to the reciever, and is automatically deallocated + when the reciever is released. + + If the user implements a `A2DynamicFooBarDataSource` subclass + of A2DynamicDelegate, its implementation of any method + will be used over the block. If the block needs to be used, + it can be called from within the custom + implementation using blockImplementationForMethod:. + + @see <A2DynamicDelegate>blockImplementationForMethod: + @return A dynamic data source. + */ +- (id) dynamicDataSource; + +/** Creates or gets a dynamic delegate for the reciever. + + A2DynamicDelegate assumes a protocol name `FooBarDelegate` + for instances of class `FooBar`. The object is given a strong + attachment to the reciever, and is automatically deallocated + when the reciever is released. + + If the user implements a `A2DynamicFooBarDelegate` subclass + of A2DynamicDelegate, its implementation of any method + will be used over the block. If the block needs to be used, + it can be called from within the custom + implementation using blockImplementationForMethod:. + + @see <A2DynamicDelegate>blockImplementationForMethod: + @return A dynamic delegate. + */ +- (id) dynamicDelegate; + +/** Creates or gets a dynamic protocol implementation for + the reciever. The designated initializer. + + The object is given a strong attachment to the reciever, + and is automatically deallocated when the reciever is released. + + If the user implements a subclass of A2DynamicDelegate prepended + with `A2Dynamic`, such as `A2DynamicFooProvider`, its + implementation of any method will be used over the block. + If the block needs to be used, it can be called from within the + custom implementation using blockImplementationForMethod:. + + @param protocol A custom protocol. + @return A dynamic protocol implementation. + @see <A2DynamicDelegate>blockImplementationForMethod: + */ +- (id) dynamicDelegateForProtocol: (Protocol *) protocol; + + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSObject+A2DynamicDelegate.m b/Pods/BlocksKit/BlocksKit/NSObject+A2DynamicDelegate.m new file mode 100644 index 0000000..753f421 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSObject+A2DynamicDelegate.m @@ -0,0 +1,65 @@ +// +// NSObject+A2DynamicDelegate.m +// BlocksKit +// +// Created by Zachary Waldowski on 10/24/12. +// Copyright (c) 2012 Pandamonia LLC. All rights reserved. +// + +#import "NSObject+A2DynamicDelegate.h" +#import "NSObject+AssociatedObjects.h" + +extern Protocol *a2_dataSourceProtocol(Class cls); +extern Protocol *a2_delegateProtocol(Class cls); + +static dispatch_queue_t a2_backgroundQueue(void) +{ + static dispatch_once_t onceToken; + static dispatch_queue_t backgroundQueue = nil; + dispatch_once(&onceToken, ^{ + backgroundQueue = dispatch_queue_create("us.pandamonia.A2DynamicDelegate.backgroundQueue", DISPATCH_QUEUE_SERIAL); + }); + return backgroundQueue; +} + +@implementation NSObject (A2DynamicDelegate) + +- (id) dynamicDataSource +{ + Protocol *protocol = a2_dataSourceProtocol([self class]); + return [self dynamicDelegateForProtocol: protocol]; +} +- (id) dynamicDelegate +{ + Protocol *protocol = a2_delegateProtocol([self class]); + return [self dynamicDelegateForProtocol: protocol]; +} +- (id) dynamicDelegateForProtocol: (Protocol *) protocol +{ + /** + * Storing the dynamic delegate as an associated object of the delegating + * object not only allows us to later retrieve the delegate, but it also + * creates a strong relationship to the delegate. Since delegates are weak + * references on the part of the delegating object, a dynamic delegate + * would be deallocated immediately after its declaring scope ends. + * Therefore, this strong relationship is required to ensure that the + * delegate's lifetime is at least as long as that of the delegating object. + **/ + + __block A2DynamicDelegate *dynamicDelegate; + + dispatch_sync(a2_backgroundQueue(), ^{ + dynamicDelegate = [self associatedValueForKey: (__bridge const void *)protocol]; + + if (!dynamicDelegate) + { + Class cls = NSClassFromString([@"A2Dynamic" stringByAppendingString: NSStringFromProtocol(protocol)]) ?: [A2DynamicDelegate class]; + dynamicDelegate = [[cls alloc] initWithProtocol: protocol]; + [self associateValue: dynamicDelegate withKey: (__bridge const void *)protocol]; + } + }); + + return dynamicDelegate; +} + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSObject+AssociatedObjects.h b/Pods/BlocksKit/BlocksKit/NSObject+AssociatedObjects.h new file mode 100755 index 0000000..f39fa35 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSObject+AssociatedObjects.h @@ -0,0 +1,158 @@ +// +// NSObject+AssociatedObjects.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Objective-C wrapper for 10.6+ associated object API. + + In Mac OS X Snow Leopard and iOS 3.0, Apple introduced an addition to the + Objective-C Runtime called associated objects. Associated objects allow for the + pairing of a random key and object pair to be saved on an instance. + + In BlocksKit, associated objects allow us to emulate instance variables in the + ategories we use. + + Class methods also exist for each association. These associations are unique to + each class, and exist for the lifetime of the application unless set to `nil`. + Each class is a unique meta-object; the ultimate singleton. + + Created by [Andy Matuschak](https://github.com/andymatuschak) as + `AMAssociatedObjects`. + */ +@interface NSObject (BKAssociatedObjects) + +/** Strongly associates an object with the reciever. + + The associated value is retained as if it were a property + synthesized with `nonatomic` and `retain`. + + Using retained association is strongly recommended for most + Objective-C object derivative of NSObject, particularly + when it is subject to being externally released or is in an + `NSAutoreleasePool`. + + @param value Any object. + @param key A unique key pointer. + */ +- (void)associateValue:(id)value withKey:(const void *)key; + +/** Strongly associates an object with the receiving class. + + @see associateValue:withKey: + @param value Any object. + @param key A unique key pointer. + */ ++ (void)associateValue:(id)value withKey:(const void *)key; + +/** Strongly, thread-safely associates an object with the reciever. + + The associated value is retained as if it were a property + synthesized with `atomic` and `retain`. + + Using retained association is strongly recommended for most + Objective-C object derivative of NSObject, particularly + when it is subject to being externally released or is in an + `NSAutoreleasePool`. + + @see associateValue:withKey: + @param value Any object. + @param key A unique key pointer. + */ +- (void)atomicallyAssociateValue:(id)value withKey:(const void *)key; + +/** Strongly, thread-safely associates an object with the receiving class. + + @see associateValue:withKey: + @param value Any object. + @param key A unique key pointer. + */ ++ (void)atomicallyAssociateValue:(id)value withKey:(const void *)key; + +/** Associates a copy of an object with the reciever. + + The associated value is copied as if it were a property + synthesized with `nonatomic` and `copy`. + + Using copied association is recommended for a block or + otherwise `NSCopying`-compliant instances like NSString. + + @param value Any object, pointer, or value. + @param key A unique key pointer. + */ +- (void)associateCopyOfValue:(id)value withKey:(const void *)key; + +/** Associates a copy of an object with the receiving class. + + @see associateCopyOfValue:withKey: + @param value Any object, pointer, or value. + @param key A unique key pointer. + */ ++ (void)associateCopyOfValue:(id)value withKey:(const void *)key; + +/** Thread-safely associates a copy of an object with the reciever. + + The associated value is copied as if it were a property + synthesized with `atomic` and `copy`. + + Using copied association is recommended for a block or + otherwise `NSCopying`-compliant instances like NSString. + + @see associateCopyOfValue:withKey: + @param value Any object, pointer, or value. + @param key A unique key pointer. + */ +- (void)atomicallyAssociateCopyOfValue:(id)value withKey:(const void *)key; + +/** Thread-safely associates a copy of an object with the receiving class. + + @see associateCopyOfValue:withKey: + @param value Any object, pointer, or value. + @param key A unique key pointer. + */ ++ (void)atomicallyAssociateCopyOfValue:(id)value withKey:(const void *)key; + +/** Weakly associates an object with the reciever. + + A weak association will cause the pointer to be set to zero + or nil upon the disappearance of what it references; + in other words, the associated object is not kept alive. + + @param value Any object. + @param key A unique key pointer. + */ +- (void)weaklyAssociateValue:(id)value withKey:(const void *)key; + +/** Weakly associates an object with the receiving class. + + @see weaklyAssociateValue:withKey: + @param value Any object. + @param key A unique key pointer. + */ ++ (void)weaklyAssociateValue:(id)value withKey:(const void *)key; + +/** Returns the associated value for a key on the reciever. + + @param key A unique key pointer. + @return The object associated with the key, or `nil` if not found. + */ +- (id)associatedValueForKey:(const void *)key; + +/** Returns the associated value for a key on the receiving class. + + @see associatedValueForKey: + @param key A unique key pointer. + @return The object associated with the key, or `nil` if not found. + */ ++ (id)associatedValueForKey:(const void *)key; + +/** Returns the reciever to a clean state by removing all + associated objects, releasing them if necessary. */ +- (void)removeAllAssociatedObjects; + +/** Returns the recieving class to a clean state by removing + all associated objects, releasing them if necessary. */ ++ (void)removeAllAssociatedObjects; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSObject+AssociatedObjects.m b/Pods/BlocksKit/BlocksKit/NSObject+AssociatedObjects.m new file mode 100755 index 0000000..e66cd37 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSObject+AssociatedObjects.m @@ -0,0 +1,71 @@ +// +// NSObject+AssociatedObjects.m +// BlocksKit +// + +#import "NSObject+AssociatedObjects.h" +#import <objc/runtime.h> + +@implementation NSObject (BKAssociatedObjects) + +#pragma mark - Instance Methods + +- (void)associateValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (void)atomicallyAssociateValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN); +} + +- (void)associateCopyOfValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY_NONATOMIC); +} + +- (void)atomicallyAssociateCopyOfValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY); +} + +- (void)weaklyAssociateValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_ASSIGN); +} + +- (id)associatedValueForKey:(const void *)key { + return objc_getAssociatedObject(self, key); +} + +- (void)removeAllAssociatedObjects { + objc_removeAssociatedObjects(self); +} + +#pragma mark - Class Methods + ++ (void)associateValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + ++ (void)atomicallyAssociateValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN); +} + ++ (void)associateCopyOfValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY_NONATOMIC); +} + ++ (void)atomicallyAssociateCopyOfValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY); +} + ++ (void)weaklyAssociateValue:(id)value withKey:(const void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_ASSIGN); +} + ++ (id)associatedValueForKey:(const void *)key { + return objc_getAssociatedObject(self, key); +} + ++ (void)removeAllAssociatedObjects { + objc_removeAssociatedObjects(self); +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSObject+BlockObservation.h b/Pods/BlocksKit/BlocksKit/NSObject+BlockObservation.h new file mode 100755 index 0000000..b66d9d3 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSObject+BlockObservation.h @@ -0,0 +1,138 @@ +// +// NSObject+BlockObservation.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Blocks wrapper for key-value observation. + + In Mac OS X Panther, Apple introduced an API called "key-value + observing." It implements an [observer pattern](http://en.wikipedia.org/wiki/Observer_pattern), + where an object will notify observers of any changes in state. + + NSNotification is a rudimentary form of this design style; + KVO, however, allows for the observation of any change in key-value state. + The API for key-value observation, however, is flawed, ugly, and lengthy. + + Like most of the other block abilities in BlocksKit, observation saves + and a bunch of code and a bunch of potential bugs. + + Includes code by the following: + + - [Andy Matuschak](https://github.com/andymatuschak) + - [Jon Sterling](https://github.com/jonsterling) + - [Zach Waldowski](https://github.com/zwaldowski) + - [Jonathan Wight](https://github.com/schwa) + */ + +@interface NSObject (BlockObservation) + +/** Adds an observer to an object conforming to NSKeyValueObserving. + + Adds a block observer that executes a block upon a state change. + + @param keyPath The property to observe, relative to the reciever. + @param task A block with no return argument, and a single parameter: the reciever. + @return Returns a globally unique process identifier for removing + observation with removeObserverWithBlockToken:. + @see addObserverForKeyPath:identifier:options:task: + */ +- (NSString *)addObserverForKeyPath:(NSString *)keyPath task:(BKSenderBlock)task; + +/** Adds an observer to an object conforming to NSKeyValueObserving. + + Adds a block observer that executes the same block upon + multiple state changes. + + @param keyPaths An array of properties to observe, relative to the reciever. + @param task A block with no return argument and two parameters: the + reciever and the key path of the value change. + @return A unique identifier for removing + observation with removeObserverWithBlockToken:. + @see addObserverForKeyPath:identifier:options:task: + */ +- (NSString *)addObserverForKeyPaths:(NSArray *)keyPaths task:(BKSenderKeyPathBlock)task; + +/** Adds an observer to an object conforming to NSKeyValueObserving. + + Adds a block observer that executes a block upon a state change + with specific options. + + @param keyPath The property to observe, relative to the reciever. + @param options The NSKeyValueObservingOptions to use. + @param task A block with no return argument and two parameters: the + reciever and the change dictionary. + @return Returns a globally unique process identifier for removing + observation with removeObserverWithBlockToken:. + @see addObserverForKeyPath:identifier:options:task: + */ +- (NSString *)addObserverForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options task:(BKObservationBlock)task; + +/** Adds an observer to an object conforming to NSKeyValueObserving. + + Adds a block observer that executes the same block upon + multiple state changes with specific options. + + @param keyPaths An array of properties to observe, relative to the reciever. + @param options The NSKeyValueObservingOptions to use. + @param task A block with no return argument and three parameters: the + reciever, the key path of the value change, and the change dictionary. + @param task A block responding to the reciever, the key path, and the KVO change. + @return A unique identifier for removing + observation with removeObserverWithBlockToken:. + @see addObserverForKeyPath:identifier:options:task: + */ +- (NSString *)addObserverForKeyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options task:(BKMultipleObservationBlock)task; + +/** Adds an observer to an object conforming to NSKeyValueObserving. + + Adds a block observer that executes the block upon a + state change. + + @param keyPath The property to observe, relative to the reciever. + @param token An identifier for the observation block. + @param options The NSKeyValueObservingOptions to use. + @param task A block responding to the reciever and the KVO change. + observation with removeObserverWithBlockToken:. + @see addObserverForKeyPath:task: + */ +- (void)addObserverForKeyPath:(NSString *)keyPath identifier:(NSString *)token options:(NSKeyValueObservingOptions)options task:(BKObservationBlock)task; + +/** Adds an observer to an object conforming to NSKeyValueObserving. + + Adds a block observer that executes the same block upon + multiple state changes. + + @param keyPaths An array of properties to observe, relative to the reciever. + @param token An identifier for the observation block. + @param options The NSKeyValueObservingOptions to use. + @param task A block responding to the reciever, the key path, and the KVO change. + observation with removeObserversWithIdentifier:. + @see addObserverForKeyPath:task: + */ +- (void)addObserverForKeyPaths:(NSArray *)keyPaths identifier:(NSString *)token options:(NSKeyValueObservingOptions)options task:(BKMultipleObservationBlock)task; + +/** Removes a block observer. + + @param keyPath The property to stop observing, relative to the reciever. + @param token The unique key returned by addObserverForKeyPath:task: + or the identifier given in addObserverForKeyPath:identifier:task:. + @see removeObserversWithIdentifier: + */ +- (void)removeObserverForKeyPath:(NSString *)keyPath identifier:(NSString *)token; + +/** Removes multiple block observers with a certain identifier. + + @param token A unique key returned by addObserverForKeyPath:task: + and addObserverForKeyPaths:task: or the identifier given in + addObserverForKeyPath:identifier:task: and + addObserverForKeyPaths:identifier:task:. + @see removeObserverForKeyPath:identifier: + */ +- (void)removeObserversWithIdentifier:(NSString *)token; + +/** Remove all registered block observers. */ +- (void)removeAllBlockObservers; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSObject+BlockObservation.m b/Pods/BlocksKit/BlocksKit/NSObject+BlockObservation.m new file mode 100755 index 0000000..5824f55 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSObject+BlockObservation.m @@ -0,0 +1,280 @@ +// +// NSObject+BlockObservation.m +// BlocksKit +// + +#import "NSObject+BlockObservation.h" +#import "NSObject+AssociatedObjects.h" +#import "NSDictionary+BlocksKit.h" +#import "NSArray+BlocksKit.h" +#import "NSSet+BlocksKit.h" +#import <objc/runtime.h> + +typedef NS_ENUM(int, BKObserverContext) { + BKObserverContextKey, + BKObserverContextKeyWithChange, + BKObserverContextManyKeys, + BKObserverContextManyKeysWithChange +}; + +@interface BKObserver : NSObject + +@property (nonatomic, readonly, unsafe_unretained) id observee; +@property (nonatomic, readonly) NSMutableArray *keyPaths; +@property (nonatomic, readonly) id task; +@property (nonatomic, readonly) BKObserverContext context; + +- (id)initWithObservee:(id)observee keyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options context:(BKObserverContext)context task:(id)task; + +@end + +static char kObserverBlocksKey; +static char BKBlockObservationContext; + +@implementation BKObserver + +- (id)initWithObservee:(id)observee keyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options context:(BKObserverContext)context task:(id)task { + if ((self = [super init])) { + _observee = observee; + _keyPaths = [keyPaths mutableCopy]; + _context = context; + _task = [task copy]; + [self startObservingWithOptions: options]; + } + return self; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if (context != &BKBlockObservationContext) return; + + @synchronized(self) { + switch (self.context) { + case BKObserverContextKey: { + BKSenderBlock task = self.task; + task(object); + break; + } + case BKObserverContextKeyWithChange: { + BKObservationBlock task = self.task; + task(object, change); + break; + } + case BKObserverContextManyKeys: { + BKSenderKeyPathBlock task = self.task; + task(object, keyPath); + break; + } + case BKObserverContextManyKeysWithChange: { + BKMultipleObservationBlock task = self.task; + task(object, keyPath, change); + break; + } + } + } +} + +- (void)startObservingWithOptions:(NSKeyValueObservingOptions)options { + [self.keyPaths each:^(NSString *keyPath) { + [self.observee addObserver:self forKeyPath:keyPath options:options context:&BKBlockObservationContext]; + }]; +} + +- (void)stopObservingKeyPath:(NSString *)keyPath { + NSParameterAssert(keyPath); + + NSObject *observee; + + @synchronized (self) { + if (![self.keyPaths containsObject:keyPath]) return; + + observee = self.observee; + if (!observee) return; + + [self.keyPaths removeObject: keyPath]; + keyPath = [keyPath copy]; + + if (!self.keyPaths.count) { + _task = nil; + _observee = nil; + _keyPaths = nil; + } + } + + [observee removeObserver:self forKeyPath:keyPath context:&BKBlockObservationContext]; +} + +- (void)stopObserving { + if (_observee == nil) return; + NSObject *observee; + NSArray *keyPaths; + + @synchronized (self) { + _task = nil; + + observee = self.observee; + keyPaths = [self.keyPaths copy]; + + _observee = nil; + _keyPaths = nil; + } + + [keyPaths each:^(NSString *keyPath) { + [observee removeObserver:self forKeyPath:keyPath context: &BKBlockObservationContext]; + }]; +} + +- (void)dealloc { + [self stopObserving]; +} + +@end + +static NSMutableSet *swizzledClasses() { + static dispatch_once_t onceToken; + static NSMutableSet *swizzledClasses = nil; + dispatch_once(&onceToken, ^{ + swizzledClasses = [[NSMutableSet alloc] init]; + }); + + return swizzledClasses; +} + +@implementation NSObject (BlockObservation) + +- (NSString *)addObserverForKeyPath:(NSString *)keyPath task:(BKSenderBlock)task { + NSString *token = [[NSProcessInfo processInfo] globallyUniqueString]; + [self bk_addObserverForKeyPaths:@[ keyPath ] identifier:token options:0 context:BKObserverContextKey task:task]; + return token; +} + +- (NSString *)addObserverForKeyPaths:(NSArray *)keyPaths task:(BKSenderKeyPathBlock)task { + NSString *token = [[NSProcessInfo processInfo] globallyUniqueString]; + [self bk_addObserverForKeyPaths:keyPaths identifier:token options:0 context:BKObserverContextManyKeys task:task]; + return token; +} + +- (NSString *)addObserverForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options task:(BKObservationBlock)task { + NSString *token = [[NSProcessInfo processInfo] globallyUniqueString]; + [self addObserverForKeyPath:keyPath identifier:token options:options task:task]; + return token; +} + +- (NSString *)addObserverForKeyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options task:(BKMultipleObservationBlock)task { + NSString *token = [[NSProcessInfo processInfo] globallyUniqueString]; + [self addObserverForKeyPaths:keyPaths identifier:token options:options task:task]; + return token; +} + +- (void)addObserverForKeyPath:(NSString *)keyPath identifier:(NSString *)identifier options:(NSKeyValueObservingOptions)options task:(BKObservationBlock)task { + BKObserverContext context = (options == 0) ? BKObserverContextKey : BKObserverContextKeyWithChange; + [self bk_addObserverForKeyPaths:@[keyPath] identifier:identifier options:options context:context task:task]; +} + +- (void)addObserverForKeyPaths:(NSArray *)keyPaths identifier:(NSString *)identifier options:(NSKeyValueObservingOptions)options task:(BKMultipleObservationBlock)task { + BKObserverContext context = (options == 0) ? BKObserverContextManyKeys : BKObserverContextManyKeysWithChange; + [self bk_addObserverForKeyPaths:keyPaths identifier:identifier options:options context:context task:task]; +} + +- (void)removeObserverForKeyPath:(NSString *)keyPath identifier:(NSString *)token { + NSParameterAssert(keyPath.length); + NSParameterAssert(token.length); + + NSMutableDictionary *dict; + + @synchronized (self) { + dict = [self bk_observerBlocks]; + if (!dict) return; + } + + BKObserver *observer = dict[token]; + [observer stopObservingKeyPath: keyPath]; + + if (observer.keyPaths.count == 0) { + [dict removeObjectForKey:token]; + } + + if (dict.count == 0) [self bk_setObserverBlocks:nil]; +} + +- (void)removeObserversWithIdentifier:(NSString *)token { + NSParameterAssert(token); + + NSMutableDictionary *dict; + + @synchronized (self) { + dict = [self bk_observerBlocks]; + if (!dict) return; + } + + BKObserver *observer = dict[token]; + [observer stopObserving]; + + [dict removeObjectForKey:token]; + + if (dict.count == 0) [self bk_setObserverBlocks:nil]; +} + +- (void)removeAllBlockObservers { + NSDictionary *dict; + + @synchronized (self) { + dict = [[self bk_observerBlocks] copy]; + [self bk_setObserverBlocks: nil]; + } + + [dict.allValues each:^(BKObserver *trampoline) { + [trampoline stopObserving]; + }]; +} + +#pragma mark - "Private" + +- (void)bk_addObserverForKeyPaths:(NSArray *)keyPaths identifier:(NSString *)identifier options:(NSKeyValueObservingOptions)options context:(BKObserverContext)context task:(id)task { + NSParameterAssert(keyPaths.count); + NSParameterAssert(identifier.length); + NSParameterAssert(task); + + @synchronized (swizzledClasses()) { + Class classToSwizzle = self.class; + NSString *className = NSStringFromClass(classToSwizzle); + if (![swizzledClasses() containsObject:className]) { + SEL deallocSelector = sel_registerName("dealloc"); + + Method deallocMethod = class_getInstanceMethod(classToSwizzle, deallocSelector); + void (*originalDealloc)(id, SEL) = (__typeof__(originalDealloc))method_getImplementation(deallocMethod); + + id newDealloc = ^(__unsafe_unretained NSObject *self) { + [self removeAllBlockObservers]; + originalDealloc(self, deallocSelector); + }; + + class_replaceMethod(classToSwizzle, deallocSelector, imp_implementationWithBlock(newDealloc), method_getTypeEncoding(deallocMethod)); + + [swizzledClasses() addObject:className]; + } + } + + NSMutableDictionary *dict; + BKObserver *observer = [[BKObserver alloc] initWithObservee:self keyPaths:keyPaths options:options context:context task:task]; + + @synchronized (self) { + dict = [self bk_observerBlocks]; + + if (dict == nil) { + dict = [NSMutableDictionary dictionary]; + [self bk_setObserverBlocks:dict]; + } + } + + dict[identifier] = observer; +} + +- (void)bk_setObserverBlocks:(NSMutableDictionary *)dict { + [self associateValue:dict withKey:&kObserverBlocksKey]; +} + +- (NSMutableDictionary *)bk_observerBlocks { + return [self associatedValueForKey:&kObserverBlocksKey]; +} + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSObject+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSObject+BlocksKit.h new file mode 100755 index 0000000..ef50cf9 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSObject+BlocksKit.h @@ -0,0 +1,72 @@ +// +// NSObject+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" +#import "NSObject+AssociatedObjects.h" + +/** Block execution on *any* object. + + This category overhauls the `performSelector:` utilities on + NSObject to instead use blocks. Not only are the blocks performed + extremely speedily, thread-safely, and asynchronously using + Grand Central Dispatch, but each convenience method also returns + a pointer that can be used to cancel the execution before it happens! + + Includes code by the following: + + - [Peter Steinberger](https://github.com/steipete) + - [Zach Waldowski](https://github.com/zwaldowski) + + */ +@interface NSObject (BlocksKit) + +/** Executes a block after a given delay on the reciever. + + [array performBlock:^(id obj){ + [obj addObject:self]; + [self release]; + } afterDelay:0.5f]; + + @warning *Important:* Use of the **self** reference in a block will + reference the current implementation context. The block argument, + `obj`, should be used instead. + + @param block A single-argument code block, where `obj` is the reciever. + @param delay A measure in seconds. + @return Returns a pointer to the block that may or may not execute the given block. + */ +- (id)performBlock:(BKSenderBlock)block afterDelay:(NSTimeInterval)delay; + +/** Executes a block after a given delay. + + This class method is functionally identical to its instance method version. It still executes + asynchronously via GCD. However, the current context is not passed so that the block is performed + in a general context. + + Block execution is very useful, particularly for small events that you would like delayed. + + [object performBlock:^(){ + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + } afterDelay:0.5f]; + + @see performBlock:afterDelay: + @param block A code block. + @param delay A measure in seconds. + @return Returns a pointer to the block that may or may not execute the given block. + */ ++ (id)performBlock:(BKBlock)block afterDelay:(NSTimeInterval)delay; + +/** Cancels the potential execution of a block. + + @warning *Important:* It is not recommended to cancel a block executed + with no delay (a delay of 0.0). While it it still possible to catch the block + before GCD has executed it, it has likely already been executed and disposed of. + + @param block A pointer to a containing block, as returned from one of the + `performBlock` selectors. + */ ++ (void)cancelBlock:(id)block; + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSObject+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSObject+BlocksKit.m new file mode 100644 index 0000000..d5c8ff6 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSObject+BlocksKit.m @@ -0,0 +1,59 @@ +// +// NSObject+BlocksKit.m +// BlocksKit +// + +#import "NSObject+BlocksKit.h" +#import <objc/runtime.h> + +typedef void(^BKInternalWrappingBlock)(BOOL); + +#define BKTimeDelay(t) dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(NSEC_PER_SEC * t)) + +@implementation NSObject (BlocksKit) + +- (id)performBlock:(BKSenderBlock)block afterDelay:(NSTimeInterval)delay { + NSParameterAssert(block != nil); + + __block BOOL cancelled = NO; + + void(^wrapper)(BOOL) = ^(BOOL cancel) { + if (cancel) { + cancelled = YES; + return; + } + if (!cancelled) block(self); + }; + + dispatch_after(BKTimeDelay(delay), dispatch_get_main_queue(), ^{ + wrapper(NO); + }); + + return [wrapper copy]; +} + ++ (id)performBlock:(BKBlock)block afterDelay:(NSTimeInterval)delay { + NSParameterAssert(block != nil); + + __block BOOL cancelled = NO; + + void(^wrapper)(BOOL) = ^(BOOL cancel) { + if (cancel) { + cancelled = YES; + return; + } + if (!cancelled) block(); + }; + + dispatch_after(BKTimeDelay(delay), dispatch_get_main_queue(), ^{ wrapper(NO); }); + + return [wrapper copy]; +} + ++ (void)cancelBlock:(id)block { + NSParameterAssert(block != nil); + void(^wrapper)(BOOL) = block; + wrapper(YES); +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSOrderedSet+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSOrderedSet+BlocksKit.h new file mode 100755 index 0000000..b641381 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSOrderedSet+BlocksKit.h @@ -0,0 +1,168 @@ +// +// NSOrderedSet+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSOrderedSet. + + Both inspired by and resembling Smalltalk syntax, these utilities allow for + iteration through an ordered set (also known as a uniqued array) in a concise + way that saves a ton of boilerplate code for filtering or finding objects. + + Includes code by the following: + + - Robin Lu. <https://github.com/robin>. 2009. + - Michael Ash. <https://github.com/mikeash>. 2010. BSD. + - Aleks Nesterow. <https://github.com/nesterow>. 2010. BSD. + - Zach Waldowski. <https://github.com/zwaldowski>. 2011. + + @see NSArray(BlocksKit) + @see NSSet(BlocksKit) + */ +@interface NSOrderedSet (BlocksKit) + +/** Loops through an ordered set and executes the given block with each object. + + @param block A single-argument, void-returning code block. + */ +- (void)each:(BKSenderBlock)block; + +/** Enumerates through an ordered set concurrently and executes the given block + once for each object. + + Enumeration will occur on appropriate background queues. This will have a + noticeable speed increase, especially on multi-core devices, but you *must* + be aware of the thread safety of the objects you message from within the block. + Be aware that the order of objects is not necessarily the order each block will + be called in. + + @param block A single-argument, void-returning code block. + */ +- (void)apply:(BKSenderBlock)block; + +/** Loops through an ordered set to find the object matching the block. + + match: is functionally identical to select:, but will stop and return + on the first match. + + @param block A single-argument, `BOOL`-returning code block. + @return Returns the object, if found, or `nil`. + @see select: + */ +- (id)match:(BKValidationBlock)block; + +/** Loops through an ordered set to find the objects matching the block. + + @param block A single-argument, BOOL-returning code block. + @return Returns an ordered set of the objects found. + @see match: + */ +- (NSOrderedSet *)select:(BKValidationBlock)block; + +/** Loops through an ordered set to to find the objects not matching the block. + + This selector performs *literally* the exact same function as select: but in + reverse. + + This is useful, as one may expect, for removing objects from an ordered set to. + NSOrderedSet *new = [computers reject:^BOOL(id obj) { + return ([obj isUgly]); + }]; + + @param block A single-argument, BOOL-returning code block. + @return Returns an ordered set of all objects not found. + */ +- (NSOrderedSet *)reject:(BKValidationBlock)block; + +/** Call the block once for each object and create an ordered set of the return + values. + + This is sometimes referred to as a transform, mutating one of each object: + NSOrderedSet *new = [stringArray map:^id(id obj) { + return [obj stringByAppendingString:@".png"]); + }]; + + @param block A single-argument, object-returning code block. + @return Returns an ordered set of the objects returned by the block. + */ +- (NSOrderedSet *)map:(BKTransformBlock)block; + +/** Arbitrarily accumulate objects using a block. + + The concept of this selector is difficult to illustrate in words. The sum can + be any NSObject, including (but not limited to) a string, number, or value. + + For example, you can concentate the strings in an ordered set: + NSString *concentrated = [stringArray reduce:@"" withBlock:^id(id sum, id obj) { + return [sum stringByAppendingString:obj]; + }]; + + You can also do something like summing the lengths of strings in an ordered set: + NSUInteger value = [[[stringArray reduce:nil withBlock:^id(id sum, id obj) { + return @([sum integerValue] + obj.length); + }]] unsignedIntegerValue]; + + @param initial The value of the reduction at its start. + @param block A block that takes the current sum and the next object to return the new sum. + @return An accumulated value. + */ +- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block; + +/** Loops through an ordered set to find whether any object matches the block. + + This method is similar to the Scala list `exists`. It is functionally + identical to match: but returns a `BOOL` instead. It is not recommended + to use any: as a check condition before executing match:, since it would + require two loops through the ordered set. + + For example, you can find if a string in an ordered set starts with a certain + letter: + + NSString *letter = @"A"; + BOOL containsLetter = [stringArray any: ^(id obj) { + return [obj hasPrefix: @"A"]; + }]; + + @param block A single-argument, BOOL-returning code block. + @return YES for the first time the block returns YES for an object, NO otherwise. + */ +- (BOOL)any:(BKValidationBlock)block; + +/** Loops through an ordered set to find whether no objects match the block. + + This selector performs *literally* the exact same function as all: but in reverse. + + @param block A single-argument, BOOL-returning code block. + @return YES if the block returns NO for all objects in the ordered set, NO + otherwise. + */ +- (BOOL)none:(BKValidationBlock)block; + +/** Loops through an ordered set to find whether all objects match the block. + + @param block A single-argument, BOOL-returning code block. + @return YES if the block returns YES for all objects in the ordered set, NO + otherwise. + */ +- (BOOL) all: (BKValidationBlock)block; + +/** Tests whether every element of this ordered set relates to the corresponding + element of another array according to match by block. + + For example, finding if a list of numbers corresponds to their sequenced string values; + + NSArray *numbers = @[ @(1), @(2), @(3) ]; + NSArray *letters = @[ @"1", @"2", @"3" ]; + BOOL doesCorrespond = [numbers corresponds: letters withBlock: ^(id number, id letter) { + return [[number stringValue] isEqualToString: letter]; + }]; + + @param list An array of objects to compare with. + @param block A two-argument, BOOL-returning code block. + @return Returns a BOOL, true if every element of the ordered set relates to + corresponding element in another ordered set. + */ +- (BOOL) corresponds: (NSOrderedSet *) list withBlock: (BKKeyValueValidationBlock) block; +@end diff --git a/Pods/BlocksKit/BlocksKit/NSOrderedSet+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSOrderedSet+BlocksKit.m new file mode 100755 index 0000000..e4ee434 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSOrderedSet+BlocksKit.m @@ -0,0 +1,130 @@ +// +// NSOrderedSet+BlocksKit.m +// BlocksKit +// +// Created by Zachary Waldowski on 10/5/12. +// Copyright (c) 2012 Pandamonia LLC. All rights reserved. +// + +#import "NSOrderedSet+BlocksKit.h" + +@implementation NSOrderedSet (BlocksKit) + +- (void)each:(BKSenderBlock)block { + NSParameterAssert(block != nil); + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + block(obj); + }]; +} + +- (void)apply:(BKSenderBlock)block { + NSParameterAssert(block != nil); + + [self enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + block(obj); + }]; +} + +- (id)match:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + NSUInteger index = [self indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + return block(obj); + }]; + + if (index == NSNotFound) + return nil; + + return self[index]; +} + +- (NSOrderedSet *)select:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + NSArray *objects = [self objectsAtIndexes:[self indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + return block(obj); + }]]; + + if (!objects.count) + return [[self class] orderedSet]; + + return [[self class] orderedSetWithArray: objects]; +} + +- (NSOrderedSet *)reject:(BKValidationBlock)block { + return [self select:^BOOL(id obj) { + return !block(obj); + }]; +} + +- (NSOrderedSet *)map:(BKTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableOrderedSet *result = [NSMutableOrderedSet orderedSetWithCapacity: self.count]; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + id value = block(obj); + if (!value) + value = [NSNull null]; + + [result addObject:value]; + }]; + + return result; +} + +- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block { + NSParameterAssert(block != nil); + + __block id result = initial; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + result = block(result, obj); + }]; + + return result; +} + +- (BOOL)any:(BKValidationBlock)block { + return [self match: block] != nil; +} + +- (BOOL)none:(BKValidationBlock)block { + return [self match: block] == nil; +} + +- (BOOL) all: (BKValidationBlock)block { + NSParameterAssert(block != nil); + + __block BOOL result = YES; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (!block(obj)) { + result = NO; + *stop = YES; + } + }]; + + return result; +} + +- (BOOL) corresponds: (NSOrderedSet *) list withBlock: (BKKeyValueValidationBlock) block { + NSParameterAssert(block != nil); + + __block BOOL result = NO; + + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (idx < list.count) { + id obj2 = list[idx]; + result = block(obj, obj2); + } else { + result = NO; + } + *stop = !result; + }]; + + return result; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSSet+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSSet+BlocksKit.h new file mode 100755 index 0000000..64b85b5 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSSet+BlocksKit.h @@ -0,0 +1,133 @@ +// +// NSSet+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block extensions for NSSet. + + Both inspired by and resembling Smalltalk syntax, these utilities allows for + iteration of a set in a logical way that saves quite a bit of boilerplate code + for filtering or finding objects or an object. + + Includes code by the following: + +- [Michael Ash](https://github.com/mikeash) +- [Corey Floyd](https://github.com/coreyfloyd) +- [Aleks Nesterow](https://github.com/nesterow) +- [Zach Waldowski](https://github.com/zwaldowski) + + @see NSArray(BlocksKit) + @see NSDictionary(BlocksKit) + */ +@interface NSSet (BlocksKit) + +/** Loops through a set and executes the given block with each object. + + @param block A single-argument, void-returning code block. + */ +- (void)each:(BKSenderBlock)block; + +/** Enumerates through a set concurrently and executes + the given block once for each object. + + Enumeration will occur on appropriate background queues. This + will have a noticeable speed increase, especially on dual-core + devices, but you *must* be aware of the thread safety of the + objects you message from within the block. + + @param block A single-argument, void-returning code block. + */ +- (void)apply:(BKSenderBlock)block; + +/** Loops through a set to find the object matching the block. + + match: is functionally identical to select:, but will stop and return + on the first match. + + @param block A single-argument, BOOL-returning code block. + @return Returns the object if found, `nil` otherwise. + @see select: + */ +- (id)match:(BKValidationBlock)block; + +/** Loops through a set to find the objects matching the block. + + @param block A single-argument, BOOL-returning code block. + @return Returns a set of the objects found. + @see match: + */ +- (NSSet *)select:(BKValidationBlock)block; + +/** Loops through a set to find the objects not matching the block. + + This selector performs *literally* the exact same function as select, but in reverse. + + This is useful, as one may expect, for removing objects from a set: + NSSet *new = [reusableWebViews reject:^BOOL(id obj) { + return ([obj isLoading]); + }]; + + @param block A single-argument, BOOL-returning code block. + @return Returns an array of all objects not found. + */ +- (NSSet *)reject:(BKValidationBlock)block; + +/** Call the block once for each object and create a set of the return values. + + This is sometimes referred to as a transform, mutating one of each object: + NSSet *new = [mimeTypes map:^id(id obj) { + return [@"x-company-" stringByAppendingString:obj]); + }]; + + @param block A single-argument, object-returning code block. + @return Returns a set of the objects returned by the block. + */ +- (NSSet *)map:(BKTransformBlock)block; + +/** Arbitrarily accumulate objects using a block. + + The concept of this selector is difficult to illustrate in words. The sum can + be any NSObject, including (but not limited to) a string, number, or value. + + You can also do something like summing the count of an item: + NSUInteger numberOfBodyParts = [[bodyList reduce:nil withBlock:^id(id sum, id obj) { + return @([sum integerValue] + obj.numberOfAppendages); + }] unsignedIntegerValue]; + + @param initial The value of the reduction at its start. + @param block A block that takes the current sum and the next object to return the new sum. + @return An accumulated value. + */ +- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block; + +/** Loops through a set to find whether any object matches the block. + + This method is similar to the Scala list `exists`. It is functionally + identical to match: but returns a `BOOL` instead. It is not recommended + to use any: as a check condition before executing match:, since it would + require two loops through the array. + + @param block A single-argument, BOOL-returning code block. + @return YES for the first time the block returns YES for an object, NO otherwise. + */ +- (BOOL)any:(BKValidationBlock)block; + +/** Loops through a set to find whether no objects match the block. + + This selector performs *literally* the exact same function as all: but in reverse. + + @param block A single-argument, BOOL-returning code block. + @return YES if the block returns NO for all objects in the set, NO otherwise. + */ +- (BOOL)none:(BKValidationBlock)block; + +/** Loops through a set to find whether all objects match the block. + + @param block A single-argument, BOOL-returning code block. + @return YES if the block returns YES for all objects in the set, NO otherwise. + */ +- (BOOL)all:(BKValidationBlock)block; + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSSet+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSSet+BlocksKit.m new file mode 100755 index 0000000..ad25739 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSSet+BlocksKit.m @@ -0,0 +1,105 @@ +// +// NSSet+BlocksKit.m +// BlocksKit +// + +#import "NSSet+BlocksKit.h" + +@implementation NSSet (BlocksKit) + +- (void)each:(BKSenderBlock)block { + NSParameterAssert(block != nil); + + [self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { + block(obj); + }]; +} + +- (void)apply:(BKSenderBlock)block { + NSParameterAssert(block != nil); + + [self enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, BOOL *stop) { + block(obj); + }]; +} + +- (id)match:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + return [[self objectsPassingTest:^BOOL(id obj, BOOL *stop) { + if (block(obj)) { + *stop = YES; + return YES; + } + return NO; + }] anyObject]; +} + +- (NSSet *)select:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + return [self objectsPassingTest:^BOOL(id obj, BOOL *stop) { + return (block(obj)); + }]; +} + +- (NSSet *)reject:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + return [self objectsPassingTest:^BOOL(id obj, BOOL *stop) { + return (!block(obj)); + }]; +} + +- (NSSet *)map:(BKTransformBlock)block { + NSParameterAssert(block != nil); + + NSMutableSet *result = [NSMutableSet setWithCapacity: self.count]; + + [self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { + id value = block(obj); + if (!value) + value = [NSNull null]; + + [result addObject:value]; + }]; + + return result; +} + +- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block { + NSParameterAssert(block != nil); + + __block id result = initial; + + [self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { + result = block(result, obj); + }]; + + return result; +} + +- (BOOL)any:(BKValidationBlock)block { + return [self match: block] != nil; +} + +- (BOOL)none:(BKValidationBlock)block { + return [self match: block] == nil; +} + +- (BOOL)all:(BKValidationBlock)block { + NSParameterAssert(block != nil); + + __block BOOL result = YES; + + [self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { + if (!block(obj)) { + result = NO; + *stop = YES; + } + }]; + + return result; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSTimer+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSTimer+BlocksKit.h new file mode 100755 index 0000000..62628d2 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSTimer+BlocksKit.h @@ -0,0 +1,36 @@ +// +// NSTimer+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Simple category on NSTimer to give it blocks capability. + + Created by [Jiva DeVoe](https://github.com/jivadevoe) as `NSTimer-Blocks`. +*/ +@interface NSTimer (BlocksKit) + +/** Creates and returns a block-based NSTimer object and schedules it on the current run loop. + + @param inTimeInterval The number of seconds between firings of the timer. + @param inBlock The block that the NSTimer fires. + @param inRepeats If YES, the timer will repeatedly reschedule itself until invalidated. If NO, the timer will be invalidated after it fires. + @return A new NSTimer object, configured according to the specified parameters. + */ ++ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(BKTimerBlock)inBlock repeats:(BOOL)inRepeats; + +/** Creates and returns a block-based NSTimer initialized with the specified block. + + You must add the new timer to a run loop, using `-addTimer:forMode:`. Then, + after seconds seconds have elapsed, the timer fires the block. If the timer + is configured to repeat, there is no need to subsequently re-add the timer. + + @param inTimeInterval The number of seconds between firings of the timer. + @param inBlock The block that the NSTimer fires. + @param inRepeats If YES, the timer will repeatedly reschedule itself until invalidated. If NO, the timer will be invalidated after it fires. + @return A new NSTimer object, configured according to the specified parameters. + */ ++ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(BKTimerBlock)inBlock repeats:(BOOL)inRepeats; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSTimer+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSTimer+BlocksKit.m new file mode 100755 index 0000000..69ceade --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSTimer+BlocksKit.m @@ -0,0 +1,30 @@ +// +// NSTimer+BlocksKit.m +// BlocksKit +// + +#import "NSTimer+BlocksKit.h" + +@interface NSTimer (BlocksKitPrivate) ++ (void)bk_executeBlockFromTimer:(NSTimer *)aTimer; +@end + +@implementation NSTimer (BlocksKit) + ++ (id)scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(BKTimerBlock)block repeats:(BOOL)inRepeats { + NSParameterAssert(block); + return [self scheduledTimerWithTimeInterval: inTimeInterval target: self selector: @selector(bk_executeBlockFromTimer:) userInfo: [block copy] repeats: inRepeats]; +} + ++ (id)timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(BKTimerBlock)block repeats:(BOOL)inRepeats { + NSParameterAssert(block); + return [self timerWithTimeInterval: inTimeInterval target: self selector: @selector(bk_executeBlockFromTimer:) userInfo: [block copy] repeats: inRepeats]; +} + ++ (void)bk_executeBlockFromTimer:(NSTimer *)aTimer { + NSTimeInterval time = [aTimer timeInterval]; + BKTimerBlock block = [aTimer userInfo]; + if (block) block(time); +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/NSURLConnection+BlocksKit.h b/Pods/BlocksKit/BlocksKit/NSURLConnection+BlocksKit.h new file mode 100644 index 0000000..423223d --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSURLConnection+BlocksKit.h @@ -0,0 +1,139 @@ +// +// NSURLConnection+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** NSURLConnection with both delegate and block callback support. + + It also adds useful block handlers for tracking upload and download progress. + + Here is a small example: + - (void)downloadImage:(id)sender { + self.downloadButton.enabled = NO; + self.progressView.progress = 0.0f; + NSURL *imageURL = [NSURL URLWithString:@"http://icanhascheezburger.files.wordpress.com/2011/06/funny-pictures-nyan-cat-wannabe1.jpg"]; + NSURLRequest *request = [NSURLRequest requestWithURL:imageURL]; + NSURLConnection *connection = [NSURLConnection connectionWithRequest:request]; + connection.delegate = self; + connection.failureBlock = ^(NSURLConnection *connection, NSError *error){ + [[UIAlertView alertViewWithTitle:@"Download error" message:[error localizedDescription]] show]; + + self.downloadButton.enabled = YES; + self.progressView.progress = 0.0f; + }; + connection.successBlock = ^(NSURLConnection *connection, NSURLResponse *response, NSData *responseData){ + self.imageView.image = [UIImage imageWithData:responseData]; + self.downloadButton.enabled = YES; + }; + connection.downloadBlock = ^(CGFloat progress){ + self.progressView.progress = progress; + }; + + [connection start]; + } + + //these methods will be called too! + - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { + NSLog(@"%s",__PRETTY_FUNCTION__); + } + + - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + NSLog(@"%s",__PRETTY_FUNCTION__); + } + + Created by Igor Evsukov as + [IEURLConnection](https://github.com/evsukov89/IEURLConnection) and contributed + to BlocksKit. +*/ + +@interface NSURLConnection (BlocksKit) + +/** A mutable delegate that implements the NSURLConnectionDelegate protocol. + + This property allows for both use of block callbacks and delegate methods + in an instance of NSURLConnection. It only works on block-backed + NSURLConnection instances. + */ +@property (nonatomic, weak) id delegate; + +/** The block fired once the connection recieves a response from the server. + + This block corresponds to the connection:didReceiveResponse: method + of NSURLConnectionDelegate. */ +@property (nonatomic, copy) void(^responseBlock)(NSURLConnection *, NSURLResponse *); + +/** The block fired upon the failure of the connection. + + This block corresponds to the connection:didFailWithError: + method of NSURLConnectionDelegate. */ +@property (nonatomic, copy) void (^failureBlock)(NSURLConnection *, NSError *); + +/** The block that upon the successful completion of the connection. + + This block corresponds to the connectionDidFinishLoading: + method of NSURLConnectionDelegate. + + @warning If the delegate implements connection:didRecieveData:, then this + block will *not* include the data recieved by the connection and appending + the recieved data to an instance NSMutableData is left up to the user due + to the behavior of frameworks that use NSURLConnection. + */ +@property (nonatomic, copy) void (^successBlock)(NSURLConnection *, NSURLResponse *, NSData *); + +/** The block fired every time new data is sent to the server, + representing the current percentage of completion. + + This block corresponds to the + connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: + method of NSURLConnectionDelegate. + */ +@property (nonatomic, copy) void (^uploadBlock)(CGFloat); + +/** The block fired every time new data is recieved from the server, + representing the current percentage of completion. + + This block corresponds to the connection:didRecieveData: + method of NSURLConnectionDelegate. + */ +@property (nonatomic, copy) void (^downloadBlock)(CGFloat); + +/** Creates and returns an initialized block-backed URL connection that does not begin to load the data for the URL request. + + @param request The URL request to load. + @return An autoreleased NSURLConnection for the specified URL request. + */ ++ (NSURLConnection *)connectionWithRequest:(NSURLRequest *)request; + +/** Creates, starts, and returns an asynchronous, block-backed URL connection + + @return New and running NSURLConnection with the specified properties. + @param request The URL request to load. + @param success A code block that acts on instances of NSURLResponse and NSData in the event of a successful connection. + @param failure A code block that acts on instances of NSURLResponse and NSError in the event of a failed connection. + */ ++ (NSURLConnection *)startConnectionWithRequest:(NSURLRequest *)request successHandler:(void(^)(NSURLConnection *urlConnection, NSURLResponse *urlResponse, NSData *data))success failureHandler:(void(^)(NSURLConnection *urlConnection, NSError *error))failure; + +/** Returns an initialized block-backed URL connection. + + @return Newly initialized NSURLConnection with the specified properties. + @param request The URL request to load. + */ +- (id)initWithRequest:(NSURLRequest *)request; + +/** Returns an initialized URL connection with the specified completion handler. + + @return Newly initialized NSURLConnection with the specified properties. + @param request The URL request to load. + @param block A code block that acts on instances of NSURLResponse and NSData in the event of a successful connection. + */ +- (id)initWithRequest:(NSURLRequest *)request completionHandler:(void(^)(NSURLConnection *urlConnection, NSURLResponse *urlResponse, NSData *data))block; + +/** Causes the connection to begin loading data, if it has not already, with the specified block to be fired on successful completion. + + @param block A code block that acts on instances of NSURLResponse and NSData in the event of a successful connection. + */ +- (void)startWithCompletionBlock:(void(^)(NSURLConnection *urlConnection, NSURLResponse *urlResponse, NSData *data))block; + +@end diff --git a/Pods/BlocksKit/BlocksKit/NSURLConnection+BlocksKit.m b/Pods/BlocksKit/BlocksKit/NSURLConnection+BlocksKit.m new file mode 100644 index 0000000..6406ef0 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/NSURLConnection+BlocksKit.m @@ -0,0 +1,394 @@ +// +// NSURLConnection+BlocksKit.m +// BlocksKit +// + +#import "NSURLConnection+BlocksKit.h" +#import "NSObject+AssociatedObjects.h" +#import <objc/runtime.h> + +#pragma mark Private + +static char kResponseDataKey; +static char kResponseKey; +static char kResponseLengthKey; + +@interface NSURLConnection (BlocksKitPrivate) +@property (nonatomic, retain, setter = bk_setResponseData:) NSMutableData *bk_responseData; +@property (nonatomic, retain, setter = bk_setResponse:) NSURLResponse *bk_response; +@property (nonatomic, setter = bk_setResponseLength:) NSUInteger bk_responseLength; +@end + +@implementation NSURLConnection (BlocksKitPrivate) + +- (NSMutableData *)bk_responseData { + return [self associatedValueForKey:&kResponseDataKey]; +} + +- (void)bk_setResponseData:(NSMutableData *)responseData { + [self associateValue:responseData withKey:&kResponseDataKey]; +} + +- (NSURLResponse *)bk_response { + return [self associatedValueForKey:&kResponseKey]; +} + +- (void)bk_setResponse:(NSURLResponse *)response { + return [self associateValue:response withKey:&kResponseKey]; +} + +- (NSUInteger)bk_responseLength { + return [[self associatedValueForKey:&kResponseLengthKey] unsignedIntegerValue]; +} + +- (void)bk_setResponseLength:(NSUInteger)responseLength { + return [self associateValue: @(responseLength) withKey: &kResponseLengthKey]; +} + +@end + +#pragma mark - BKURLConnectionInformalDelegate - iOS 4.3 & Snow Leopard support + +@protocol BKURLConnectionInformalDelegate <NSObject> +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response; +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data; +- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite; +- (void)connectionDidFinishLoading:(NSURLConnection *)connection; +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error; +- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; +- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace; +@end + +@interface A2DynamicBKURLConnectionInformalDelegate : A2DynamicDelegate + +@end + +@implementation A2DynamicBKURLConnectionInformalDelegate + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didReceiveResponse:)]) + [realDelegate connection:connection didReceiveResponse:response]; + + connection.bk_responseLength = 0; + [connection.bk_responseData setLength:0]; + + connection.bk_response = response; + + void (^block)(NSURLConnection *, NSURLResponse *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(connection, response); +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + connection.bk_responseLength += data.length; + + void (^block)(CGFloat) = connection.downloadBlock; + if (block && connection.bk_response && connection.bk_response.expectedContentLength != NSURLResponseUnknownLength) + block((CGFloat)connection.bk_responseLength / (CGFloat)connection.bk_response.expectedContentLength); + + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didReceiveData:)]) { + [realDelegate connection:connection didReceiveData:data]; + return; + } + + NSMutableData *responseData = connection.bk_responseData; + if (!responseData) { + responseData = [NSMutableData data]; + connection.bk_responseData = responseData; + } + + [responseData appendData:data]; +} + +- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:)]) + [realDelegate connection:connection didSendBodyData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite]; + + void (^block)(CGFloat) = connection.uploadBlock; + if (block) + block((CGFloat)totalBytesWritten/(CGFloat)totalBytesExpectedToWrite); +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connectionDidFinishLoading:)]) + [realDelegate connectionDidFinishLoading:connection]; + + if (!connection.bk_responseData.length) + connection.bk_responseData = nil; + + void(^block)(NSURLConnection *, NSURLResponse *, NSData *) = connection.successBlock; + if (block) + block(connection, connection.bk_response, connection.bk_responseData); +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didFailWithError:)]) + [realDelegate connection:connection didFailWithError:error]; + + connection.bk_responseLength = 0; + [connection.bk_responseData setLength:0]; + + void (^block)(NSURLConnection *, NSError *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(connection, error); +} + +- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didReceiveAuthenticationChallenge:)]) + [realDelegate connection:connection didReceiveAuthenticationChallenge:challenge]; +} + +- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:canAuthenticateAgainstProtectionSpace:)]) + return [realDelegate connection:connection canAuthenticateAgainstProtectionSpace:protectionSpace]; + + return NO; +} + +@end + +#pragma mark - NSURLConnectionDelegate - iOS 5.0 & Lion support + +@interface A2DynamicNSURLConnectionDelegate : A2DynamicDelegate + +@end + +@implementation A2DynamicNSURLConnectionDelegate + +- (BOOL)conformsToProtocol:(Protocol *)protocol { + Protocol *dataDelegateProtocol = objc_getProtocol("NSURLConnectionDataDelegate"); + return (protocol_isEqual(protocol, dataDelegateProtocol) || protocol_isEqual(protocol, self.protocol) || [super conformsToProtocol:protocol]); +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didFailWithError:)]) + [realDelegate connection:connection didFailWithError:error]; + + connection.bk_responseLength = 0; + [connection.bk_responseData setLength:0]; + + void (^block)(NSURLConnection *, NSError *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(connection, error); +} + +- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connectionShouldUseCredentialStorage:)]) + return [realDelegate connectionShouldUseCredentialStorage: connection]; + + return YES; +} + +- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:willSendRequestForAuthenticationChallenge:)]) + [realDelegate connection: connection willSendRequestForAuthenticationChallenge: challenge]; +} + +#pragma mark - NSURLConnectionDataDelegate + +- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:willSendRequest:redirectResponse:)]) + return [realDelegate connection: connection willSendRequest: request redirectResponse: response]; + + return request; +} + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didReceiveResponse:)]) + [realDelegate connection:connection didReceiveResponse:response]; + + connection.bk_responseLength = 0; + + if (connection.bk_responseData) + [connection.bk_responseData setLength:0]; + + connection.bk_response = response; + + void (^block)(NSURLConnection *, NSURLResponse *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(connection, response); +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + connection.bk_responseLength += data.length; + + void (^block)(CGFloat) = connection.downloadBlock; + if (block && connection.bk_response && connection.bk_response.expectedContentLength != NSURLResponseUnknownLength) + block((CGFloat)connection.bk_responseLength / (CGFloat)connection.bk_response.expectedContentLength); + + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didReceiveData:)]) { + [realDelegate connection:connection didReceiveData:data]; + return; + } + + NSMutableData *responseData = connection.bk_responseData; + if (!responseData) { + responseData = [NSMutableData data]; + connection.bk_responseData = responseData; + } + + [responseData appendData:data]; +} + +- (NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:needNewBodyStream:)]) + return [realDelegate connection: connection needNewBodyStream: request]; + + return nil; +} + +- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:)]) + [realDelegate connection:connection didSendBodyData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite]; + + void (^block)(CGFloat) = connection.uploadBlock; + if (block) + block((CGFloat)totalBytesWritten/(CGFloat)totalBytesExpectedToWrite); +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:willCacheResponse:)]) + return [realDelegate connection: connection willCacheResponse: cachedResponse]; + + return cachedResponse; +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)connection { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connectionDidFinishLoading:)]) + [realDelegate connectionDidFinishLoading:connection]; + + if (!connection.bk_responseData.length) + connection.bk_responseData = nil; + + void(^block)(NSURLConnection *, NSURLResponse *, NSData *) = connection.successBlock; + if (block) + block(connection, connection.bk_response, connection.bk_responseData); +} + +#pragma mark - Deprecated iOS 4.x authentication methods + +- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:didReceiveAuthenticationChallenge:)]) + [realDelegate connection:connection didReceiveAuthenticationChallenge:challenge]; +} + +- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(connection:canAuthenticateAgainstProtectionSpace:)]) + return [realDelegate connection:connection canAuthenticateAgainstProtectionSpace:protectionSpace]; + + return NO; +} + +@end + +#pragma mark - Category + +static NSString *const kSuccessBlockKey = @"NSURLConnectionDidFinishLoading"; +static NSString *const kFailureBlockKey = @"NSURLConnectionDidFailWithError"; +static NSString *const kUploadBlockKey = @"NSURLConnectionDidSendData"; +static NSString *const kDownloadBlockKey = @"NSURLConnectionDidRecieveData"; + +@implementation NSURLConnection (BlocksKit) + +@dynamic delegate, responseBlock, failureBlock; + ++ (void)load { + @autoreleasepool { + [self registerDynamicDelegate]; + [self linkDelegateMethods: @{ @"responseBlock": @"connection:didReceiveResponse:", @"failureBlock": @"connection:didFailWithError:" }]; + } +} + +#pragma mark Initializers + ++ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request { + return [[[self class] alloc] initWithRequest:request]; +} + ++ (NSURLConnection *)startConnectionWithRequest:(NSURLRequest *)request successHandler:(void(^)(NSURLConnection *, NSURLResponse *, NSData *))success failureHandler:(void(^)(NSURLConnection *, NSError *))failure { + Protocol *delegateProtocol = objc_getProtocol("NSURLConnectionDelegate"); + if (!delegateProtocol) + delegateProtocol = @protocol(BKURLConnectionInformalDelegate); + NSURLConnection *ret = [[self class] alloc]; + A2DynamicDelegate *dd = [ret dynamicDelegateForProtocol:delegateProtocol]; + if (success) + dd.handlers[kSuccessBlockKey] = [success copy]; + if (failure) + [dd implementMethod: @selector(connection:didFailWithError:) withBlock: [failure copy]]; + return [ret initWithRequest: request delegate: dd startImmediately: YES]; +} + +- (id)initWithRequest:(NSURLRequest *)request { + return [self initWithRequest:request completionHandler:NULL]; +} + +- (id)initWithRequest:(NSURLRequest *)request completionHandler:(void(^)(NSURLConnection *, NSURLResponse *, NSData *))block { + Protocol *delegateProtocol = objc_getProtocol("NSURLConnectionDelegate"); + if (!delegateProtocol) + delegateProtocol = @protocol(BKURLConnectionInformalDelegate); + A2DynamicDelegate *dd = [self dynamicDelegateForProtocol:delegateProtocol]; + if (block) + dd.handlers[kSuccessBlockKey] = [block copy]; + return [self initWithRequest: request delegate: dd startImmediately: NO]; +} + +- (void)startWithCompletionBlock:(void(^)(NSURLConnection *, NSURLResponse *, NSData *))block { + self.successBlock = block; + [self start]; +} + +#pragma mark Properties + +- (void(^)(NSURLConnection *, NSURLResponse *, NSData *))successBlock { + return [self.dynamicDelegate handlers][kSuccessBlockKey]; +} + +- (void)setSuccessBlock:(void(^)(NSURLConnection *, NSURLResponse *, NSData *))block { + if (block) + [self.dynamicDelegate handlers][kSuccessBlockKey] = [block copy]; + else + [[self.dynamicDelegate handlers] removeObjectForKey: kSuccessBlockKey]; +} + +- (void(^)(CGFloat))uploadBlock { + return [self.dynamicDelegate handlers][kUploadBlockKey]; +} + +- (void)setUploadBlock:(void(^)(CGFloat))block { + if (block) + [self.dynamicDelegate handlers][kUploadBlockKey] = [block copy]; + else + [[self.dynamicDelegate handlers] removeObjectForKey: kUploadBlockKey]; +} + +- (void(^)(CGFloat))downloadBlock { + return [self.dynamicDelegate handlers][kDownloadBlockKey]; +} + +- (void)setDownloadBlock:(void(^)(CGFloat))block { + if (block) + [self.dynamicDelegate handlers][kDownloadBlockKey] = [block copy]; + else + [[self.dynamicDelegate handlers] removeObjectForKey: kDownloadBlockKey]; +} + +@end diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.h b/Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.h new file mode 100755 index 0000000..b0cbe49 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.h @@ -0,0 +1,128 @@ +// +// UIActionSheet+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** UIActionSheet without delegates! + + This set of extensions and convenience classes allows + for an instance of UIAlertView without the implementation + of a delegate. Any time you instantiate a UIAlertView + using the methods here, you must add buttons using + addButtonWithTitle:handler: to make sure nothing breaks. + + A typical invocation might go like this: + UIActionSheet *testSheet = [UIActionSheet actionSheetWithTitle:@"Please select one."]; + [testSheet addButtonWithTitle:@"Zip" handler:^{ NSLog(@"Zip!"); }]; + [testSheet addButtonWithTitle:@"Zap" handler:^{ NSLog(@"Zap!"); }]; + [testSheet addButtonWithTitle:@"Zop" handler:^{ NSLog(@"Zop!"); }]; + [testSheet setDestructiveButtonWithTitle:@"No!" handler:^{ NSLog(@"Fine!"); }]; + [testSheet setCancelButtonWithTitle:nil handler:^{ NSLog(@"Never mind, then!"); }]; + [testSheet showInView:self.view]; + + Includes code by the following: + + - [Landon Fuller](http://landonf.bikemonkey.org), "Using Blocks". + - [Peter Steinberger](https://github.com/steipete) + - [Zach Waldowski](https://github.com/zwaldowski) + + @warning UIActionSheet is only available on a platform with UIKit. + */ +@interface UIActionSheet (BlocksKit) <UIActionSheetDelegate> + +///----------------------------------- +/// @name Creating action sheets +///----------------------------------- + +/** Creates and returns a new action sheet with only a title and cancel button. + + @param title The header of the action sheet. + @return A newly created action sheet. + */ ++ (id)actionSheetWithTitle:(NSString *)title; + +/** Returns a configured action sheet with only a title and cancel button. + + @param title The header of the action sheet. + @return An instantiated actionSheet. + */ +- (id)initWithTitle:(NSString *)title; + +///----------------------------------- +/// @name Adding buttons +///----------------------------------- + +/** Add a new button with an associated code block. + + @param title The text of the button. + @param block A block of code. + */ +- (NSInteger)addButtonWithTitle:(NSString *)title handler:(BKBlock)block; + +/** Set the destructive (red) button with an associated code block. + + @warning Because buttons cannot be removed from an action sheet, + be aware that the effects of calling this method are cumulative. + Previously added destructive buttons will become normal buttons. + + @param title The text of the button. + @param block A block of code. + */ +- (NSInteger)setDestructiveButtonWithTitle:(NSString *)title handler:(BKBlock)block; + +/** Set the title and trigger of the cancel button. + + `block` can be set to `nil`, but this is generally useless as + the cancel button is configured already to do nothing. + + iPhone users will have the button shown regardless; if the title is + set to `nil`, it will automatically be localized. + + @param title The text of the button. + @param block A block of code. + */ +- (NSInteger)setCancelButtonWithTitle:(NSString *)title handler:(BKBlock)block; + +///----------------------------------- +/// @name Altering actions +///----------------------------------- + +/** Sets the block that is to be fired when a button is pressed. + + @param block A code block, or nil to set no response. + @param index The index of a button already added to the action sheet. +*/ +- (void)setHandler:(BKBlock)block forButtonAtIndex:(NSInteger)index; + +/** The block that is to be fired when a button is pressed. + + @param index The index of a button already added to the action sheet. + @return A code block, or nil if no block is assigned. + */ +- (BKBlock)handlerForButtonAtIndex:(NSInteger)index; + +/** The block to be fired when the action sheet is dismissed with the cancel + button and/or action. + + This property performs the same action as setCancelButtonWithTitle:handler: + but with `title` set to nil. Contrary to setCancelButtonWithTitle:handler:, + you can set this property multiple times and multiple cancel buttons will + not be generated. + */ +@property (nonatomic, copy) BKBlock cancelBlock; + +/** The block to be fired before the action sheet will show. */ +@property (nonatomic, copy) void (^willShowBlock)(UIActionSheet *); + +/** The block to be fired when the action sheet shows. */ +@property (nonatomic, copy) void (^didShowBlock)(UIActionSheet *); + +/** The block to be fired before the action sheet will dismiss. */ +@property (nonatomic, copy) void (^willDismissBlock)(UIActionSheet *, NSInteger); + +/** The block to be fired after the action sheet dismisses. */ +@property (nonatomic, copy) void (^didDismissBlock)(UIActionSheet *, NSInteger); + +@end diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.m b/Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.m new file mode 100755 index 0000000..db619b1 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.m @@ -0,0 +1,160 @@ +// +// UIActionSheet+BlocksKit.m +// BlocksKit +// + +#import "UIActionSheet+BlocksKit.h" + +#pragma mark Custom delegate + +@interface A2DynamicUIActionSheetDelegate : A2DynamicDelegate + +@end + +@implementation A2DynamicUIActionSheetDelegate + +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(actionSheet:clickedButtonAtIndex:)]) + [realDelegate actionSheet:actionSheet clickedButtonAtIndex:buttonIndex]; + + id key = @(buttonIndex); + BKBlock block = (self.handlers)[key]; + if (block) + block(); +} + +- (void)willPresentActionSheet:(UIActionSheet *)actionSheet { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(willPresentActionSheet:)]) + [realDelegate willPresentActionSheet:actionSheet]; + + void (^block)(UIActionSheet *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(actionSheet); +} + +- (void)didPresentActionSheet:(UIActionSheet *)actionSheet { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(didPresentActionSheet:)]) + [realDelegate didPresentActionSheet:actionSheet]; + + void (^block)(UIActionSheet *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(actionSheet); +} + +- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(actionSheet:willDismissWithButtonIndex:)]) + [realDelegate actionSheet:actionSheet willDismissWithButtonIndex:buttonIndex]; + + void (^block)(UIActionSheet *, NSInteger) = [self blockImplementationForMethod:_cmd]; + if (block) + block(actionSheet, buttonIndex); +} + +- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(actionSheet:didDismissWithButtonIndex:)]) + [realDelegate actionSheet:actionSheet didDismissWithButtonIndex:buttonIndex]; + + void (^block)(UIActionSheet *, NSInteger) = [self blockImplementationForMethod:_cmd]; + if (block) + block(actionSheet, buttonIndex); +} + +- (void)actionSheetCancel:(UIActionSheet *)actionSheet { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(actionSheetCancel:)]) + [realDelegate actionSheetCancel:actionSheet]; + + BKBlock block = actionSheet.cancelBlock; + if (block) + block(); +} + +@end + +#pragma mark - Category + +@implementation UIActionSheet (BlocksKit) + +@dynamic willShowBlock, didShowBlock, willDismissBlock, didDismissBlock; + ++ (void)load { + @autoreleasepool { + [self registerDynamicDelegate]; + [self linkDelegateMethods: @{ + @"willShowBlock": @"willPresentActionSheet:", + @"didShowBlock": @"didPresentActionSheet:", + @"willDismissBlock": @"actionSheet:willDismissWithButtonIndex:", + @"didDismissBlock": @"actionSheet:didDismissWithButtonIndex:" + }]; + } +} + +#pragma mark Initializers + ++ (id)actionSheetWithTitle:(NSString *)title { + return [[[self class] alloc] initWithTitle:title]; +} + +- (id)initWithTitle:(NSString *)title { + return [self initWithTitle:title delegate:self.dynamicDelegate cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil]; +} + +#pragma mark Actions + +- (NSInteger)addButtonWithTitle:(NSString *)title handler:(BKBlock)block { + NSAssert(title.length, @"A button without a title cannot be added to an action sheet."); + NSInteger index = [self addButtonWithTitle:title]; + [self setHandler:block forButtonAtIndex:index]; + return index; +} + +- (NSInteger)setDestructiveButtonWithTitle:(NSString *)title handler:(BKBlock)block { + NSInteger index = [self addButtonWithTitle:title handler:block]; + self.destructiveButtonIndex = index; + return index; +} + +- (NSInteger)setCancelButtonWithTitle:(NSString *)title handler:(BKBlock)block { + NSInteger cancelButtonIndex = self.cancelButtonIndex; + + if ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) && !title.length) + title = NSLocalizedString(@"Cancel", nil); + + if (title.length) + cancelButtonIndex = [self addButtonWithTitle:title]; + + [self setHandler:block forButtonAtIndex:cancelButtonIndex]; + self.cancelButtonIndex = cancelButtonIndex; + return cancelButtonIndex; +} + +#pragma mark Properties + +- (void)setHandler:(BKBlock)block forButtonAtIndex:(NSInteger)index { + id key = @(index); + + if (block) + [self.dynamicDelegate handlers][key] = [block copy]; + else + [[self.dynamicDelegate handlers] removeObjectForKey:key]; +} + +- (BKBlock)handlerForButtonAtIndex:(NSInteger)index { + id key = @(index); + return [self.dynamicDelegate handlers][key]; +} + +- (BKBlock)cancelBlock { + return [self handlerForButtonAtIndex:self.cancelButtonIndex]; +} + +- (void)setCancelBlock:(BKBlock)block { + [self setHandler:block forButtonAtIndex:self.cancelButtonIndex]; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.h b/Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.h new file mode 100755 index 0000000..c2b2f56 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.h @@ -0,0 +1,134 @@ +// +// UIAlertView+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** UIAlertView without delegates! + + This set of extensions and convenience classes allows + for an instance of UIAlertView without the implementation + of a delegate. Any time you instantiate a UIAlertView + using the methods here, you must add buttons using + addButtonWithTitle:handler: otherwise nothing will happen. + + A typical invocation will go like this: + UIAlertView *testView = [UIAlertView alertViewWithTitle:@"Application Alert" message:@"This app will explode in 42 seconds."]; + [testView setCancelButtonWithTitle:@"Oh No!" handler:^{ NSLog(@"Boom!"); }]; + [testView show]; + + A more traditional, and more useful, modal dialog looks like so: + UIAlertView *testView = [UIAlertView alertViewWithTitle:@"Very important!" message:@"Do you like chocolate?"]; + [testView addButtonWithTitle:@"Yes" handler:^{ NSLog(@"Yay!"); }]; + [testView addButtonWithTitle:@"No" handler:^{ NSLog(@"We hate you."); }]; + [testView show]; + + Includes code by the following: + + - [Landon Fuller](http://landonf.bikemonkey.org), "Using Blocks". + - [Peter Steinberger](https://github.com/steipete) + - [Zach Waldowski](https://github.com/zwaldowski) + + @warning UIAlertView is only available on a platform with UIKit. + */ +@interface UIAlertView (BlocksKit) + +///----------------------------------- +/// @name Creating alert views +///----------------------------------- + +/** Creates and shows a new alert view with only a title, message, and cancel button. + + @param title The title of the alert view. + @param message The message content of the alert. + @param cancelButtonTitle The title of the cancel button. If both cancelButtonTitle and otherButtonTitles are empty or nil, defaults to a + @param otherButtonTitles Titles of additional buttons to add to the receiver. + @param block A block of code to be fired on the dismissal of the alert view. + */ ++ (void) showAlertViewWithTitle: (NSString *) title message: (NSString *) message cancelButtonTitle: (NSString *) cancelButtonTitle otherButtonTitles: (NSArray *) otherButtonTitles handler: (void (^)(UIAlertView *alertView, NSInteger buttonIndex)) block; + +/** Creates and returns a new alert view with only a title and cancel button. + + @param title The title of the alert view. + @return A newly created alert view. + */ ++ (id)alertViewWithTitle:(NSString *)title; + +/** Creates and returns a new alert view with only a title, message, and cancel button. + + @param title The title of the alert view. + @param message The message content of the alert. + @return A newly created alert view. + */ ++ (id)alertViewWithTitle:(NSString *)title message:(NSString *)message; + +/** Returns a configured alert view with only a title, message, and cancel button. + + @param title The title of the alert view. + @param message The message content of the alert. + @return An instantiated alert view. + */ +- (id)initWithTitle:(NSString *)title message:(NSString *)message; + +///----------------------------------- +/// @name Adding buttons +///----------------------------------- + +/** Add a new button with an associated code block. + + @param title The text of the button. + @param block A block of code. + */ +- (NSInteger)addButtonWithTitle:(NSString *)title handler:(BKBlock)block; + +/** Set the title and trigger of the cancel button. + + @param title The text of the button. + @param block A block of code. + */ +- (NSInteger)setCancelButtonWithTitle:(NSString *)title handler:(BKBlock)block; + +///----------------------------------- +/// @name Altering actions +///----------------------------------- + +/** Sets the block that is to be fired when a button is pressed. + + @param block A code block, or nil to set no response. + @param index The index of a button already added to the action sheet. + */ +- (void)setHandler:(BKBlock)block forButtonAtIndex:(NSInteger)index; + +/** The block that is to be fired when a button is pressed. + + @param index The index of the button already added to the alert view. + @return A code block, or nil if no block yet assigned. + */ +- (BKBlock)handlerForButtonAtIndex:(NSInteger)index; + +/** The block to be fired when the action sheet is dismissed with the cancel + button. + + Contrary to setCancelButtonWithTitle:handler:, you can set this + property multiple times but multiple cancel buttons will + not be generated. + */ +@property (nonatomic, copy) BKBlock cancelBlock; + +/** The block to be fired before the alert view will show. */ +@property (nonatomic, copy) void (^willShowBlock)(UIAlertView *); + +/** The block to be fired when the alert view shows. */ +@property (nonatomic, copy) void (^didShowBlock)(UIAlertView *); + +/** The block to be fired before the alert view will dismiss. */ +@property (nonatomic, copy) void (^willDismissBlock)(UIAlertView *, NSInteger); + +/** The block to be fired after the alert view dismisses. */ +@property (nonatomic, copy) void (^didDismissBlock)(UIAlertView *, NSInteger); + +/** The block to be fired to determine whether the first non-cancel should be enabled */ +@property (nonatomic, copy) BOOL (^shouldEnableFirstOtherButtonBlock)(UIAlertView *) NS_AVAILABLE_IOS(5_0); + +@end diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.m b/Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.m new file mode 100644 index 0000000..de20d3f --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.m @@ -0,0 +1,212 @@ +// +// UIAlertView+BlocksKit.m +// BlocksKit +// + +#import "NSArray+BlocksKit.h" +#import "UIAlertView+BlocksKit.h" + +#pragma mark Delegate + +@interface A2DynamicUIAlertViewDelegate : A2DynamicDelegate + +@end + +@implementation A2DynamicUIAlertViewDelegate + +- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView { + BOOL should = YES; + + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(alertViewShouldEnableFirstOtherButton:)]) + should &= [realDelegate alertViewShouldEnableFirstOtherButton:alertView]; + + BOOL (^block)(UIAlertView *) = [self blockImplementationForMethod:_cmd]; + if (block) + should &= block(alertView); + + return should; +} + +- (void)alertViewCancel:(UIAlertView *)alertView { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(alertViewCancel:)]) + [realDelegate alertViewCancel:alertView]; + + id key = @(alertView.cancelButtonIndex); + BKBlock cancelBlock = (self.handlers)[key]; + if (cancelBlock) + cancelBlock(); +} + +- (void)willPresentAlertView:(UIAlertView *)alertView { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(willPresentAlertView:)]) + [realDelegate willPresentAlertView:alertView]; + + void (^block)(UIAlertView *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(alertView); +} + +- (void)didPresentAlertView:(UIAlertView *)alertView { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(didPresentAlertView:)]) + [realDelegate didPresentAlertView:alertView]; + + void (^block)(UIAlertView *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(alertView); +} + +- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(alertView:willDismissWithButtonIndex:)]) + [realDelegate alertView:alertView willDismissWithButtonIndex:buttonIndex]; + + void (^block)(UIAlertView *, NSInteger) = [self blockImplementationForMethod:_cmd]; + if (block) + block(alertView, buttonIndex); +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(alertView:didDismissWithButtonIndex:)]) + [realDelegate alertView:alertView didDismissWithButtonIndex:buttonIndex]; + + void (^block)(UIAlertView *, NSInteger) = [self blockImplementationForMethod:_cmd]; + if (block) + block(alertView, buttonIndex); +} + +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) + [realDelegate alertView:alertView clickedButtonAtIndex:buttonIndex]; + + void (^block)(UIAlertView *, NSInteger) = [self blockImplementationForMethod:_cmd]; + if (block) + block(alertView, buttonIndex); + + id key = @(buttonIndex); + BKBlock buttonBlock = (self.handlers)[key]; + if (buttonBlock) + buttonBlock(); +} + +@end + +#pragma mark - Category + +@implementation UIAlertView (BlocksKit) + +@dynamic willShowBlock, didShowBlock, willDismissBlock, didDismissBlock, shouldEnableFirstOtherButtonBlock; + ++ (void)load { + @autoreleasepool { + [self registerDynamicDelegate]; + [self linkDelegateMethods: @{ + @"willShowBlock": @"willPresentAlertView:", + @"didShowBlock": @"didPresentAlertView:", + @"willDismissBlock": @"alertView:willDismissWithButtonIndex:", + @"didDismissBlock": @"alertView:didDismissWithButtonIndex:", + @"shouldEnableFirstOtherButtonBlock": @"alertViewShouldEnableFirstOtherButton:" + }]; + } +} + +#pragma mark Convenience + ++ (void) showAlertViewWithTitle: (NSString *) title message: (NSString *) message cancelButtonTitle: (NSString *) cancelButtonTitle otherButtonTitles: (NSArray *) otherButtonTitles handler: (void (^)(UIAlertView *, NSInteger)) block +{ + UIAlertView *alertView = [[self class] alertViewWithTitle: title message: message]; + + // Set other buttons + if (otherButtonTitles.count) + { + NSUInteger firstOtherButton = [alertView addButtonWithTitle: otherButtonTitles[0]]; + [alertView setValue: @(firstOtherButton) forKey: @"firstOtherButton"]; + + otherButtonTitles = [otherButtonTitles subarrayWithRange: NSMakeRange(1, otherButtonTitles.count - 1)]; + [otherButtonTitles each: ^(NSString *button) { + [alertView addButtonWithTitle: button]; + }]; + } + + // If no buttons were specified, cancel button becomes "Dismiss" + if (!cancelButtonTitle.length && !otherButtonTitles.count) + cancelButtonTitle = NSLocalizedString(@"Dismiss", nil); + + // Set cancel button + if (cancelButtonTitle.length) + alertView.cancelButtonIndex = [alertView addButtonWithTitle: cancelButtonTitle]; + + // Set `didDismissBlock` + if (block) alertView.didDismissBlock = block; + + // Show alert view + [alertView show]; +} + +#pragma mark Initializers + ++ (id)alertViewWithTitle:(NSString *)title { + return [self alertViewWithTitle:title message:nil]; +} + ++ (id)alertViewWithTitle:(NSString *)title message:(NSString *)message { + return [[[self class] alloc] initWithTitle:title message:message]; +} + +- (id)initWithTitle:(NSString *)title message:(NSString *)message { + return [self initWithTitle:title message:message delegate:self.dynamicDelegate cancelButtonTitle:nil otherButtonTitles:nil]; +} + +#pragma Actions + +- (NSInteger)addButtonWithTitle:(NSString *)title handler:(BKBlock)block { + NSAssert(title.length, @"A button without a title cannot be added to the alert view."); + NSInteger index = [self addButtonWithTitle:title]; + [self setHandler:block forButtonAtIndex:index]; + return index; +} + +- (NSInteger)setCancelButtonWithTitle:(NSString *)title handler:(BKBlock)block { + if (!title.length) + title = NSLocalizedString(@"Cancel", nil); + NSInteger cancelButtonIndex = [self addButtonWithTitle:title]; + self.cancelButtonIndex = cancelButtonIndex; + [self setHandler:block forButtonAtIndex:cancelButtonIndex]; + return cancelButtonIndex; +} + +#pragma mark Properties + +- (void)setHandler:(BKBlock)block forButtonAtIndex:(NSInteger)index { + id key = @(index); + + if (block) + [self.dynamicDelegate handlers][key] = [block copy]; + else + [[self.dynamicDelegate handlers] removeObjectForKey: key]; +} + +- (BKBlock)handlerForButtonAtIndex:(NSInteger)index { + id key = @(index); + return [self.dynamicDelegate handlers][key]; +} + +- (BKBlock)cancelBlock { + return [self handlerForButtonAtIndex:self.cancelButtonIndex]; +} + +- (void)setCancelBlock:(BKBlock)block { + if (block && self.cancelButtonIndex == -1) { + [self setCancelButtonWithTitle:nil handler:block]; + return; + } + + [self setHandler:block forButtonAtIndex:self.cancelButtonIndex]; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIBarButtonItem+BlocksKit.h b/Pods/BlocksKit/BlocksKit/UIKit/UIBarButtonItem+BlocksKit.h new file mode 100755 index 0000000..bbd1b8d --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIBarButtonItem+BlocksKit.h @@ -0,0 +1,51 @@ +// +// UIBarButtonItem+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block event initialization for UIBarButtonItem. + + This set of extensions has near-drop-in replacements + for the standard set of UIBarButton item initializations, + using a block handler instead of a target/selector. + + Includes code by the following: + + - [Kevin O'Neill](https://github.com/kevinoneill) + - [Zach Waldowski](https://github.com/zwaldowski) + + @warning UIBarButtonItem is only available on a platform with UIKit. + */ +@interface UIBarButtonItem (BlocksKit) + +/** Creates and returns a configured item containing the specified system item. + + @return Newly initialized item with the specified properties. + @param systemItem The system item to use as the item representation. One of the constants defined in UIBarButtonSystemItem. + @param action The block that gets fired on the button press. + */ +- (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem handler:(BKSenderBlock)action; + +/** Creates and returns a configured item using the specified image and style. + + @return Newly initialized item with the specified properties. + @param image The item’s image. If nil an image is not displayed. + If this image is too large to fit on the bar, it is scaled to fit + The size of a toolbar and navigation bar image is 20 x 20 points. + @param style The style of the item. One of the constants defined in UIBarButtonItemStyle. + @param action The block that gets fired on the button press. + */ +- (id)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style handler:(BKSenderBlock)action; + +/** Creates and returns a configured item using the specified text and style. + + @return Newly initialized item with the specified properties. + @param title The text displayed on the button item. + @param style The style of the item. One of the constants defined in UIBarButtonItemStyle. + @param action The block that gets fired on the button press. + */ +- (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style handler:(BKSenderBlock)action; + +@end diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIBarButtonItem+BlocksKit.m b/Pods/BlocksKit/BlocksKit/UIKit/UIBarButtonItem+BlocksKit.m new file mode 100755 index 0000000..89a03f6 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIBarButtonItem+BlocksKit.m @@ -0,0 +1,41 @@ +// +// UIBarButtonItem+BlocksKit.m +// BlocksKit +// + +#import "UIBarButtonItem+BlocksKit.h" +#import "NSObject+AssociatedObjects.h" + +static char kBarButtonItemBlockKey; + +@interface UIBarButtonItem (BlocksKitPrivate) +- (void)_handleAction:(UIBarButtonItem *)sender; +@end + +@implementation UIBarButtonItem (BlocksKit) + +- (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem handler:(BKSenderBlock)action { + self = [self initWithBarButtonSystemItem:systemItem target:self action:@selector(_handleAction:)]; + [self associateCopyOfValue:action withKey:&kBarButtonItemBlockKey]; + return self; +} + +- (id)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style handler:(BKSenderBlock)action { + self = [self initWithImage:image style:style target:self action:@selector(_handleAction:)]; + [self associateCopyOfValue:action withKey:&kBarButtonItemBlockKey]; + return self; +} + +- (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style handler:(BKSenderBlock)action { + self = [self initWithTitle:title style:style target:self action:@selector(_handleAction:)]; + [self associateCopyOfValue:action withKey:&kBarButtonItemBlockKey]; + return self; +} + +- (void)_handleAction:(UIBarButtonItem *)sender { + BKSenderBlock block = [self associatedValueForKey:&kBarButtonItemBlockKey]; + if (block) + block(self); +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIControl+BlocksKit.h b/Pods/BlocksKit/BlocksKit/UIKit/UIControl+BlocksKit.h new file mode 100755 index 0000000..c7c7af6 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIControl+BlocksKit.h @@ -0,0 +1,44 @@ +// +// UIControl+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block control event handling for UIControl. + + Includes code by the following: + + - [Kevin O'Neill](https://github.com/kevinoneill) + - [Zach Waldowski](https://github.com/zwaldowski) + + @warning UIControl is only available on a platform with UIKit. + */ +@interface UIControl (BlocksKit) + +///----------------------------------- +/// @name Block event handling +///----------------------------------- + +/** Adds a block for a particular event to an internal dispatch table. + + @param handler A block representing an action message, with an argument for the sender. + @param controlEvents A bitmask specifying the control events for which the action message is sent. + @see removeEventHandlersForControlEvents: + */ +- (void)addEventHandler:(BKSenderBlock)handler forControlEvents:(UIControlEvents)controlEvents; + +/** Removes all blocks for a particular event combination. + @param controlEvents A bitmask specifying the control events for which the block will be removed. + @see addEventHandler:forControlEvents: + */ +- (void)removeEventHandlersForControlEvents:(UIControlEvents)controlEvents; + +/** Checks to see if the control has any blocks for a particular event combination. + @param controlEvents A bitmask specifying the control events for which to check for blocks. + @see addEventHandler:forControlEvents: + @return Returns YES if there are blocks for these control events, NO otherwise. + */ +- (BOOL)hasEventHandlersForControlEvents:(UIControlEvents)controlEvents; + +@end diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIControl+BlocksKit.m b/Pods/BlocksKit/BlocksKit/UIKit/UIControl+BlocksKit.m new file mode 100644 index 0000000..054178c --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIControl+BlocksKit.m @@ -0,0 +1,103 @@ +// +// UIControl+BlocksKit.m +// BlocksKit +// + +#import "UIControl+BlocksKit.h" +#import "NSObject+AssociatedObjects.h" +#import "NSSet+BlocksKit.h" + +static char kControlHandlersKey; + +#pragma mark Private + +@interface BKControlWrapper : NSObject <NSCopying> + +- (id)initWithHandler:(BKSenderBlock)handler forControlEvents:(UIControlEvents)controlEvents; +@property (nonatomic, copy) BKSenderBlock handler; +@property (nonatomic) UIControlEvents controlEvents; + +@end + +@implementation BKControlWrapper + +- (id)initWithHandler:(BKSenderBlock)handler forControlEvents:(UIControlEvents)controlEvents { + if ((self = [super init])) { + self.handler = handler; + self.controlEvents = controlEvents; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + return [[BKControlWrapper alloc] initWithHandler:self.handler forControlEvents:self.controlEvents]; +} + +- (void)invoke:(id)sender { + self.handler(sender); +} + +@end + +#pragma mark Category + +@implementation UIControl (BlocksKit) + +- (void)addEventHandler:(BKSenderBlock)handler forControlEvents:(UIControlEvents)controlEvents { + NSParameterAssert(handler); + + NSMutableDictionary *events = [self associatedValueForKey:&kControlHandlersKey]; + if (!events) { + events = [NSMutableDictionary dictionary]; + [self associateValue:events withKey:&kControlHandlersKey]; + } + + NSNumber *key = @(controlEvents); + NSMutableSet *handlers = events[key]; + if (!handlers) { + handlers = [NSMutableSet set]; + events[key] = handlers; + } + + BKControlWrapper *target = [[BKControlWrapper alloc] initWithHandler:handler forControlEvents:controlEvents]; + [handlers addObject:target]; + [self addTarget:target action:@selector(invoke:) forControlEvents:controlEvents]; +} + +- (void)removeEventHandlersForControlEvents:(UIControlEvents)controlEvents { + NSMutableDictionary *events = [self associatedValueForKey:&kControlHandlersKey]; + if (!events) { + events = [NSMutableDictionary dictionary]; + [self associateValue:events withKey:&kControlHandlersKey]; + } + + NSNumber *key = @(controlEvents); + NSSet *handlers = events[key]; + + if (!handlers) + return; + + [handlers each:^(id sender) { + [self removeTarget:sender action:NULL forControlEvents:controlEvents]; + }]; + + [events removeObjectForKey:key]; +} + +- (BOOL)hasEventHandlersForControlEvents:(UIControlEvents)controlEvents { + NSMutableDictionary *events = [self associatedValueForKey:&kControlHandlersKey]; + if (!events) { + events = [NSMutableDictionary dictionary]; + [self associateValue:events withKey:&kControlHandlersKey]; + } + + NSNumber *key = @(controlEvents); + NSSet *handlers = events[key]; + + if (!handlers) + return NO; + + return !!handlers.count; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIGestureRecognizer+BlocksKit.h b/Pods/BlocksKit/BlocksKit/UIKit/UIGestureRecognizer+BlocksKit.h new file mode 100755 index 0000000..b8b95ea --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIGestureRecognizer+BlocksKit.h @@ -0,0 +1,114 @@ +// +// UIGestureRecognizer+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block functionality for UIGestureRecognizer. + + Use of the delay property is pretty straightforward, although + cancellation might be a little harder to swallow. An example + follows: + UITapGestureRecognizer *singleTap = [UITapGestureRecognizer recognizerWithHandler:^(id sender) { + NSLog(@"Single tap."); + } delay:0.18]; + [self addGestureRecognizer:singleTap]; + + UITapGestureRecognizer *doubleTap = [UITapGestureRecognizer recognizerWithHandler:^(id sender) { + [singleTap cancel]; + NSLog(@"Double tap."); + }]; + doubleTap.numberOfTapsRequired = 2; + [self addGestureRecognizer:doubleTap]; + + Believe it or not, the above code is fully memory-safe and efficient. Eagle-eyed coders + will notice that this setup emulates UIGestureRecognizer's requireGestureRecognizerToFail:, + and, yes, it totally apes it. Not only is this setup much faster on the user's end of + things, it is more flexible and allows for much more complicated setups. + + Includes code by the following: + + - [Kevin O'Neill](https://github.com/kevinoneill) + - [Zach Waldowski](https://github.com/zwaldowski) + + @warning UIGestureRecognizer is only available on a platform with UIKit. + + @warning It is not recommended to use the Apple-supplied locationInView and state + methods on a *delayed* block-backed gesture recognizer, as these properties are + likely to have been cleared by the time by the block fires. It is instead recommended + to use the arguments provided to the block. + */ + +@interface UIGestureRecognizer (BlocksKit) + +/** An autoreleased gesture recognizer that will, on firing, call + the given block asynchronously after a number of seconds. + + @return An autoreleased instance of a concrete UIGestureRecognizer subclass, or `nil`. + @param block The block which handles an executed gesture. + @param delay A number of seconds after which the block will fire. + */ ++ (id)recognizerWithHandler:(BKGestureRecognizerBlock)block delay:(NSTimeInterval)delay; + +/** Initializes an allocated gesture recognizer that will call the given block + after a given delay. + + An alternative to the designated initializer. + + @return An initialized instance of a concrete UIGestureRecognizer subclass or `nil`. + @param block The block which handles an executed gesture. + @param delay A number of seconds after which the block will fire. + */ +- (id)initWithHandler:(BKGestureRecognizerBlock)block delay:(NSTimeInterval)delay; + +/** An autoreleased gesture recognizer that will call the given block. + + For convenience and compatibility reasons, this method is indentical + to using recognizerWithHandler:delay: with a delay of 0.0. + + @return An initialized and autoreleased instance of a concrete UIGestureRecognizer + subclass, or `nil`. + @param block The block which handles an executed gesture. + */ ++ (id)recognizerWithHandler:(BKGestureRecognizerBlock)block; + +/** Initializes an allocated gesture recognizer that will call the given block. + + This method is indentical to calling initWithHandler:delay: with a delay of 0.0. + + @return An initialized instance of a concrete UIGestureRecognizer subclass or `nil`. + @param block The block which handles an executed gesture. + */ +- (id)initWithHandler:(BKGestureRecognizerBlock)block; + +/** Allows the block that will be fired by the gesture recognizer + to be modified after the fact. + */ +@property (nonatomic, copy) BKGestureRecognizerBlock handler; + +/** Allows the length of the delay after which the gesture + recognizer will be fired to modify. */ +@property (nonatomic) NSTimeInterval handlerDelay; + +/** Allows the length of the delay after which the gesture + recognizer will be fired to modify. + + @warning Due to a collision with an internal method in + UILongPressGestureRecognizer, this method was replaced + with handlerDelay starting in BlocksKit 1.0.5. + + */ +@property (nonatomic) NSTimeInterval delay DEPRECATED_ATTRIBUTE_M("Use handlerDelay"); + +/** If the recognizer happens to be fired, calling this method + will stop it from firing, but only if a delay is set. + + @warning This method is not for arbitrarily canceling the + firing of a recognizer, but will only function for a block + handler *after the recognizer has already been fired*. Be + sure to make your delay times accomodate this likelihood. + */ +- (void)cancel; + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIGestureRecognizer+BlocksKit.m b/Pods/BlocksKit/BlocksKit/UIKit/UIGestureRecognizer+BlocksKit.m new file mode 100755 index 0000000..28ceed7 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIGestureRecognizer+BlocksKit.m @@ -0,0 +1,90 @@ +// +// UIGestureRecognizer+BlocksKit.m +// BlocksKit +// + +#import "UIGestureRecognizer+BlocksKit.h" +#import "NSObject+AssociatedObjects.h" +#import "NSObject+BlocksKit.h" + +static char kGestureRecognizerBlockKey; +static char kGestureRecognizerDelayKey; +static char kGestureRecognizerCancelKey; + +@interface UIGestureRecognizer (BlocksKitInternal) +- (void)_handleAction:(UIGestureRecognizer *)recognizer; +@end + +@implementation UIGestureRecognizer (BlocksKit) + ++ (id)recognizerWithHandler:(BKGestureRecognizerBlock)block delay:(NSTimeInterval)delay { + return [[[self class] alloc] initWithHandler:block delay:delay]; +} + +- (id)initWithHandler:(BKGestureRecognizerBlock)block delay:(NSTimeInterval)delay { + if ((self = [self initWithTarget:self action:@selector(_handleAction:)])) { + self.handler = block; + self.handlerDelay = delay; + } + return self; +} + ++ (id)recognizerWithHandler:(BKGestureRecognizerBlock)block { + return [self recognizerWithHandler:block delay:0.0]; +} + +- (id)initWithHandler:(BKGestureRecognizerBlock)block { + return [self initWithHandler:block delay:0.0]; +} + +- (void)_handleAction:(UIGestureRecognizer *)recognizer { + BKGestureRecognizerBlock handler = recognizer.handler; + if (!handler) + return; + + NSTimeInterval delay = self.handlerDelay; + CGPoint location = [self locationInView:self.view]; + BKBlock block = ^{ + handler(self, self.state, location); + }; + + if (!delay) { + block(); + return; + } + + id cancel = [NSObject performBlock:block afterDelay:delay]; + [self associateCopyOfValue:cancel withKey:&kGestureRecognizerCancelKey]; +} + +- (void)setHandler:(BKGestureRecognizerBlock)handler { + [self associateCopyOfValue:handler withKey:&kGestureRecognizerBlockKey]; +} + +- (BKGestureRecognizerBlock)handler { + return [self associatedValueForKey:&kGestureRecognizerBlockKey]; +} + +- (void)setHandlerDelay:(NSTimeInterval)delay { + NSNumber *delayValue = delay ? @(delay) : nil; + [self associateValue:delayValue withKey:&kGestureRecognizerDelayKey]; +} + +- (NSTimeInterval)handlerDelay { + NSNumber *delay = [self associatedValueForKey:&kGestureRecognizerDelayKey]; + return delay ? [delay doubleValue] : 0.0; +} + +- (void)setDelay:(NSTimeInterval)delay { + [self setHandlerDelay:delay]; +} + +- (NSTimeInterval)delay { + return [self handlerDelay]; +} + +- (void)cancel { + [NSObject cancelBlock:[self associatedValueForKey:&kGestureRecognizerCancelKey]]; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIPopoverController+BlocksKit.h b/Pods/BlocksKit/BlocksKit/UIKit/UIPopoverController+BlocksKit.h new file mode 100644 index 0000000..266b34c --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIPopoverController+BlocksKit.h @@ -0,0 +1,22 @@ +// +// UIPopoverController+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block functionality for UIPopoverController. + + Created by [Alexsander Akers](https://github.com/a2) and contributed to BlocksKit. + + @warning UIPopovercontroller is only available on a platform with UIKit. + */ +@interface UIPopoverController (BlocksKit) + +/** The block to be called when the popover controller will dismiss the popover. Return NO to prevent the dismissal of the view. */ +@property (nonatomic, copy) BOOL (^shouldDismissBlock)(UIPopoverController *); + +/** The block to be called when the user has taken action to dismiss the popover. This is not called when -dismissPopoverAnimated: is called directly. */ +@property (nonatomic, copy) void (^didDismissBlock)(UIPopoverController *); + +@end diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIPopoverController+BlocksKit.m b/Pods/BlocksKit/BlocksKit/UIKit/UIPopoverController+BlocksKit.m new file mode 100644 index 0000000..59b7b94 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIPopoverController+BlocksKit.m @@ -0,0 +1,57 @@ +// +// UIPopoverController+BlocksKit.m +// BlocksKit +// + +#import "UIPopoverController+BlocksKit.h" + +#pragma mark - Delegate + +@interface A2DynamicUIPopoverControllerDelegate : A2DynamicDelegate + +@end + +@implementation A2DynamicUIPopoverControllerDelegate + +- (BOOL) popoverControllerShouldDismissPopover: (UIPopoverController *) popoverController +{ + BOOL should = YES; + + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector: @selector(popoverControllerShouldDismissPopover:)]) + should &= [realDelegate popoverControllerShouldDismissPopover: popoverController]; + + BOOL (^block)(UIPopoverController *) = [self blockImplementationForMethod: _cmd]; + if (block) should &= block(popoverController); + + return should; +} + +- (void) popoverControllerDidDismissPopover: (UIPopoverController *) popoverController +{ + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector: @selector(popoverControllerDidDismissPopover:)]) + [realDelegate popoverControllerDidDismissPopover: popoverController]; + + void (^block)(UIPopoverController *) = [self blockImplementationForMethod: _cmd]; + if (block) block(popoverController); +} + +@end + +#pragma mark - Category + +@implementation UIPopoverController (BlocksKit) + +@dynamic didDismissBlock, shouldDismissBlock; + ++ (void) load +{ + @autoreleasepool + { + [self registerDynamicDelegate]; + [self linkDelegateMethods: @{ @"didDismissBlock": @"popoverControllerDidDismissPopover:", @"shouldDismissBlock": @"popoverControllerShouldDismissPopover:" }]; + } +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIView+BlocksKit.h b/Pods/BlocksKit/BlocksKit/UIKit/UIView+BlocksKit.h new file mode 100755 index 0000000..7f976b4 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIView+BlocksKit.h @@ -0,0 +1,92 @@ +// +// UIView+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Convenience on-touch methods for UIView. + + Includes code by the following: + + - Kevin O'Neill. <https://github.com/kevinoneill>. 2011. BSD. + - Jake Marsh. <https://github.com/jakemarsh>. 2011. + - Zach Waldowski. <https://github.com/zwaldowski>. 2011. + + @warning UIView is only available on a platform with UIKit. + */ +@interface UIView (BlocksKit) + +/** Abstract creation of a block-backed UITapGestureRecognizer. + + This method allows for the recognition of any arbitrary number + of fingers tapping any number of times on a view. An instance + of UITapGesture recognizer is allocated for the block and added + to the recieving view. + + @warning This method has an _additive_ effect. Do not call it multiple + times to set-up or tear-down. The view will discard the gesture recognizer + on release. + + @param numberOfTouches The number of fingers tapping that will trigger the block. + @param numberOfTaps The number of taps required to trigger the block. + @param block The handler for the UITapGestureRecognizer + @see whenTapped: + @see whenDoubleTapped: + */ +- (void)whenTouches:(NSUInteger)numberOfTouches tapped:(NSUInteger)numberOfTaps handler:(BKBlock)block; + +/** Adds a recognizer for one finger tapping once. + + @warning This method has an _additive_ effect. Do not call it multiple + times to set-up or tear-down. The view will discard the gesture recognizer + on release. + + @param block The handler for the tap recognizer + @see whenDoubleTapped: + @see whenTouches:tapped:handler: + */ +- (void)whenTapped:(BKBlock)block; + +/** Adds a recognizer for one finger tapping twice. + + @warning This method has an _additive_ effect. Do not call it multiple + times to set-up or tear-down. The view will discard the gesture recognizer + on release. + + @param block The handler for the tap recognizer + @see whenTapped: + @see whenTouches:tapped:handler: + */ +- (void)whenDoubleTapped:(BKBlock)block; + +/** A convenience wrapper that non-recursively loops through the subviews of a view. + + @param block A code block that interacts with a UIView sender. + */ +- (void)eachSubview:(void(^)(UIView *))block; + +/** The block that gets called on a finger down. + + Internally, this method overrides the touchesBegan:withEvent: + selector of UIView and is mechanically similar to + UIControlEventTouchDown. + */ +@property (nonatomic, copy) BKTouchBlock onTouchDownBlock; + +/** The block that gets called on a finger drag. + + Internally, this method overrides the touchesMoved:withEvent: + selector of UIView. + */ +@property (nonatomic, copy) BKTouchBlock onTouchMoveBlock; + +/** The block that gets called on a finger up. + + Internally, this method overrides the touchesBegan:withEvent: + selector of UIView and is mechanically similar to + UIControlEventTouchCancel. + */ +@property (nonatomic, copy) BKTouchBlock onTouchUpBlock; + +@end diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIView+BlocksKit.m b/Pods/BlocksKit/BlocksKit/UIKit/UIView+BlocksKit.m new file mode 100755 index 0000000..520378f --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIView+BlocksKit.m @@ -0,0 +1,101 @@ +// +// UIView+BlocksKit.m +// BlocksKit +// + +#import "UIView+BlocksKit.h" +#import "NSObject+AssociatedObjects.h" +#import "UIGestureRecognizer+BlocksKit.h" +#import "NSArray+BlocksKit.h" + +static char kViewTouchDownBlockKey; +static char kViewTouchMoveBlockKey; +static char kViewTouchUpBlockKey; + +@implementation UIView (BlocksKit) + +- (void)whenTouches:(NSUInteger)numberOfTouches tapped:(NSUInteger)numberOfTaps handler:(BKBlock)block { + if (!block) + return; + + UITapGestureRecognizer *gesture = [UITapGestureRecognizer recognizerWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) { + if (state == UIGestureRecognizerStateRecognized) block(); + }]; + + [gesture setNumberOfTouchesRequired:numberOfTouches]; + [gesture setNumberOfTapsRequired:numberOfTaps]; + + [[self.gestureRecognizers select:^BOOL(id obj) { + if ([obj isKindOfClass:[UITapGestureRecognizer class]]) { + BOOL rightTouches = ([(UITapGestureRecognizer *)obj numberOfTouchesRequired] == numberOfTouches); + BOOL rightTaps = ([(UITapGestureRecognizer *)obj numberOfTapsRequired] == numberOfTaps); + return (rightTouches && rightTaps); + } + return NO; + }] each:^(id obj) { + [gesture requireGestureRecognizerToFail:(UITapGestureRecognizer *)obj]; + }]; + + [self addGestureRecognizer:gesture]; +} + +- (void)whenTapped:(BKBlock)block { + [self whenTouches:1 tapped:1 handler:block]; +} + +- (void)whenDoubleTapped:(BKBlock)block { + [self whenTouches:2 tapped:1 handler:block]; +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [super touchesBegan:touches withEvent:event]; + BKTouchBlock block = [self associatedValueForKey:&kViewTouchDownBlockKey]; + if (block) + block(touches, event); +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + [super touchesMoved:touches withEvent:event]; + BKTouchBlock block = [self associatedValueForKey:&kViewTouchMoveBlockKey]; + if (block) + block(touches, event); +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [super touchesEnded:touches withEvent:event]; + BKTouchBlock block = [self associatedValueForKey:&kViewTouchUpBlockKey]; + if (block) + block(touches, event); +} + +- (void)eachSubview:(void(^)(UIView *))block { + [self.subviews each:(BKSenderBlock)block]; +} + +#pragma mark Properties + +- (void)setOnTouchDownBlock:(BKTouchBlock)block { + [self associateCopyOfValue:block withKey:&kViewTouchDownBlockKey]; +} + +- (BKTouchBlock)onTouchDownBlock { + return [self associatedValueForKey:&kViewTouchDownBlockKey]; +} + +- (void)setOnTouchMoveBlock:(BKTouchBlock)block { + [self associateCopyOfValue:block withKey:&kViewTouchMoveBlockKey]; +} + +- (BKTouchBlock)onTouchMoveBlock { + return [self associatedValueForKey:&kViewTouchMoveBlockKey]; +} + +- (void)setOnTouchUpBlock:(BKTouchBlock)block { + [self associateCopyOfValue:block withKey:&kViewTouchUpBlockKey]; +} + +- (BKTouchBlock)onTouchUpBlock { + return [self associatedValueForKey:&kViewTouchUpBlockKey]; +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIWebView+BlocksKit.h b/Pods/BlocksKit/BlocksKit/UIKit/UIWebView+BlocksKit.h new file mode 100755 index 0000000..64247c2 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIWebView+BlocksKit.h @@ -0,0 +1,31 @@ +// +// UIWebView+BlocksKit.h +// BlocksKit +// + +#import "BKGlobals.h" + +/** Block callbacks for UIWebView. + + @warning UIWebView is only available on a platform with UIKit. +*/ + +@interface UIWebView (BlocksKit) + +/** The block to be decide whether a URL will be loaded. + + @warning If the delegate implements webView:shouldStartLoadWithRequest:navigationType:, + the return values of both the delegate method and the block will be considered. +*/ +@property (nonatomic, copy) BOOL(^shouldStartLoadBlock)(UIWebView *, NSURLRequest *, UIWebViewNavigationType); + +/** The block that is fired when the web view starts loading. */ +@property (nonatomic, copy) void(^didStartLoadBlock)(UIWebView *); + +/** The block that is fired when the web view finishes loading. */ +@property (nonatomic, copy) void(^didFinishLoadBlock)(UIWebView *); + +/** The block that is fired when the web view stops loading due to an error. */ +@property (nonatomic, copy) void(^didFinishWithErrorBlock)(UIWebView *, NSError *); + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/BlocksKit/UIKit/UIWebView+BlocksKit.m b/Pods/BlocksKit/BlocksKit/UIKit/UIWebView+BlocksKit.m new file mode 100755 index 0000000..c7ce644 --- /dev/null +++ b/Pods/BlocksKit/BlocksKit/UIKit/UIWebView+BlocksKit.m @@ -0,0 +1,79 @@ +// +// UIWebView+BlocksKit.m +// BlocksKit +// + +#import "UIWebView+BlocksKit.h" + +#pragma mark Custom delegate + +@interface A2DynamicUIWebViewDelegate : A2DynamicDelegate +@end + +@implementation A2DynamicUIWebViewDelegate + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { + BOOL ret = YES; + + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(webView:shouldStartLoadWithRequest:navigationType:)]) + ret = [realDelegate webView:webView shouldStartLoadWithRequest:request navigationType:navigationType]; + + BOOL (^block)(UIWebView *, NSURLRequest *, UIWebViewNavigationType) = [self blockImplementationForMethod:_cmd]; + if (block) + ret &= block(webView, request, navigationType); + + return ret; +} + +- (void)webViewDidStartLoad:(UIWebView *)webView { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(webViewDidStartLoad:)]) + [realDelegate webViewDidStartLoad:webView]; + + void(^block)(UIWebView *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(webView); +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(webViewDidFinishLoad:)]) + [realDelegate webViewDidFinishLoad:webView]; + + void(^block)(UIWebView *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(webView); +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { + id realDelegate = self.realDelegate; + if (realDelegate && [realDelegate respondsToSelector:@selector(webView:didFailLoadWithError:)]) + [realDelegate webView:webView didFailLoadWithError:error]; + + void(^block)(UIWebView *, NSError *) = [self blockImplementationForMethod:_cmd]; + if (block) + block(webView, error); +} + +@end + +#pragma mark Category + +@implementation UIWebView (BlocksKit) + +@dynamic shouldStartLoadBlock, didStartLoadBlock, didFinishLoadBlock, didFinishWithErrorBlock; + ++ (void)load { + @autoreleasepool { + [self registerDynamicDelegate]; + [self linkDelegateMethods: @{ + @"shouldStartLoadBlock": @"webView:shouldStartLoadWithRequest:navigationType:", + @"didStartLoadBlock": @"webViewDidStartLoad:", + @"didFinishLoadBlock": @"webViewDidFinishLoad:", + @"didFinishWithErrorBlock": @"webView:didFailLoadWithError:" + }]; + } +} + +@end
\ No newline at end of file diff --git a/Pods/BlocksKit/LICENSE b/Pods/BlocksKit/LICENSE new file mode 100644 index 0000000..f79ee06 --- /dev/null +++ b/Pods/BlocksKit/LICENSE @@ -0,0 +1,12 @@ +// +// LICENSE +// BlocksKit +// + +Copyright (c) 2011-2012 Zachary Waldowski, Alexsander Akers, and the BlocksKit Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/Pods/BlocksKit/README.md b/Pods/BlocksKit/README.md new file mode 100755 index 0000000..850e863 --- /dev/null +++ b/Pods/BlocksKit/README.md @@ -0,0 +1,34 @@ +[BlocksKit](http://pandamonia.github.com/BlocksKit) +=================================================== + +Blocks in C and Objective-C are downright magical. They make coding easier and potentially quicker, not to mention faster on the front end with multithreading and Grand Central Dispatch. BlocksKit hopes to facilitate this kind of programming by removing some of the annoying - and, in some cases, impeding - limits on coding with blocks. + +BlocksKit is a framework for OS X Lion and newer and a static library for iOS 5 and newer. + +Installation +============ + +BlocksKit can be added to a project using [CocoaPods](https://github.com/cocoapods/cocoapods). We also distribute a static library build. + +### Library + +* Download a release of BlocksKit. +* Move libBlocksKit.a and Headers to your project's folder, preferably a subfolder like "Vendor". +* In "Build Phases", Drag libBlocksKit.a into your target's "Link Binary With Libraries" build phase. +* In the build settings of your target or project, change "Other Linker Flags" to `-ObjC -all_load`. Make sure your app is linked with CoreGraphics, Foundation, MessageUI, and UIKit. +* Change (or add) to "Header Search Paths" the relative path to BlocksKit's headers, like `$(SRCROOT)/Vendor/Headers`. +* Insert `#import <BlocksKit/BlocksKit.h>`` in your project's prefix header. + +Documentation +============= + +An Xcode 4 compatible documentation set is available [using this Atom link](http://pandamonia.github.com/BlocksKit/us.pandamonia.BlocksKit.atom). You may also view the documentation [online](http://pandamonia.github.com/BlocksKit/Documentation). + +License +======= + +BlocksKit is created and maintained by [Pandamonia LLC](https://github.com/pandamonia) under the MIT license. **The project itself is free for use in any and all projects.** You can use BlocksKit in any project, public or private, with or without attribution - though we prefer attribution! It helps us. + +Unsure about your rights? [Read more.](http://pandamonia.github.com/BlocksKit/index.html#license) + +Individual credits for included code exist in the header files and documentation. We thank them for their contributions to the open source community.
\ No newline at end of file |
