Showing preview only (614K chars total). Download the full file or copy to clipboard to get everything.
Repository: wangyingbo/YBPasterImage
Branch: master
Commit: d4eea364aaf2
Files: 188
Total size: 550.8 KB
Directory structure:
gitextract_v1bw8za9/
├── Podfile
├── Pods/
│ ├── BlocksKit/
│ │ ├── BlocksKit/
│ │ │ ├── BlocksKit+MessageUI.h
│ │ │ ├── BlocksKit+UIKit.h
│ │ │ ├── BlocksKit.h
│ │ │ ├── Core/
│ │ │ │ ├── BKMacros.h
│ │ │ │ ├── NSArray+BlocksKit.h
│ │ │ │ ├── NSArray+BlocksKit.m
│ │ │ │ ├── NSDictionary+BlocksKit.h
│ │ │ │ ├── NSDictionary+BlocksKit.m
│ │ │ │ ├── NSIndexSet+BlocksKit.h
│ │ │ │ ├── NSIndexSet+BlocksKit.m
│ │ │ │ ├── NSInvocation+BlocksKit.h
│ │ │ │ ├── NSInvocation+BlocksKit.m
│ │ │ │ ├── NSMutableArray+BlocksKit.h
│ │ │ │ ├── NSMutableArray+BlocksKit.m
│ │ │ │ ├── NSMutableDictionary+BlocksKit.h
│ │ │ │ ├── NSMutableDictionary+BlocksKit.m
│ │ │ │ ├── NSMutableIndexSet+BlocksKit.h
│ │ │ │ ├── NSMutableIndexSet+BlocksKit.m
│ │ │ │ ├── NSMutableOrderedSet+BlocksKit.h
│ │ │ │ ├── NSMutableOrderedSet+BlocksKit.m
│ │ │ │ ├── NSMutableSet+BlocksKit.h
│ │ │ │ ├── NSMutableSet+BlocksKit.m
│ │ │ │ ├── NSObject+BKAssociatedObjects.h
│ │ │ │ ├── NSObject+BKAssociatedObjects.m
│ │ │ │ ├── NSObject+BKBlockExecution.h
│ │ │ │ ├── NSObject+BKBlockExecution.m
│ │ │ │ ├── NSObject+BKBlockObservation.h
│ │ │ │ ├── NSObject+BKBlockObservation.m
│ │ │ │ ├── NSOrderedSet+BlocksKit.h
│ │ │ │ ├── NSOrderedSet+BlocksKit.m
│ │ │ │ ├── NSSet+BlocksKit.h
│ │ │ │ ├── NSSet+BlocksKit.m
│ │ │ │ ├── NSTimer+BlocksKit.h
│ │ │ │ └── NSTimer+BlocksKit.m
│ │ │ ├── DynamicDelegate/
│ │ │ │ ├── A2BlockInvocation.h
│ │ │ │ ├── A2BlockInvocation.m
│ │ │ │ ├── A2DynamicDelegate.h
│ │ │ │ ├── A2DynamicDelegate.m
│ │ │ │ ├── Foundation/
│ │ │ │ │ ├── NSCache+BlocksKit.h
│ │ │ │ │ ├── NSCache+BlocksKit.m
│ │ │ │ │ ├── NSURLConnection+BlocksKit.h
│ │ │ │ │ └── NSURLConnection+BlocksKit.m
│ │ │ │ ├── NSObject+A2BlockDelegate.h
│ │ │ │ ├── NSObject+A2BlockDelegate.m
│ │ │ │ ├── NSObject+A2DynamicDelegate.h
│ │ │ │ └── NSObject+A2DynamicDelegate.m
│ │ │ ├── MessageUI/
│ │ │ │ ├── MFMailComposeViewController+BlocksKit.h
│ │ │ │ ├── MFMailComposeViewController+BlocksKit.m
│ │ │ │ ├── MFMessageComposeViewController+BlocksKit.h
│ │ │ │ └── MFMessageComposeViewController+BlocksKit.m
│ │ │ └── UIKit/
│ │ │ ├── UIActionSheet+BlocksKit.h
│ │ │ ├── UIActionSheet+BlocksKit.m
│ │ │ ├── UIAlertView+BlocksKit.h
│ │ │ ├── UIAlertView+BlocksKit.m
│ │ │ ├── UIBarButtonItem+BlocksKit.h
│ │ │ ├── UIBarButtonItem+BlocksKit.m
│ │ │ ├── UIControl+BlocksKit.h
│ │ │ ├── UIControl+BlocksKit.m
│ │ │ ├── UIGestureRecognizer+BlocksKit.h
│ │ │ ├── UIGestureRecognizer+BlocksKit.m
│ │ │ ├── UIImagePickerController+BlocksKit.h
│ │ │ ├── UIImagePickerController+BlocksKit.m
│ │ │ ├── UIPopoverController+BlocksKit.h
│ │ │ ├── UIPopoverController+BlocksKit.m
│ │ │ ├── UITextField+BlocksKit.h
│ │ │ ├── UITextField+BlocksKit.m
│ │ │ ├── UIView+BlocksKit.h
│ │ │ ├── UIView+BlocksKit.m
│ │ │ ├── UIWebView+BlocksKit.h
│ │ │ └── UIWebView+BlocksKit.m
│ │ ├── LICENSE
│ │ └── README.md
│ ├── Local Podspecs/
│ │ └── NBSwipePageView.podspec.json
│ ├── NBSwipePageView/
│ │ ├── NBSwipePageView/
│ │ │ ├── NBSwipePageView.h
│ │ │ ├── NBSwipePageView.m
│ │ │ ├── NBSwipePageViewSheet.h
│ │ │ └── NBSwipePageViewSheet.m
│ │ └── README.md
│ ├── Pods.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── xcuserdata/
│ │ ├── vipstore.xcuserdatad/
│ │ │ └── xcschemes/
│ │ │ ├── BlocksKit.xcscheme
│ │ │ ├── NBSwipePageView.xcscheme
│ │ │ ├── Pods-testPasterImage.xcscheme
│ │ │ └── xcschememanagement.plist
│ │ └── wangyingbo.xcuserdatad/
│ │ └── xcschemes/
│ │ ├── BlocksKit.xcscheme
│ │ ├── NBSwipePageView.xcscheme
│ │ ├── Pods-testPasterImage.xcscheme
│ │ └── xcschememanagement.plist
│ └── Target Support Files/
│ ├── BlocksKit/
│ │ ├── BlocksKit-dummy.m
│ │ ├── BlocksKit-prefix.pch
│ │ └── BlocksKit.xcconfig
│ ├── NBSwipePageView/
│ │ ├── NBSwipePageView-dummy.m
│ │ ├── NBSwipePageView-prefix.pch
│ │ └── NBSwipePageView.xcconfig
│ └── Pods-testPasterImage/
│ ├── Pods-testPasterImage-acknowledgements.markdown
│ ├── Pods-testPasterImage-acknowledgements.plist
│ ├── Pods-testPasterImage-dummy.m
│ ├── Pods-testPasterImage-frameworks.sh
│ ├── Pods-testPasterImage-resources.sh
│ ├── Pods-testPasterImage.debug.xcconfig
│ └── Pods-testPasterImage.release.xcconfig
├── README.md
├── files/
│ └── README发帖专用.md
├── testPasterImage/
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets/
│ │ ├── 1.imageset/
│ │ │ └── Contents.json
│ │ ├── 2.imageset/
│ │ │ └── Contents.json
│ │ ├── 3.imageset/
│ │ │ └── Contents.json
│ │ ├── 4.imageset/
│ │ │ └── Contents.json
│ │ ├── 5.imageset/
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── bt_paster_delete.imageset/
│ │ │ └── Contents.json
│ │ ├── bt_paster_transform.imageset/
│ │ │ └── Contents.json
│ │ ├── dogs.imageset/
│ │ │ └── Contents.json
│ │ ├── gao4.imageset/
│ │ │ └── Contents.json
│ │ └── gaoyuanyuan.imageset/
│ │ └── Contents.json
│ ├── Base.lproj/
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Categories/
│ │ ├── UIImage+AddFunction.h
│ │ ├── UIImage+AddFunction.m
│ │ ├── UIViewController+Example.h
│ │ ├── UIViewController+Example.m
│ │ ├── UIViewController+Extension.h
│ │ ├── UIViewController+Extension.m
│ │ ├── UIViewController+Swizzling.h
│ │ └── UIViewController+Swizzling.m
│ ├── Controllers/
│ │ ├── ViewController.h
│ │ ├── ViewController.m
│ │ ├── YBBaseViewController.h
│ │ ├── YBBaseViewController.m
│ │ ├── YBPasterImageVC.h
│ │ └── YBPasterImageVC.m
│ ├── Info.plist
│ ├── Libs/
│ │ └── FilterImageLibs/
│ │ ├── ColorMatrix.h
│ │ ├── ImageUtil.h
│ │ ├── ImageUtil.m
│ │ └── UIImage-Extensions/
│ │ ├── .svn/
│ │ │ ├── entries
│ │ │ ├── format
│ │ │ └── pristine/
│ │ │ ├── 06/
│ │ │ │ └── 062d14b8b3d1573c2d8c9d30257fd9b0b84bd59c.svn-base
│ │ │ ├── 39/
│ │ │ │ └── 3944926a8fe582382d834a9fecb902c171a9a76e.svn-base
│ │ │ ├── 43/
│ │ │ │ └── 43a6e58f03ebdbe417f3c5028d4dc1b936e030b4.svn-base
│ │ │ ├── 5d/
│ │ │ │ └── 5deb2d07c4dd4089e7ade0df1f5278a51efb71cf.svn-base
│ │ │ ├── 74/
│ │ │ │ └── 7403967df71a9ffaa67500af6a610523742bfd53.svn-base
│ │ │ ├── 9e/
│ │ │ │ └── 9e08c4f172f233df24ad098fd5059cdaf5ad8268.svn-base
│ │ │ ├── a3/
│ │ │ │ └── a31a6fddf40b76b94df05097d799e55a769d8440.svn-base
│ │ │ ├── be/
│ │ │ │ └── becc3c813720214cae048c91b03d26dba76ff1ca.svn-base
│ │ │ ├── c8/
│ │ │ │ └── c8496f35a02cbd4ef1b2a81af9b5ca802b339a3a.svn-base
│ │ │ ├── d8/
│ │ │ │ └── d878290233a5ccddb800ee8a4f409b373e187859.svn-base
│ │ │ ├── dc/
│ │ │ │ └── dc06ddf7d7a2ad296ab0a741fcc7c3bc6d34b0e3.svn-base
│ │ │ └── ee/
│ │ │ └── ee255ad5f9f4f575fb733f734606d7eb9e0efeac.svn-base
│ │ ├── UIImage+Alpha.h
│ │ ├── UIImage+Alpha.m
│ │ ├── UIImage+Cut.h
│ │ ├── UIImage+Cut.m
│ │ ├── UIImage+Resize.h
│ │ ├── UIImage+Resize.m
│ │ ├── UIImage+RoundedCorner.h
│ │ ├── UIImage+RoundedCorner.m
│ │ ├── UIImage+SplitImageIntoTwoParts.h
│ │ └── UIImage+SplitImageIntoTwoParts.m
│ ├── Views/
│ │ ├── YBCustomViews/
│ │ │ ├── YBCustomButton.h
│ │ │ └── YBCustomButton.m
│ │ ├── YBFilterImage/
│ │ │ ├── YBFilterScrollView.h
│ │ │ └── YBFilterScrollView.m
│ │ └── YBPasterImage/
│ │ ├── YBPasterScrollView.h
│ │ ├── YBPasterScrollView.m
│ │ ├── YBPasterView.h
│ │ └── YBPasterView.m
│ └── main.m
├── testPasterImage.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata/
│ │ ├── vipstore.xcuserdatad/
│ │ │ └── UserInterfaceState.xcuserstate
│ │ └── wangyingbo.xcuserdatad/
│ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata/
│ ├── vipstore.xcuserdatad/
│ │ ├── xcdebugger/
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes/
│ │ ├── testPasterImage.xcscheme
│ │ └── xcschememanagement.plist
│ └── wangyingbo.xcuserdatad/
│ └── xcschemes/
│ ├── testPasterImage.xcscheme
│ └── xcschememanagement.plist
├── testPasterImage.xcworkspace/
│ ├── contents.xcworkspacedata
│ ├── xcshareddata/
│ │ └── testPasterImage.xcscmblueprint
│ └── xcuserdata/
│ ├── vipstore.xcuserdatad/
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── xcdebugger/
│ │ └── Breakpoints_v2.xcbkptlist
│ └── wangyingbo.xcuserdatad/
│ └── UserInterfaceState.xcuserstate
├── testPasterImageTests/
│ ├── Info.plist
│ └── testPasterImageTests.m
└── testPasterImageUITests/
├── Info.plist
└── testPasterImageUITests.m
================================================
FILE CONTENTS
================================================
================================================
FILE: Podfile
================================================
platform :ios, '8.0'
target 'testPasterImage' do
pod 'BlocksKit', '~> 2.2.5'
pod 'NBSwipePageView', :git => 'https://github.com/xuzhe/NBSwipePageView.git'
end
================================================
FILE: Pods/BlocksKit/BlocksKit/BlocksKit+MessageUI.h
================================================
//
// BlocksKit+MessageUI
//
// The Objective-C block utilities you always wish you had.
//
// Copyright (c) 2011-2012, 2013-2014 Zachary Waldowski
// Copyright (c) 2012-2013 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 <BlocksKit/MFMailComposeViewController+BlocksKit.h>
#import <BlocksKit/MFMessageComposeViewController+BlocksKit.h>
================================================
FILE: Pods/BlocksKit/BlocksKit/BlocksKit+UIKit.h
================================================
//
// BlocksKit+UIKit
//
// The Objective-C block utilities you always wish you had.
//
// Copyright (c) 2011-2012, 2013-2014 Zachary Waldowski
// Copyright (c) 2012-2013 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 <BlocksKit/UIActionSheet+BlocksKit.h>
#import <BlocksKit/UIAlertView+BlocksKit.h>
#import <BlocksKit/UIBarButtonItem+BlocksKit.h>
#import <BlocksKit/UIControl+BlocksKit.h>
#import <BlocksKit/UIGestureRecognizer+BlocksKit.h>
#import <BlocksKit/UIPopoverController+BlocksKit.h>
#import <BlocksKit/UITextField+BlocksKit.h>
#import <BlocksKit/UIView+BlocksKit.h>
#import <BlocksKit/UIWebView+BlocksKit.h>
#import <BlocksKit/UITextField+BlocksKit.h>
#import <BlocksKit/UIImagePickerController+BlocksKit.h>
================================================
FILE: Pods/BlocksKit/BlocksKit/BlocksKit.h
================================================
//
// BlocksKit
//
// The Objective-C block utilities you always wish you had.
//
// Copyright (c) 2011-2012, 2013-2014 Zachary Waldowski
// Copyright (c) 2012-2013 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 <BlocksKit/NSArray+BlocksKit.h>
#import <BlocksKit/NSDictionary+BlocksKit.h>
#import <BlocksKit/NSIndexSet+BlocksKit.h>
#import <BlocksKit/NSInvocation+BlocksKit.h>
#import <BlocksKit/NSMutableArray+BlocksKit.h>
#import <BlocksKit/NSMutableDictionary+BlocksKit.h>
#import <BlocksKit/NSMutableIndexSet+BlocksKit.h>
#import <BlocksKit/NSMutableOrderedSet+BlocksKit.h>
#import <BlocksKit/NSMutableSet+BlocksKit.h>
#import <BlocksKit/NSObject+BKAssociatedObjects.h>
#import <BlocksKit/NSObject+BKBlockExecution.h>
#import <BlocksKit/NSObject+BKBlockObservation.h>
#import <BlocksKit/NSOrderedSet+BlocksKit.h>
#import <BlocksKit/NSSet+BlocksKit.h>
#import <BlocksKit/NSTimer+BlocksKit.h>
#import <BlocksKit/BKMacros.h>
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/BKMacros.h
================================================
//
// 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 BK_eachTable = nil; \
(void)BK_eachTable; \
__typeof__(__VA_ARGS__) BK_retval = __VA_ARGS__; \
if(BK_eachTable) \
CFRelease(BK_eachTable); \
return BK_retval; \
}())
#define __BK_EACH_WRAPPER_VOID(...) (^{ __block CFMutableDictionaryRef BK_eachTable = nil; \
(void)BK_eachTable; \
__VA_ARGS__; \
if(BK_eachTable) \
CFRelease(BK_eachTable); \
}())
#define BK_EACH(collection, ...) __BK_EACH_WRAPPER_VOID([collection bk_each:^(id obj) { __VA_ARGS__ }])
#define BK_MAP(collection, ...) __BK_EACH_WRAPPER([collection bk_map:^id(id obj) { return (__VA_ARGS__); }])
#define BK_SELECT(collection, ...) __BK_EACH_WRAPPER([collection bk_select: ^BOOL (id obj) { return (__VA_ARGS__) != 0; }])
#define BK_REJECT(collection, ...) __BK_EACH_WRAPPER([collection bk_select: ^BOOL (id obj) { return (__VA_ARGS__) == 0; }])
#define BK_MATCH(collection, ...) __BK_EACH_WRAPPER([collection bk_match: ^BOOL (id obj) { return (__VA_ARGS__) != 0; }])
#define BK_REDUCE(collection, initial, ...) __BK_EACH_WRAPPER([collection bk_reduce: (initial) withBlock: ^id (id a, id b) { return (__VA_ARGS__); }])
// BK_APPLY is not wrapped, because we don't guarantee that the order matches the current collection during parallel execution.
#define BK_APPLY(collection, ...) [collection bk_apply:^(id obj) { __VA_ARGS__ }]
static inline id BKNextHelper(NSArray *array, CFMutableDictionaryRef *eachTablePtr) {
if (!*eachTablePtr) {
CFDictionaryKeyCallBacks keycb = {
0,
kCFTypeDictionaryKeyCallBacks.retain,
kCFTypeDictionaryKeyCallBacks.release,
kCFTypeDictionaryKeyCallBacks.copyDescription,
NULL,
NULL
};
*eachTablePtr = CFDictionaryCreateMutable(NULL, 0, &keycb, &kCFTypeDictionaryValueCallBacks);
}
NSEnumerator *enumerator = (__bridge id)CFDictionaryGetValue(*eachTablePtr, (__bridge CFArrayRef)array);
if (!enumerator) {
enumerator = [array objectEnumerator];
CFDictionarySetValue(*eachTablePtr, (__bridge CFArrayRef)array, (__bridge void *)enumerator);
}
return [enumerator nextObject];
}
#define BK_NEXT(array) BKNextHelper(array, &BK_eachTable)
#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
#ifndef NEXT
#define NEXT BK_NEXT
#endif
#endif
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSArray+BlocksKit.h
================================================
//
// NSArray+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.h>
#import <CoreGraphics/CGBase.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)bk_each:(void (^)(id obj))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)bk_apply:(void (^)(id obj))block;
/** Loops through an array to find the object matching the block.
bk_match: is functionally identical to bk_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 bk_select:
*/
- (id)bk_match:(BOOL (^)(id obj))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 bk_match:
*/
- (NSArray *)bk_select:(BOOL (^)(id obj))block;
/** Loops through an array to find the objects not matching the block.
This selector performs *literally* the exact same function as bk_select: but in reverse.
This is useful, as one may expect, for removing objects from an array.
NSArray *new = [computers bk_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 *)bk_reject:(BOOL (^)(id obj))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 bk_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 *)bk_map:(id (^)(id obj))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 bk_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 bk_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)bk_reduce:(id)initial withBlock:(id (^)(id sum, id obj))block;
/**
Sometimes we just want to loop an objects list and reduce one property, where
each result is a primitive type.
For example, say we want to calculate the total age of a list of people.
Code without using block will be something like:
NSArray *peoples = @[p1, p2, p3];
NSInteger totalAge = 0;
for (People *people in peoples) {
totalAge += [people age];
}
We can use a block to make it simpler:
NSArray *peoples = @[p1, p2, p3];
NSInteger totalAge = [peoples reduceInteger:0 withBlock:^(NSInteger result, id obj, NSInteger index) {
return result + [obj age];
}];
*/
- (NSInteger)bk_reduceInteger:(NSInteger)initial withBlock:(NSInteger(^)(NSInteger result, id obj))block;
/**
Sometimes we just want to loop an objects list and reduce one property, where
each result is a primitive type.
For instance, say we want to caculate the total balance from a list of people.
Code without using a block will be something like:
NSArray *peoples = @[p1, p2, p3];
CGFloat totalBalance = 0;
for (People *people in peoples) {
totalBalance += [people balance];
}
We can use a block to make it simpler:
NSArray *peoples = @[p1, p2, p3];
CGFloat totalBalance = [peoples reduceFloat:.0f WithBlock:^CGFloat(CGFloat result, id obj, NSInteger index) {
return result + [obj balance];
}];
*/
- (CGFloat)bk_reduceFloat:(CGFloat)inital withBlock:(CGFloat(^)(CGFloat result, id obj))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 bk_match: but returns a `BOOL` instead. It is not recommended
to use bk_any: as a check condition before executing bk_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 bk_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)bk_any:(BOOL (^)(id obj))block;
/** Loops through an array to find whether no objects match the block.
This selector performs *literally* the exact same function as bk_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)bk_none:(BOOL (^)(id obj))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)bk_all:(BOOL (^)(id obj))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 bk_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)bk_corresponds:(NSArray *)list withBlock:(BOOL (^)(id obj1, id obj2))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSArray+BlocksKit.m
================================================
//
// NSArray+BlocksKit.m
// BlocksKit
//
#import "NSArray+BlocksKit.h"
@implementation NSArray (BlocksKit)
- (void)bk_each:(void (^)(id obj))block
{
NSParameterAssert(block != nil);
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
block(obj);
}];
}
- (void)bk_apply:(void (^)(id obj))block
{
NSParameterAssert(block != nil);
[self enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
block(obj);
}];
}
- (id)bk_match:(BOOL (^)(id obj))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 *)bk_select:(BOOL (^)(id obj))block
{
NSParameterAssert(block != nil);
return [self objectsAtIndexes:[self indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return block(obj);
}]];
}
- (NSArray *)bk_reject:(BOOL (^)(id obj))block
{
NSParameterAssert(block != nil);
return [self bk_select:^BOOL(id obj) {
return !block(obj);
}];
}
- (NSArray *)bk_map:(id (^)(id obj))block
{
NSParameterAssert(block != nil);
NSMutableArray *result = [NSMutableArray arrayWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id value = block(obj) ?: [NSNull null];
[result addObject:value];
}];
return result;
}
- (id)bk_reduce:(id)initial withBlock:(id (^)(id sum, id obj))block
{
NSParameterAssert(block != nil);
__block id result = initial;
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
result = block(result, obj);
}];
return result;
}
- (NSInteger)bk_reduceInteger:(NSInteger)initial withBlock:(NSInteger (^)(NSInteger, id))block
{
NSParameterAssert(block != nil);
__block NSInteger result = initial;
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
result = block(result, obj);
}];
return result;
}
- (CGFloat)bk_reduceFloat:(CGFloat)inital withBlock:(CGFloat (^)(CGFloat, id))block
{
NSParameterAssert(block != nil);
__block CGFloat result = inital;
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
result = block(result, obj);
}];
return result;
}
- (BOOL)bk_any:(BOOL (^)(id obj))block
{
return [self bk_match:block] != nil;
}
- (BOOL)bk_none:(BOOL (^)(id obj))block
{
return [self bk_match:block] == nil;
}
- (BOOL)bk_all:(BOOL (^)(id obj))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)bk_corresponds:(NSArray *)list withBlock:(BOOL (^)(id obj1, id obj2))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
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSDictionary+BlocksKit.h
================================================
//
// NSDictionary+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)bk_each:(void (^)(id key, id obj))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)bk_apply:(void (^)(id key, id obj))block;
/** Loops through a dictionary to find the first key/value pair matching the block.
bk_match: is functionally identical to bk_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)bk_match:(BOOL (^)(id key, id obj))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 *)bk_select:(BOOL (^)(id key, id obj))block;
/** Loops through a dictionary to find the key/value pairs not matching the block.
This selector performs *literally* the exact same function as bk_select: but in reverse.
This is useful, as one may expect, for filtering objects.
NSDictionary *strings = [userData bk_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 *)bk_reject:(BOOL (^)(id key, id obj))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 *)bk_map:(id (^)(id key, id obj))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 bk_match: but returns a `BOOL` instead. It is not recommended
to use bk_any: as a check condition before executing bk_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)bk_any:(BOOL (^)(id key, id obj))block;
/** Loops through a dictionary to find whether no key/value pairs match the block.
This selector performs *literally* the exact same function as bk_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)bk_none:(BOOL (^)(id key, id obj))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)bk_all:(BOOL (^)(id key, id obj))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSDictionary+BlocksKit.m
================================================
//
// NSDictionary+BlocksKit.m
// BlocksKit
//
#import "NSDictionary+BlocksKit.h"
@implementation NSDictionary (BlocksKit)
- (void)bk_each:(void (^)(id key, id obj))block
{
NSParameterAssert(block != nil);
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
block(key, obj);
}];
}
- (void)bk_apply:(void (^)(id key, id obj))block
{
NSParameterAssert(block != nil);
[self enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id key, id obj, BOOL *stop) {
block(key, obj);
}];
}
- (id)bk_match:(BOOL (^)(id key, id obj))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 *)bk_select:(BOOL (^)(id key, id obj))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 *)bk_reject:(BOOL (^)(id key, id obj))block
{
NSParameterAssert(block != nil);
return [self bk_select:^BOOL(id key, id obj) {
return !block(key, obj);
}];
}
- (NSDictionary *)bk_map:(id (^)(id key, id obj))block
{
NSParameterAssert(block != nil);
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:self.count];
[self bk_each:^(id key, id obj) {
id value = block(key, obj) ?: [NSNull null];
result[key] = value;
}];
return result;
}
- (BOOL)bk_any:(BOOL (^)(id key, id obj))block
{
return [self bk_match:block] != nil;
}
- (BOOL)bk_none:(BOOL (^)(id key, id obj))block
{
return [self bk_match:block] == nil;
}
- (BOOL)bk_all:(BOOL (^)(id key, id obj))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
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSIndexSet+BlocksKit.h
================================================
//
// NSIndexSet+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)bk_each:(void (^)(NSUInteger index))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)bk_apply:(void (^)(NSUInteger index))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 bk_select:
*/
- (NSUInteger)bk_match:(BOOL (^)(NSUInteger index))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 bk_match:
*/
- (NSIndexSet *)bk_select:(BOOL (^)(NSUInteger index))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 bk_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 *)bk_reject:(BOOL (^)(NSUInteger index))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 *)bk_map:(NSUInteger (^)(NSUInteger index))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 *)bk_mapIndex:(id (^)(NSUInteger index))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 bk_match: but returns a `BOOL` instead. It is not recommended
to use bk_any: as a check condition before executing bk_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)bk_any:(BOOL (^)(NSUInteger index))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)bk_all:(BOOL (^)(NSUInteger index))block;
/** Loops through an index set to find whether no objects match the block.
This selector performs *literally* the exact same function as bk_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)bk_none:(BOOL (^)(NSUInteger index))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSIndexSet+BlocksKit.m
================================================
//
// NSIndexSet+BlocksKit.m
// BlocksKit
//
#import "NSIndexSet+BlocksKit.h"
@implementation NSIndexSet (BlocksKit)
- (void)bk_each:(void (^)(NSUInteger index))block {
NSParameterAssert(block != nil);
[self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
block(idx);
}];
}
- (void)bk_apply:(void (^)(NSUInteger index))block {
NSParameterAssert(block != nil);
[self enumerateIndexesWithOptions:NSEnumerationConcurrent usingBlock:^(NSUInteger idx, BOOL *stop) {
block(idx);
}];
}
- (NSUInteger)bk_match:(BOOL (^)(NSUInteger index))block {
NSParameterAssert(block != nil);
return [self indexPassingTest:^BOOL(NSUInteger idx, BOOL *stop) {
return block(idx);
}];
}
- (NSIndexSet *)bk_select:(BOOL (^)(NSUInteger index))block {
NSParameterAssert(block != nil);
NSIndexSet *list = [self indexesPassingTest:^BOOL(NSUInteger idx, BOOL *stop) {
return block(idx);
}];
if (!list.count) return nil;
return list;
}
- (NSIndexSet *)bk_reject:(BOOL (^)(NSUInteger index))block {
NSParameterAssert(block != nil);
return [self bk_select:^BOOL(NSUInteger idx) {
return !block(idx);
}];
}
- (NSIndexSet *)bk_map:(NSUInteger (^)(NSUInteger index))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 *)bk_mapIndex:(id (^)(NSUInteger index))block {
NSParameterAssert(block != nil);
NSMutableArray *result = [NSMutableArray arrayWithCapacity:self.count];
[self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
id value = block(idx) ?: [NSNull null];
[result addObject:value];
}];
return result;
}
- (BOOL)bk_any:(BOOL (^)(NSUInteger index))block {
return [self bk_match:block] != NSNotFound;
}
- (BOOL)bk_none:(BOOL (^)(NSUInteger index))block {
return [self bk_match:block] == NSNotFound;
}
- (BOOL)bk_all:(BOOL (^)(NSUInteger index))block {
NSParameterAssert(block != nil);
__block BOOL result = YES;
[self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
if (!block(idx)) {
result = NO;
*stop = YES;
}
}];
return result;
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSInvocation+BlocksKit.h
================================================
//
// NSInvocation+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.h>
/** BlocksKit extensions for NSInvocation. */
@interface NSInvocation (BlocksKit)
/** Generates a forwarding `NSInvocation` instance for a given method call
encapsulated by the 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. More complicated forwarding machinery
can be accomplished by the A2DynamicDelegate family of classes included in
BlocksKit.
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 *)bk_invocationWithTarget:(id)target block:(void (^)(id target))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSInvocation+BlocksKit.m
================================================
//
// 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];
NSParameterAssert(self.invocation == nil);
self.invocation = invocation;
}
@end
@implementation NSInvocation (BlocksKit)
+ (NSInvocation *)bk_invocationWithTarget:(id)target block:(void (^)(id target))block
{
NSParameterAssert(block != nil);
BKInvocationGrabber *grabber = [BKInvocationGrabber grabberWithTarget:target];
block(grabber);
return grabber.invocation;
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableArray+BlocksKit.h
================================================
//
// NSMutableArray+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)>bk_reject:
*/
- (void)bk_performSelect:(BOOL (^)(id obj))block;
/** Filters a mutable array to all objects but the ones matching the block,
the logical inverse to bk_select:.
@param block A single-argument, BOOL-returning code block.
@see <NSArray(BlocksKit)>bk_select:
*/
- (void)bk_performReject:(BOOL (^)(id obj))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 bk_performMap:^id(id obj) {
return [dateTransformer dateFromString:obj];
}];
@param block A single-argument, object-returning code block.
@see <NSArray(BlocksKit)>bk_map:
*/
- (void)bk_performMap:(id (^)(id obj))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableArray+BlocksKit.m
================================================
//
// NSMutableArray+BlocksKit.m
// BlocksKit
//
#import "NSMutableArray+BlocksKit.h"
@implementation NSMutableArray (BlocksKit)
- (void)bk_performSelect:(BOOL (^)(id obj))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)bk_performReject:(BOOL (^)(id obj))block {
NSParameterAssert(block != nil);
return [self bk_performSelect:^BOOL(id obj) {
return !block(obj);
}];
}
- (void)bk_performMap:(id (^)(id obj))block {
NSParameterAssert(block != nil);
NSMutableArray *new = [self mutableCopy];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id value = block(obj) ?: [NSNull null];
if ([value isEqual:obj]) return;
new[idx] = value;
}];
[self setArray:new];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableDictionary+BlocksKit.h
================================================
//
// NSMutableDictionary+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)>bk_reject:
*/
- (void)bk_performSelect:(BOOL (^)(id key, id obj))block;
/** Filters a mutable dictionary to the key/value pairs not matching the block,
the logical inverse to bk_select:.
@param block A BOOL-returning code block for a key/value pair.
@see <NSDictionary(BlocksKit)>bk_select:
*/
- (void)bk_performReject:(BOOL (^)(id key, id obj))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)>bk_map:
*/
- (void)bk_performMap:(id (^)(id key, id obj))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableDictionary+BlocksKit.m
================================================
//
// NSMutableDictionary+BlocksKit.m
// BlocksKit
//
#import "NSMutableDictionary+BlocksKit.h"
@implementation NSMutableDictionary (BlocksKit)
- (void)bk_performSelect:(BOOL (^)(id key, id obj))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)bk_performReject:(BOOL (^)(id key, id obj))block
{
NSParameterAssert(block != nil);
[self bk_performSelect:^BOOL(id key, id obj) {
return !block(key, obj);
}];
}
- (void)bk_performMap:(id (^)(id key, id obj))block
{
NSParameterAssert(block != nil);
NSMutableDictionary *new = [self mutableCopy];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
id value = block(key, obj) ?: [NSNull null];
if ([value isEqual:obj]) return;
new[key] = value;
}];
[self setDictionary:new];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableIndexSet+BlocksKit.h
================================================
//
// NSMutableIndexSet+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)>bk_reject:
*/
- (void)bk_performSelect:(BOOL (^)(NSUInteger index))block;
/** Filters a mutable index set to all indexes but the ones matching the block,
the logical inverse to bk_select:.
@param block A single-argument, BOOL-returning code block.
@see <NSIndexSet(BlocksKit)>bk_select:
*/
- (void)bk_performReject:(BOOL (^)(NSUInteger index))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)>bk_map:
*/
- (void)bk_performMap:(NSUInteger (^)(NSUInteger index))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableIndexSet+BlocksKit.m
================================================
//
// NSMutableIndexSet+BlocksKit.m
// BlocksKit
//
#import "NSMutableIndexSet+BlocksKit.h"
@implementation NSMutableIndexSet (BlocksKit)
- (void)bk_performSelect:(BOOL (^)(NSUInteger index))block
{
NSParameterAssert(block != nil);
NSIndexSet *list = [self indexesPassingTest:^BOOL(NSUInteger idx, BOOL *stop) {
return !block(idx);
}];
if (!list.count) return;
[self removeIndexes:list];
}
- (void)bk_performReject:(BOOL (^)(NSUInteger index))block
{
NSParameterAssert(block != nil);
return [self bk_performSelect:^BOOL(NSUInteger idx) {
return !block(idx);
}];
}
- (void)bk_performMap:(NSUInteger (^)(NSUInteger index))block
{
NSParameterAssert(block != nil);
NSMutableIndexSet *new = [self mutableCopy];
[self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
[new addIndex:block(idx)];
}];
[self removeAllIndexes];
[self addIndexes:new];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableOrderedSet+BlocksKit.h
================================================
//
// NSMutableOrderedSet+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)>bk_reject:
*/
- (void)bk_performSelect:(BOOL (^)(id obj))block;
/** Filters a mutable ordered set to all objects but the ones matching the
block, the logical inverse to bk_select:.
@param block A single-argument, BOOL-returning code block.
@see <NSOrderedSet(BlocksKit)>bk_select:
*/
- (void)bk_performReject:(BOOL (^)(id obj))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 bk_performMap:^id(id obj) {
return [dateTransformer dateFromString:obj];
}];
@param block A single-argument, object-returning code block.
@see <NSOrderedSet(BlocksKit)>bk_map:
*/
- (void)bk_performMap:(id (^)(id obj))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableOrderedSet+BlocksKit.m
================================================
//
// NSMutableOrderedSet+BlocksKit.m
// BlocksKit
//
#import "NSMutableOrderedSet+BlocksKit.h"
@implementation NSMutableOrderedSet (BlocksKit)
- (void)bk_performSelect:(BOOL (^)(id obj))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)bk_performReject:(BOOL (^)(id obj))block {
NSParameterAssert(block != nil);
return [self bk_performSelect:^BOOL(id obj) {
return !block(obj);
}];
}
- (void)bk_performMap:(id (^)(id obj))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) ?: [NSNull null];
if ([value isEqual:obj]) return;
[newIndexes addIndex:idx];
[newObjects addObject:obj];
}];
[self replaceObjectsAtIndexes:newIndexes withObjects:newObjects];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableSet+BlocksKit.h
================================================
//
// NSMutableSet+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)>bk_reject:
*/
- (void)bk_performSelect:(BOOL (^)(id obj))block;
/** Filters a mutable set to all objects but the ones matching the block,
the logical inverse to bk_select:.
@param block A single-argument, BOOL-returning code block.
@see <NSSet(BlocksKit)>bk_select:
*/
- (void)bk_performReject:(BOOL (^)(id obj))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 bk_map:^id(id obj) {
return [obj view];
}];
@param block A single-argument, object-returning code block.
@see <NSSet(BlocksKit)>bk_map:
*/
- (void)bk_performMap:(id (^)(id obj))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSMutableSet+BlocksKit.m
================================================
//
// NSMutableSet+BlocksKit.m
// BlocksKit
//
#import "NSMutableSet+BlocksKit.h"
@implementation NSMutableSet (BlocksKit)
- (void)bk_performSelect:(BOOL (^)(id obj))block {
NSParameterAssert(block != nil);
NSSet *list = [self objectsPassingTest:^BOOL(id obj, BOOL *stop) {
return block(obj);
}];
[self setSet:list];
}
- (void)bk_performReject:(BOOL (^)(id obj))block {
NSParameterAssert(block != nil);
[self bk_performSelect:^BOOL(id obj) {
return !block(obj);
}];
}
- (void)bk_performMap:(id (^)(id obj))block {
NSParameterAssert(block != nil);
NSMutableSet *new = [NSMutableSet setWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
id value = block(obj);
if (!value) return;
[new addObject:value];
}];
[self setSet:new];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSObject+BKAssociatedObjects.h
================================================
//
// NSObject+BKAssociatedObjects.h
// BlocksKit
//
#import <Foundation/Foundation.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)bk_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)bk_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)bk_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)bk_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)bk_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)bk_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)bk_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)bk_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)bk_weaklyAssociateValue:(__autoreleasing 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)bk_weaklyAssociateValue:(__autoreleasing 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)bk_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)bk_associatedValueForKey:(const void *)key;
/** Returns the reciever to a clean state by removing all
associated objects, releasing them if necessary. */
- (void)bk_removeAllAssociatedObjects;
/** Returns the recieving class to a clean state by removing
all associated objects, releasing them if necessary. */
+ (void)bk_removeAllAssociatedObjects;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSObject+BKAssociatedObjects.m
================================================
//
// NSObject+BKAssociatedObjects.m
// BlocksKit
//
#import <objc/runtime.h>
#import "NSObject+BKAssociatedObjects.h"
#pragma mark - Weak support
@interface _BKWeakAssociatedObject : NSObject
@property (nonatomic, weak) id value;
@end
@implementation _BKWeakAssociatedObject
@end
@implementation NSObject (BKAssociatedObjects)
#pragma mark - Instance Methods
- (void)bk_associateValue:(id)value withKey:(const void *)key
{
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)bk_atomicallyAssociateValue:(id)value withKey:(const void *)key
{
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN);
}
- (void)bk_associateCopyOfValue:(id)value withKey:(const void *)key
{
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (void)bk_atomicallyAssociateCopyOfValue:(id)value withKey:(const void *)key
{
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY);
}
- (void)bk_weaklyAssociateValue:(__autoreleasing id)value withKey:(const void *)key
{
_BKWeakAssociatedObject *assoc = objc_getAssociatedObject(self, key);
if (!assoc) {
assoc = [_BKWeakAssociatedObject new];
[self bk_associateValue:assoc withKey:key];
}
assoc.value = value;
}
- (id)bk_associatedValueForKey:(const void *)key
{
id value = objc_getAssociatedObject(self, key);
if (value && [value isKindOfClass:[_BKWeakAssociatedObject class]]) {
return [(_BKWeakAssociatedObject *)value value];
}
return value;
}
- (void)bk_removeAllAssociatedObjects
{
objc_removeAssociatedObjects(self);
}
#pragma mark - Class Methods
+ (void)bk_associateValue:(id)value withKey:(const void *)key
{
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (void)bk_atomicallyAssociateValue:(id)value withKey:(const void *)key
{
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN);
}
+ (void)bk_associateCopyOfValue:(id)value withKey:(const void *)key
{
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
+ (void)bk_atomicallyAssociateCopyOfValue:(id)value withKey:(const void *)key
{
objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_COPY);
}
+ (void)bk_weaklyAssociateValue:(__autoreleasing id)value withKey:(const void *)key
{
_BKWeakAssociatedObject *assoc = objc_getAssociatedObject(self, key);
if (!assoc) {
assoc = [_BKWeakAssociatedObject new];
[self bk_associateValue:assoc withKey:key];
}
assoc.value = value;
}
+ (id)bk_associatedValueForKey:(const void *)key
{
id value = objc_getAssociatedObject(self, key);
if (value && [value isKindOfClass:[_BKWeakAssociatedObject class]]) {
return [(_BKWeakAssociatedObject *)value value];
}
return value;
}
+ (void)bk_removeAllAssociatedObjects
{
objc_removeAssociatedObjects(self);
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSObject+BKBlockExecution.h
================================================
//
// NSObject+BKBlockExecution.h
// BlocksKit
//
#import <Foundation/Foundation.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 (BKBlockExecution)
/** 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)bk_performBlock:(void (^)(id obj))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)bk_performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay;
/** Executes a block in the background after a given delay on the receiver.
This class method is functionally identical to `- (id)bk_performBlock:afterDelay:`,
except the block will be performed on a background thread instead of the main thread.
@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)bk_performBlockInBackground:(void (^)(id obj))block afterDelay:(NSTimeInterval)delay;
/** Executes a block in the background after a given delay.
This class method is functionally identical to `+ (id)bk_performBlock:afterDelay:`,
except the block will be performed on a background thread instead of the main thread.
@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)bk_performBlockInBackground:(void (^)(void))block afterDelay:(NSTimeInterval)delay;
/** Executes a block in the background after a given delay.
This class method is functionally identical to `+ (id)bk_performBlock:afterDelay:`,
except the block will be performed on the specified thread instead of the main thread.
@see performBlock:afterDelay:
@param block A code block.
@param queue A background queue.
@param delay A measure in seconds.
@return Returns a pointer to the block that may or may not execute the given block.
*/
+ (id)bk_performBlock:(void (^)(void))block onQueue:(dispatch_queue_t)queue afterDelay:(NSTimeInterval)delay;
/** Executes a block in the background after a given delay.
This class method is functionally identical to `- (id)bk_performBlock:afterDelay:`,
except the block will be performed on the specified thread instead of the main thread.
@see performBlock:afterDelay:
@param block A code block.
@param queue A background queue.
@param delay A measure in seconds.
@return Returns a pointer to the block that may or may not execute the given block.
*/
- (id)bk_performBlock:(void (^)(id obj))block onQueue:(dispatch_queue_t)queue 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)bk_cancelBlock:(id)block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSObject+BKBlockExecution.m
================================================
//
// NSObject+BKBlockExecution.m
// BlocksKit
//
#import "NSObject+BKBlockExecution.h"
#define BKTimeDelay(t) dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(NSEC_PER_SEC * t))
@implementation NSObject (BlocksKit)
- (id)bk_performBlock:(void (^)(id obj))block afterDelay:(NSTimeInterval)delay
{
return [self bk_performBlock:block onQueue:dispatch_get_main_queue() afterDelay:delay];
}
+ (id)bk_performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay
{
return [NSObject bk_performBlock:block onQueue:dispatch_get_main_queue() afterDelay:delay];
}
- (id)bk_performBlockInBackground:(void (^)(id obj))block afterDelay:(NSTimeInterval)delay
{
return [self bk_performBlock:block onQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0) afterDelay:delay];
}
+ (id)bk_performBlockInBackground:(void (^)(void))block afterDelay:(NSTimeInterval)delay
{
return [NSObject bk_performBlock:block onQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0) afterDelay:delay];
}
- (id)bk_performBlock:(void (^)(id obj))block onQueue:(dispatch_queue_t)queue 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), queue, ^{
wrapper(NO);
});
return [wrapper copy];
}
+ (id)bk_performBlock:(void (^)(void))block onQueue:(dispatch_queue_t)queue 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), queue, ^{ wrapper(NO); });
return [wrapper copy];
}
+ (void)bk_cancelBlock:(id)block
{
NSParameterAssert(block != nil);
void (^wrapper)(BOOL) = block;
wrapper(YES);
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSObject+BKBlockObservation.h
================================================
//
// NSObject+BKBlockObservation.h
// BlocksKit
//
#import <Foundation/Foundation.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 *)bk_addObserverForKeyPath:(NSString *)keyPath task:(void (^)(id target))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 *)bk_addObserverForKeyPaths:(NSArray *)keyPaths task:(void (^)(id obj, NSString *keyPath))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 *)bk_addObserverForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options task:(void (^)(id obj, NSDictionary *change))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.
@return A unique identifier for removing
observation with removeObserverWithBlockToken:.
@see addObserverForKeyPath:identifier:options:task:
*/
- (NSString *)bk_addObserverForKeyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options task:(void (^)(id obj, NSString *keyPath, NSDictionary *change))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)bk_addObserverForKeyPath:(NSString *)keyPath identifier:(NSString *)token options:(NSKeyValueObservingOptions)options task:(void (^)(id obj, NSDictionary *change))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)bk_addObserverForKeyPaths:(NSArray *)keyPaths identifier:(NSString *)token options:(NSKeyValueObservingOptions)options task:(void (^)(id obj, NSString *keyPath, NSDictionary *change))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)bk_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)bk_removeObserversWithIdentifier:(NSString *)token;
/** Remove all registered block observers. */
- (void)bk_removeAllBlockObservers;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSObject+BKBlockObservation.m
================================================
//
// NSObject+BKBlockObservation.m
// BlocksKit
//
#import <objc/runtime.h>
#import <objc/message.h>
#import "NSArray+BlocksKit.h"
#import "NSDictionary+BlocksKit.h"
#import "NSObject+BKAssociatedObjects.h"
#import "NSObject+BKBlockObservation.h"
#import "NSSet+BlocksKit.h"
typedef NS_ENUM(int, BKObserverContext) {
BKObserverContextKey,
BKObserverContextKeyWithChange,
BKObserverContextManyKeys,
BKObserverContextManyKeysWithChange
};
@interface _BKObserver : NSObject {
BOOL _isObserving;
}
@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 context:(BKObserverContext)context task:(id)task;
@end
static void *BKObserverBlocksKey = &BKObserverBlocksKey;
static void *BKBlockObservationContext = &BKBlockObservationContext;
@implementation _BKObserver
- (id)initWithObservee:(id)observee keyPaths:(NSArray *)keyPaths context:(BKObserverContext)context task:(id)task
{
if ((self = [super init])) {
_observee = observee;
_keyPaths = [keyPaths mutableCopy];
_context = context;
_task = [task copy];
}
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: {
void (^task)(id) = self.task;
task(object);
break;
}
case BKObserverContextKeyWithChange: {
void (^task)(id, NSDictionary *) = self.task;
task(object, change);
break;
}
case BKObserverContextManyKeys: {
void (^task)(id, NSString *) = self.task;
task(object, keyPath);
break;
}
case BKObserverContextManyKeysWithChange: {
void (^task)(id, NSString *, NSDictionary *) = self.task;
task(object, keyPath, change);
break;
}
}
}
}
- (void)startObservingWithOptions:(NSKeyValueObservingOptions)options
{
@synchronized(self) {
if (_isObserving) return;
[self.keyPaths bk_each:^(NSString *keyPath) {
[self.observee addObserver:self forKeyPath:keyPath options:options context:BKBlockObservationContext];
}];
_isObserving = YES;
}
}
- (void)stopObservingKeyPath:(NSString *)keyPath
{
NSParameterAssert(keyPath);
@synchronized (self) {
if (!_isObserving) return;
if (![self.keyPaths containsObject:keyPath]) return;
NSObject *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)_stopObservingLocked
{
if (!_isObserving) return;
_task = nil;
NSObject *observee = self.observee;
NSArray *keyPaths = [self.keyPaths copy];
_observee = nil;
_keyPaths = nil;
[keyPaths bk_each:^(NSString *keyPath) {
[observee removeObserver:self forKeyPath:keyPath context:BKBlockObservationContext];
}];
}
- (void)stopObserving
{
if (_observee == nil) return;
@synchronized (self) {
[self _stopObservingLocked];
}
}
- (void)dealloc
{
if (self.keyPaths) {
[self _stopObservingLocked];
}
}
@end
@implementation NSObject (BlockObservation)
- (NSString *)bk_addObserverForKeyPath:(NSString *)keyPath task:(void (^)(id target))task
{
NSString *token = [[NSProcessInfo processInfo] globallyUniqueString];
[self bk_addObserverForKeyPaths:@[ keyPath ] identifier:token options:0 context:BKObserverContextKey task:task];
return token;
}
- (NSString *)bk_addObserverForKeyPaths:(NSArray *)keyPaths task:(void (^)(id obj, NSString *keyPath))task
{
NSString *token = [[NSProcessInfo processInfo] globallyUniqueString];
[self bk_addObserverForKeyPaths:keyPaths identifier:token options:0 context:BKObserverContextManyKeys task:task];
return token;
}
- (NSString *)bk_addObserverForKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options task:(void (^)(id obj, NSDictionary *change))task
{
NSString *token = [[NSProcessInfo processInfo] globallyUniqueString];
[self bk_addObserverForKeyPath:keyPath identifier:token options:options task:task];
return token;
}
- (NSString *)bk_addObserverForKeyPaths:(NSArray *)keyPaths options:(NSKeyValueObservingOptions)options task:(void (^)(id obj, NSString *keyPath, NSDictionary *change))task
{
NSString *token = [[NSProcessInfo processInfo] globallyUniqueString];
[self bk_addObserverForKeyPaths:keyPaths identifier:token options:options task:task];
return token;
}
- (void)bk_addObserverForKeyPath:(NSString *)keyPath identifier:(NSString *)identifier options:(NSKeyValueObservingOptions)options task:(void (^)(id obj, NSDictionary *change))task
{
BKObserverContext context = (options == 0) ? BKObserverContextKey : BKObserverContextKeyWithChange;
[self bk_addObserverForKeyPaths:@[keyPath] identifier:identifier options:options context:context task:task];
}
- (void)bk_addObserverForKeyPaths:(NSArray *)keyPaths identifier:(NSString *)identifier options:(NSKeyValueObservingOptions)options task:(void (^)(id obj, NSString *keyPath, NSDictionary *change))task
{
BKObserverContext context = (options == 0) ? BKObserverContextManyKeys : BKObserverContextManyKeysWithChange;
[self bk_addObserverForKeyPaths:keyPaths identifier:identifier options:options context:context task:task];
}
- (void)bk_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)bk_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)bk_removeAllBlockObservers
{
NSDictionary *dict;
@synchronized (self) {
dict = [[self bk_observerBlocks] copy];
[self bk_setObserverBlocks:nil];
}
[dict.allValues bk_each:^(_BKObserver *trampoline) {
[trampoline stopObserving];
}];
}
#pragma mark - "Private"s
+ (NSMutableSet *)bk_observedClassesHash
{
static dispatch_once_t onceToken;
static NSMutableSet *swizzledClasses = nil;
dispatch_once(&onceToken, ^{
swizzledClasses = [[NSMutableSet alloc] init];
});
return swizzledClasses;
}
- (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);
Class classToSwizzle = self.class;
NSMutableSet *classes = self.class.bk_observedClassesHash;
@synchronized (classes) {
NSString *className = NSStringFromClass(classToSwizzle);
if (![classes containsObject:className]) {
SEL deallocSelector = sel_registerName("dealloc");
__block void (*originalDealloc)(__unsafe_unretained id, SEL) = NULL;
id newDealloc = ^(__unsafe_unretained id objSelf) {
[objSelf bk_removeAllBlockObservers];
if (originalDealloc == NULL) {
struct objc_super superInfo = {
.receiver = objSelf,
.super_class = class_getSuperclass(classToSwizzle)
};
void (*msgSend)(struct objc_super *, SEL) = (__typeof__(msgSend))objc_msgSendSuper;
msgSend(&superInfo, deallocSelector);
} else {
originalDealloc(objSelf, deallocSelector);
}
};
IMP newDeallocIMP = imp_implementationWithBlock(newDealloc);
if (!class_addMethod(classToSwizzle, deallocSelector, newDeallocIMP, "v@:")) {
// The class already contains a method implementation.
Method deallocMethod = class_getInstanceMethod(classToSwizzle, deallocSelector);
// We need to store original implementation before setting new implementation
// in case method is called at the time of setting.
originalDealloc = (void(*)(__unsafe_unretained id, SEL))method_getImplementation(deallocMethod);
// We need to store original implementation again, in case it just changed.
originalDealloc = (void(*)(__unsafe_unretained id, SEL))method_setImplementation(deallocMethod, newDeallocIMP);
}
[classes addObject:className];
}
}
NSMutableDictionary *dict;
_BKObserver *observer = [[_BKObserver alloc] initWithObservee:self keyPaths:keyPaths context:context task:task];
[observer startObservingWithOptions:options];
@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 bk_associateValue:dict withKey:BKObserverBlocksKey];
}
- (NSMutableDictionary *)bk_observerBlocks
{
return [self bk_associatedValueForKey:BKObserverBlocksKey];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSOrderedSet+BlocksKit.h
================================================
//
// NSOrderedSet+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)bk_each:(void (^)(id obj))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)bk_apply:(void (^)(id obj))block;
/** Loops through an ordered set to find the object matching the block.
bk_match: is functionally identical to bk_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 bk_select:
*/
- (id)bk_match:(BOOL (^)(id obj))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 bk_match:
*/
- (NSOrderedSet *)bk_select:(BOOL (^)(id obj))block;
/** Loops through an ordered set to to find the objects not matching the block.
This selector performs *literally* the exact same function as bk_select: but in
reverse.
This is useful, as one may expect, for removing objects from an ordered set to.
NSOrderedSet *new = [computers bk_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 *)bk_reject:(BOOL (^)(id obj))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 bk_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 *)bk_map:(id (^)(id obj))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 bk_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 bk_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)bk_reduce:(id)initial withBlock:(id (^)(id sum, id obj))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 bk_match: but returns a `BOOL` instead. It is not recommended
to use bk_any: as a check condition before executing bk_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 bk_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)bk_any:(BOOL (^)(id obj))block;
/** Loops through an ordered set to find whether no objects match the block.
This selector performs *literally* the exact same function as bk_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)bk_none:(BOOL (^)(id obj))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)bk_all:(BOOL (^)(id obj))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 bk_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)bk_corresponds:(NSOrderedSet *)list withBlock:(BOOL (^)(id obj1, id obj2))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSOrderedSet+BlocksKit.m
================================================
//
// NSOrderedSet+BlocksKit.m
// BlocksKit
//
#import "NSOrderedSet+BlocksKit.h"
@implementation NSOrderedSet (BlocksKit)
- (void)bk_each:(void (^)(id obj))block
{
NSParameterAssert(block != nil);
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
block(obj);
}];
}
- (void)bk_apply:(void (^)(id obj))block
{
NSParameterAssert(block != nil);
[self enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
block(obj);
}];
}
- (id)bk_match:(BOOL (^)(id obj))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 *)bk_select:(BOOL (^)(id obj))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 *)bk_reject:(BOOL (^)(id obj))block
{
NSParameterAssert(block != nil);
return [self bk_select:^BOOL(id obj) {
return !block(obj);
}];
}
- (NSOrderedSet *)bk_map:(id (^)(id obj))block
{
NSParameterAssert(block != nil);
NSMutableOrderedSet *result = [NSMutableOrderedSet orderedSetWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id value = block(obj) ?: [NSNull null];
[result addObject:value];
}];
return result;
}
- (id)bk_reduce:(id)initial withBlock:(id (^)(id sum, id obj))block
{
NSParameterAssert(block != nil);
__block id result = initial;
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
result = block(result, obj);
}];
return result;
}
- (BOOL)bk_any:(BOOL (^)(id obj))block
{
return [self bk_match:block] != nil;
}
- (BOOL)bk_none:(BOOL (^)(id obj))block
{
return [self bk_match:block] == nil;
}
- (BOOL)bk_all:(BOOL (^)(id obj))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)bk_corresponds:(NSOrderedSet *)list withBlock:(BOOL (^)(id obj1, id obj2))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
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSSet+BlocksKit.h
================================================
//
// NSSet+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)bk_each:(void (^)(id obj))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)bk_apply:(void (^)(id obj))block;
/** Loops through a set to find the object matching the block.
bk_match: is functionally identical to bk_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 bk_select:
*/
- (id)bk_match:(BOOL (^)(id obj))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 bk_match:
*/
- (NSSet *)bk_select:(BOOL (^)(id obj))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 bk_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 *)bk_reject:(BOOL (^)(id obj))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 bk_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 *)bk_map:(id (^)(id obj))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 bk_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)bk_reduce:(id)initial withBlock:(id (^)(id sum, id obj))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 bk_match: but returns a `BOOL` instead. It is not recommended
to use bk_any: as a check condition before executing bk_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)bk_any:(BOOL (^)(id obj))block;
/** Loops through a set to find whether no objects match the block.
This selector performs *literally* the exact same function as bk_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)bk_none:(BOOL (^)(id obj))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)bk_all:(BOOL (^)(id obj))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSSet+BlocksKit.m
================================================
//
// NSSet+BlocksKit.m
// BlocksKit
//
#import "NSSet+BlocksKit.h"
@implementation NSSet (BlocksKit)
- (void)bk_each:(void (^)(id obj))block
{
NSParameterAssert(block != nil);
[self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
block(obj);
}];
}
- (void)bk_apply:(void (^)(id obj))block
{
NSParameterAssert(block != nil);
[self enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, BOOL *stop) {
block(obj);
}];
}
- (id)bk_match:(BOOL (^)(id obj))block
{
NSParameterAssert(block != nil);
return [[self objectsPassingTest:^BOOL(id obj, BOOL *stop) {
if (block(obj)) {
*stop = YES;
return YES;
}
return NO;
}] anyObject];
}
- (NSSet *)bk_select:(BOOL (^)(id obj))block
{
NSParameterAssert(block != nil);
return [self objectsPassingTest:^BOOL(id obj, BOOL *stop) {
return block(obj);
}];
}
- (NSSet *)bk_reject:(BOOL (^)(id obj))block
{
NSParameterAssert(block != nil);
return [self objectsPassingTest:^BOOL(id obj, BOOL *stop) {
return !block(obj);
}];
}
- (NSSet *)bk_map:(id (^)(id obj))block
{
NSParameterAssert(block != nil);
NSMutableSet *result = [NSMutableSet setWithCapacity:self.count];
[self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
id value = block(obj) ?:[NSNull null];
[result addObject:value];
}];
return result;
}
- (id)bk_reduce:(id)initial withBlock:(id (^)(id sum, id obj))block
{
NSParameterAssert(block != nil);
__block id result = initial;
[self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
result = block(result, obj);
}];
return result;
}
- (BOOL)bk_any:(BOOL (^)(id obj))block
{
return [self bk_match:block] != nil;
}
- (BOOL)bk_none:(BOOL (^)(id obj))block
{
return [self bk_match:block] == nil;
}
- (BOOL)bk_all:(BOOL (^)(id obj))block
{
NSParameterAssert(block != nil);
__block BOOL result = YES;
[self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
if (!block(obj)) {
result = NO;
*stop = YES;
}
}];
return result;
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSTimer+BlocksKit.h
================================================
//
// NSTimer+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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 *)bk_scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)(NSTimer *timer))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 *)bk_timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)(NSTimer *timer))inBlock repeats:(BOOL)inRepeats;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/Core/NSTimer+BlocksKit.m
================================================
//
// NSTimer+BlocksKit.m
// BlocksKit
//
#import "NSTimer+BlocksKit.h"
@interface NSTimer (BlocksKitPrivate)
+ (void)bk_executeBlockFromTimer:(NSTimer *)aTimer;
@end
@implementation NSTimer (BlocksKit)
+ (id)bk_scheduledTimerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)(NSTimer *timer))block repeats:(BOOL)inRepeats
{
NSParameterAssert(block != nil);
return [self scheduledTimerWithTimeInterval:inTimeInterval target:self selector:@selector(bk_executeBlockFromTimer:) userInfo:[block copy] repeats:inRepeats];
}
+ (id)bk_timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)(NSTimer *timer))block repeats:(BOOL)inRepeats
{
NSParameterAssert(block != nil);
return [self timerWithTimeInterval:inTimeInterval target:self selector:@selector(bk_executeBlockFromTimer:) userInfo:[block copy] repeats:inRepeats];
}
+ (void)bk_executeBlockFromTimer:(NSTimer *)aTimer {
void (^block)(NSTimer *) = [aTimer userInfo];
if (block) block(aTimer);
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/A2BlockInvocation.h
================================================
//
// A2BlockInvocation.h
// BlocksKit
//
#import <Foundation/Foundation.h>
/// If a block invocation is instiated with an invalid method signature,
/// an `NSInvalidArgumentException` is thrown containing this key in the
/// user info.
extern NSString *const A2IncompatibleMethodSignatureKey;
/** 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.
A block invocation object can be repeatedly dispatched with multiple sets of
arguments with the same flexibility as NSInvocation. This design makes
`A2BlockInvocation` extremely useful, because blocks can be used to capture
scope and a block invocation can be used to save it for later.
Like `NSInvocation`, `A2BlockInvocation` does not support invocations of
methods with variadic arguments or union arguments.
*/
@interface A2BlockInvocation : NSObject
/** Inspects the given block literal and returns a compatible method signature.
The returned method signature is suitable for use in the Foundation forwarding
system to link a method call to a block invocation.
@param block An Objective-C block literal
@return A method signature matching the declared prototype for the block
*/
+ (NSMethodSignature *)methodSignatureForBlock:(id)block;
/** @name Creating A2BlockInvocation Objects */
/** Returns a block invocation object able to construct calls to a given block.
This method synthesizes a compatible method signature for the given block.
@param block A block literal
@return An initialized block invocation object
@see methodSignatureForBlock
*/
- (instancetype)initWithBlock:(id)block;
/** Returns a block invocation object able to construct calls to a given block
using a given Objective-C method signature.
The method signature given must be compatible with the signature of the block;
that is, equal to the block signature but with a `SEL` (`':'`) as the second
parameter. Passing in an incompatible method signature will raise an exception.
An example method returning a string for an integer argument would have the
following properties:
- Block type signature of `NSString *(^)(int)`
- Block function definition of `NSString *(*)(id, int)`
- Block signature of `"@@?i"`
- Method signature of `"@:i"` or `"@i"`
@param block An Objective-C block literal
@param methodSignature An method signature matching the block
@return An initialized block invocation object
*/
- (instancetype)initWithBlock:(id)block methodSignature:(NSMethodSignature *)methodSignature;
/** @name Getting the Block and Method Signatures */
/// The receiver's method signature, reflecting the block with a selector.
/// Appropriate for use in `-methodSignatureForSelector:`.
@property (nonatomic, strong, readonly) NSMethodSignature *methodSignature;
/// Returns the receiver's block.
@property (nonatomic, copy, readonly) id block;
/** Calls the receiver's block with the arguments from the given invocation,
providing a buffer containing the block's return value upon return.
@param inv An instance of NSInvocation with values for its arguments set.
@param returnValue On return, the block's return value, or `nil` for a void
return type.
@param NO if the buffer copies necessary for invocation failed, YES otherwise.
@see invokeWithInvocation:returnValue:
*/
- (BOOL)invokeWithInvocation:(NSInvocation *)inv returnValue:(out NSValue **)returnValue;
/** Calls the receiver's block with the arguments from the given invocation
and sets the return value on the given invocation.
@param inv An instance of NSInvocation with values for its arguments set.
@see invokeWithInvocation:returnValue:
*/
- (void)invokeWithInvocation:(NSInvocation *)inv;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/A2BlockInvocation.m
================================================
//
// A2BlockInvocation.m
// BlocksKit
//
#import "A2BlockInvocation.h"
NSString *const A2IncompatibleMethodSignatureKey = @"incompatibleMethodSignature";
#ifndef NSFoundationVersionNumber10_8
#define NSFoundationVersionNumber10_8 945.00
#endif
#ifndef NSFoundationVersionNumber_iOS_6_0
#define NSFoundationVersionNumber_iOS_6_0 993.00
#endif
#pragma mark Block Internals
typedef NS_OPTIONS(int, BKBlockFlags) {
BKBlockFlagsHasCopyDisposeHelpers = (1 << 25),
BKBlockFlagsHasSignature = (1 << 30)
};
typedef struct _BKBlock {
__unused Class isa;
BKBlockFlags flags;
__unused int reserved;
void (__unused *invoke)(struct _BKBlock *block, ...);
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;
@interface A2BlockInvocation ()
@property (nonatomic, readonly) NSMethodSignature *blockSignature;
@end
@implementation A2BlockInvocation
/** Determines if two given signatures (block or method) are compatible.
A signature is compatible with another signature if their return types and
parameter types are equal, minus the parameter types dedicated to the Obj-C
method reciever and selector or a block literal argument.
@param signatureA Any signature object reflecting a block or method signature
@param signatureB Any signature object reflecting a block or method signature
@return YES if the given signatures may be used to dispatch for one another
*/
+ (BOOL)isSignature:(NSMethodSignature *)signatureA compatibleWithSignature:(NSMethodSignature *)signatureB __attribute__((pure))
{
if (!signatureA || !signatureB) return NO;
if ([signatureA isEqual:signatureB]) return YES;
if (signatureA.methodReturnType[0] != signatureB.methodReturnType[0]) return NO;
NSMethodSignature *methodSignature = nil, *blockSignature = nil;
if (signatureA.numberOfArguments > signatureB.numberOfArguments) {
methodSignature = signatureA;
blockSignature = signatureB;
} else if (signatureB.numberOfArguments > signatureA.numberOfArguments) {
methodSignature = signatureB;
blockSignature = signatureA;
} else {
return NO;
}
NSUInteger numberOfArguments = methodSignature.numberOfArguments;
for (NSUInteger i = 2; i < numberOfArguments; i++) {
if ([methodSignature getArgumentTypeAtIndex:i][0] != [blockSignature getArgumentTypeAtIndex:i - 1][0])
return NO;
}
return YES;
}
/** Inspects the given block literal and returns a compatible type signature.
Unlike a typical method signature, a block type signature has no `self` (`'@'`)
or `_cmd` (`':'`) parameter, but instead just one parameter for the block itself
(`'@?'`).
@param block An Objective-C block literal
@return A method signature matching the declared prototype for the block
*/
+ (NSMethodSignature *)typeSignatureForBlock:(id)block __attribute__((pure, nonnull(1)))
{
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];
}
/// Creates a method signature compatible with a given block signature.
+ (NSMethodSignature *)methodSignatureForBlockSignature:(NSMethodSignature *)original
{
if (!original) return nil;
if (original.numberOfArguments < 1) {
return nil;
}
if (original.numberOfArguments >= 2 && strcmp(@encode(SEL), [original getArgumentTypeAtIndex:1]) == 0) {
return original;
}
// initial capacity is num. arguments - 1 (@? -> @) + 1 (:) + 1 (ret type)
// optimistically assuming most signature components are char[1]
NSMutableString *signature = [[NSMutableString alloc] initWithCapacity:original.numberOfArguments + 1];
const char *retTypeStr = original.methodReturnType;
[signature appendFormat:@"%s%s%s", retTypeStr, @encode(id), @encode(SEL)];
for (NSUInteger i = 1; i < original.numberOfArguments; i++) {
const char *typeStr = [original getArgumentTypeAtIndex:i];
NSString *type = [[NSString alloc] initWithBytesNoCopy:(void *)typeStr length:strlen(typeStr) encoding:NSUTF8StringEncoding freeWhenDone:NO];
[signature appendString:type];
}
return [NSMethodSignature signatureWithObjCTypes:signature.UTF8String];
}
+ (NSMethodSignature *)methodSignatureForBlock:(id)block
{
NSMethodSignature *original = [self typeSignatureForBlock:block];
if (!original) return nil;
return [self methodSignatureForBlockSignature:original];
}
- (instancetype)initWithBlock:(id)block methodSignature:(NSMethodSignature *)methodSignature blockSignature:(NSMethodSignature *)blockSignature
{
self = [super init];
if (self) {
_block = [block copy];
_methodSignature = methodSignature;
_blockSignature = blockSignature;
}
return self;
}
- (instancetype)initWithBlock:(id)block
{
NSParameterAssert(block);
NSMethodSignature *blockSignature = [[self class] typeSignatureForBlock:block];
NSMethodSignature *methodSignature = [[self class] methodSignatureForBlockSignature:blockSignature];
NSAssert(methodSignature, @"Incompatible block: %@", block);
return (self = [self initWithBlock:block methodSignature:methodSignature blockSignature:blockSignature]);
}
- (instancetype)initWithBlock:(id)block methodSignature:(NSMethodSignature *)methodSignature
{
NSParameterAssert(block);
NSMethodSignature *blockSignature = [[self class] typeSignatureForBlock:block];
if (![[self class] isSignature:methodSignature compatibleWithSignature:blockSignature]) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Attempted to create block invocation with incompatible signatures" userInfo:@{A2IncompatibleMethodSignatureKey: methodSignature}];
}
return (self = [self initWithBlock:block methodSignature:methodSignature blockSignature:blockSignature]);
}
- (BOOL)invokeWithInvocation:(NSInvocation *)outerInv returnValue:(out NSValue **)outReturnValue setOnInvocation:(BOOL)setOnInvocation
{
NSParameterAssert(outerInv);
NSMethodSignature *sig = self.methodSignature;
if (![outerInv.methodSignature isEqual:sig]) {
NSAssert(0, @"Attempted to invoke block invocation with incompatible frame");
return NO;
}
NSInvocation *innerInv = [NSInvocation invocationWithMethodSignature:self.blockSignature];
void *argBuf = NULL;
for (NSUInteger i = 2; i < sig.numberOfArguments; i++) {
const char *type = [sig getArgumentTypeAtIndex:i];
NSUInteger argSize;
NSGetSizeAndAlignment(type, &argSize, NULL);
if (!(argBuf = reallocf(argBuf, argSize))) {
return NO;
}
[outerInv getArgument:argBuf atIndex:i];
[innerInv setArgument:argBuf atIndex:i - 1];
}
[innerInv invokeWithTarget:self.block];
NSUInteger retSize = sig.methodReturnLength;
if (retSize) {
if (outReturnValue || setOnInvocation) {
if (!(argBuf = reallocf(argBuf, retSize))) {
return NO;
}
[innerInv getReturnValue:argBuf];
if (setOnInvocation) {
[outerInv setReturnValue:argBuf];
}
if (outReturnValue) {
*outReturnValue = [NSValue valueWithBytes:argBuf objCType:sig.methodReturnType];
}
}
} else {
if (outReturnValue) {
*outReturnValue = nil;
}
}
free(argBuf);
return YES;
}
- (void)invokeWithInvocation:(NSInvocation *)inv
{
[self invokeWithInvocation:inv returnValue:NULL setOnInvocation:YES];
}
- (BOOL)invokeWithInvocation:(NSInvocation *)inv returnValue:(out NSValue **)returnValue
{
return [self invokeWithInvocation:inv returnValue:returnValue setOnInvocation:NO];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/A2DynamicDelegate.h
================================================
//
// A2DynamicDelegate.h
// BlocksKit
//
#import <Foundation/Foundation.h>
#import <BlocksKit/NSObject+A2BlockDelegate.h>
#import <BlocksKit/NSObject+A2DynamicDelegate.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.bk_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];
}
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
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/A2DynamicDelegate.m
================================================
//
// A2DynamicDelegate.m
// BlocksKit
//
#import <objc/message.h>
#import "A2BlockInvocation.h"
#import "A2DynamicDelegate.h"
Protocol *a2_dataSourceProtocol(Class cls);
Protocol *a2_delegateProtocol(Class cls);
Protocol *a2_protocolForDelegatingObject(id obj, Protocol *protocol);
static BOOL selectorsEqual(const void *item1, const void *item2, NSUInteger(*__unused size)(const void __unused *item))
{
return sel_isEqual((SEL)item1, (SEL)item2);
}
static NSString *selectorDescribe(const void *item1)
{
return NSStringFromSelector((SEL)item1);
}
@interface NSMapTable (BKAdditions)
+ (instancetype)bk_selectorsToStrongObjectsMapTable;
- (id)bk_objectForSelector:(SEL)aSEL;
- (void)bk_removeObjectForSelector:(SEL)aSEL;
- (void)bk_setObject:(id)anObject forSelector:(SEL)aSEL;
@end
@implementation NSMapTable (BKAdditions)
+ (instancetype)bk_selectorsToStrongObjectsMapTable
{
NSPointerFunctions *selectors = [NSPointerFunctions pointerFunctionsWithOptions:NSPointerFunctionsOpaqueMemory|NSPointerFunctionsOpaquePersonality];
selectors.isEqualFunction = selectorsEqual;
selectors.descriptionFunction = selectorDescribe;
NSPointerFunctions *strongObjects = [NSPointerFunctions pointerFunctionsWithOptions:NSPointerFunctionsStrongMemory|NSPointerFunctionsObjectPersonality];
return [[NSMapTable alloc] initWithKeyPointerFunctions:selectors valuePointerFunctions:strongObjects capacity:1];
}
- (id)bk_objectForSelector:(SEL)aSEL
{
void *selAsPtr = aSEL;
return [self objectForKey:(__bridge id)selAsPtr];
}
- (void)bk_removeObjectForSelector:(SEL)aSEL
{
void *selAsPtr = aSEL;
[self removeObjectForKey:(__bridge id)selAsPtr];
}
- (void)bk_setObject:(id)anObject forSelector:(SEL)aSEL
{
void *selAsPtr = aSEL;
[self setObject:anObject forKey:(__bridge id)selAsPtr];
}
@end
@interface A2DynamicClassDelegate : A2DynamicDelegate
@property (nonatomic) Class proxiedClass;
@end
#pragma mark -
@interface A2DynamicDelegate ()
@property (nonatomic) A2DynamicClassDelegate *classProxy;
@property (nonatomic, readonly) NSMapTable *invocationsBySelectors;
@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];
_invocationsBySelectors = [NSMapTable bk_selectorsToStrongObjectsMapTable];
return self;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
A2BlockInvocation *invocation = nil;
if ((invocation = [self.invocationsBySelectors bk_objectForSelector:aSelector]))
return invocation.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 = %@>", (__bridge void *)self, NSStringFromProtocol(self.protocol)];
}
- (void)forwardInvocation:(NSInvocation *)outerInv
{
SEL selector = outerInv.selector;
A2BlockInvocation *innerInv = nil;
if ((innerInv = [self.invocationsBySelectors bk_objectForSelector:selector])) {
[innerInv invokeWithInvocation:outerInv];
} else if ([self.realDelegate respondsToSelector: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.invocationsBySelectors bk_objectForSelector: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), (__bridge void *)self];
}
#pragma mark - Block Instance Method Implementations
- (id)blockImplementationForMethod:(SEL)selector
{
A2BlockInvocation *invocation = nil;
if ((invocation = [self.invocationsBySelectors bk_objectForSelector:selector]))
return invocation.block;
return NULL;
}
- (void)implementMethod:(SEL)selector withBlock:(id)block
{
NSCAssert(selector, @"Attempt to implement or remove NULL selector");
BOOL isClassMethod = self.isClassProxy;
if (!block) {
[self.invocationsBySelectors bk_removeObjectForSelector:selector];
return;
}
struct objc_method_description methodDescription = protocol_getMethodDescription(self.protocol, selector, YES, !isClassMethod);
if (!methodDescription.name) methodDescription = protocol_getMethodDescription(self.protocol, selector, NO, !isClassMethod);
A2BlockInvocation *inv = nil;
if (methodDescription.name) {
NSMethodSignature *protoSig = [NSMethodSignature signatureWithObjCTypes:methodDescription.types];
inv = [[A2BlockInvocation alloc] initWithBlock:block methodSignature:protoSig];
} else {
inv = [[A2BlockInvocation alloc] initWithBlock:block];
}
[self.invocationsBySelectors bk_setObject:inv forSelector:selector];
}
- (void)removeBlockImplementationForMethod:(SEL)selector __unused
{
[self implementMethod:selector withBlock:nil];
}
#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 __unused
{
[self.classProxy implementMethod:selector withBlock:nil];
}
@end
#pragma mark -
@implementation A2DynamicClassDelegate
- (BOOL)isClassProxy
{
return YES;
}
- (BOOL)isEqual:(id)object
{
return [super isEqual:object] || [_proxiedClass isEqual:object];
}
- (BOOL)respondsToSelector:(SEL)aSelector
{
return [self.invocationsBySelectors bk_objectForSelector:aSelector] || [_proxiedClass respondsToSelector:aSelector];
}
- (Class)class
{
return self.proxiedClass;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
A2BlockInvocation *invocation = nil;
if ((invocation = [self.invocationsBySelectors bk_objectForSelector:aSelector]))
return invocation.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 *)outerInv
{
SEL selector = outerInv.selector;
A2BlockInvocation *innerInv = nil;
if ((innerInv = [self.invocationsBySelectors bk_objectForSelector:selector])) {
[innerInv invokeWithInvocation:outerInv];
} else {
[outerInv 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
static Protocol *a2_classProtocol(Class _cls, NSString *suffix, NSString *description)
{
Class cls = _cls;
while (cls) {
NSString *className = NSStringFromClass(cls);
NSString *protocolName = [className stringByAppendingString:suffix];
Protocol *protocol = objc_getProtocol(protocolName.UTF8String);
if (protocol) return protocol;
cls = class_getSuperclass(cls);
}
NSCAssert(NO, @"Specify protocol explicitly: could not determine %@ protocol for class %@ (tried <%@>)", description, NSStringFromClass(_cls), [NSStringFromClass(_cls) stringByAppendingString:suffix]);
return nil;
}
Protocol *a2_dataSourceProtocol(Class cls)
{
return a2_classProtocol(cls, @"DataSource", @"data source");
}
Protocol *a2_delegateProtocol(Class cls)
{
return a2_classProtocol(cls, @"Delegate", @"delegate");
}
Protocol *a2_protocolForDelegatingObject(id obj, Protocol *protocol)
{
NSString *protocolName = NSStringFromProtocol(protocol);
if ([protocolName hasSuffix:@"Delegate"]) {
Protocol *p = a2_delegateProtocol([obj class]);
if (p) return p;
} else if ([protocolName hasSuffix:@"DataSource"]) {
Protocol *p = a2_dataSourceProtocol([obj class]);
if (p) return p;
}
return protocol;
}
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/Foundation/NSCache+BlocksKit.h
================================================
//
// NSCache+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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)bk_objectForKey:(id)key withGetter:(id (^)(void))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, setter = bk_setWillEvictBlock:) void (^bk_willEvictBlock)(NSCache *cache, id obj);
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/Foundation/NSCache+BlocksKit.m
================================================
//
// NSCache+BlocksKit.m
// BlocksKit
//
#import "A2DynamicDelegate.h"
#import "NSCache+BlocksKit.h"
#import "NSObject+A2BlockDelegate.h"
#pragma mark Custom delegate
@interface A2DynamicNSCacheDelegate : A2DynamicDelegate <NSCacheDelegate>
@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 bk_willEvictBlock;
+ (void)load
{
@autoreleasepool {
[self bk_registerDynamicDelegate];
[self bk_linkDelegateMethods:@{ @"bk_willEvictBlock": @"cache:willEvictObject:" }];
}
}
#pragma mark Methods
- (id)bk_objectForKey:(id)key withGetter:(id (^)(void))block
{
id object = [self objectForKey:key];
if (object) return object;
if (block) {
object = block();
[self setObject:object forKey:key];
}
return object;
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/Foundation/NSURLConnection+BlocksKit.h
================================================
//
// NSURLConnection+BlocksKit.h
// BlocksKit
//
#import <Foundation/Foundation.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 = ^(double 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, setter = setDelegate:) id delegate;
/** The block fired once the connection recieves a response from the server.
This block corresponds to the connection:didReceiveResponse: method
of NSURLConnectionDataDelegate. */
@property (nonatomic, copy, setter = bk_setResponseBlock:) void (^bk_responseBlock)(NSURLConnection *connection, NSURLResponse *response);
/** The block fired upon the failure of the connection.
This block corresponds to the connection:didFailWithError:
method of NSURLConnectionDelegate. */
@property (nonatomic, copy, setter = bk_setFailureBlock:) void (^bk_failureBlock)(NSURLConnection *connection, NSError *error);
/** 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, setter = bk_setSuccessBlock:) void (^bk_successBlock)(NSURLConnection *connection, NSURLResponse *response, NSData *responseData);
/** 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, setter = bk_setUploadBlock:) void (^bk_uploadBlock)(double percent);
/** 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, setter = bk_setDownloadBlock:) void (^bk_downloadBlock)(double percent);
/** 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 *)bk_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 *)bk_startConnectionWithRequest:(NSURLRequest *)request successHandler:(void (^)(NSURLConnection *connection, NSURLResponse *response, NSData *responseData))success failureHandler:(void (^)(NSURLConnection *connection, 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)bk_initWithRequest:(NSURLRequest *)request NS_REPLACES_RECEIVER;
/** 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)bk_initWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLConnection *connection, NSURLResponse *response, NSData *responseData))block NS_REPLACES_RECEIVER;
/** 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)bk_startWithCompletionBlock:(void (^)(NSURLConnection *connection, NSURLResponse *response, NSData *responseData))block;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/Foundation/NSURLConnection+BlocksKit.m
================================================
//
// NSURLConnection+BlocksKit.m
// BlocksKit
//
#import <objc/runtime.h>
#import "A2DynamicDelegate.h"
#import "NSObject+A2BlockDelegate.h"
#import "NSObject+A2DynamicDelegate.h"
#import "NSURLConnection+BlocksKit.h"
#pragma mark Private
static const void *BKResponseDataKey = &BKResponseDataKey;
static const void *BKResponseKey = &BKResponseKey;
static const void *BKResponseLengthKey = &BKResponseLengthKey;
@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 objc_getAssociatedObject(self, BKResponseDataKey);
}
- (void)bk_setResponseData:(NSMutableData *)responseData
{
objc_setAssociatedObject(self, BKResponseDataKey, responseData, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSURLResponse *)bk_response
{
return objc_getAssociatedObject(self, BKResponseKey);
}
- (void)bk_setResponse:(NSURLResponse *)response
{
objc_setAssociatedObject(self, BKResponseKey, response, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSUInteger)bk_responseLength
{
return [objc_getAssociatedObject(self, BKResponseLengthKey) unsignedIntegerValue];
}
- (void)bk_setResponseLength:(NSUInteger)responseLength
{
objc_setAssociatedObject(self, BKResponseLengthKey, @(responseLength), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@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 <BKURLConnectionInformalDelegate>
@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)(double) = connection.bk_downloadBlock;
if (block && connection.bk_response && connection.bk_response.expectedContentLength != NSURLResponseUnknownLength)
block((double)connection.bk_responseLength / (double)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)(double) = connection.bk_uploadBlock;
if (block) block((double)totalBytesWritten/(double)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.bk_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 <NSURLConnectionDelegate>
@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)(double) = connection.bk_downloadBlock;
if (block && connection.bk_response && connection.bk_response.expectedContentLength != NSURLResponseUnknownLength)
block((double)connection.bk_responseLength / (double)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)(double) = connection.bk_uploadBlock;
if (block)
block((double)totalBytesWritten/(double)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.bk_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, bk_responseBlock, bk_failureBlock;
+ (void)load
{
@autoreleasepool {
[self bk_registerDynamicDelegate];
[self bk_linkDelegateMethods:@{ @"bk_responseBlock": @"connection:didReceiveResponse:", @"bk_failureBlock": @"connection:didFailWithError:" }];
}
}
#pragma mark Initializers
+ (NSURLConnection*)bk_connectionWithRequest:(NSURLRequest *)request
{
return [[[self class] alloc] bk_initWithRequest:request];
}
+ (NSURLConnection *)bk_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 bk_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)bk_initWithRequest:(NSURLRequest *)request
{
return (self = [self bk_initWithRequest:request completionHandler:nil]);
}
- (id)bk_initWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLConnection *, NSURLResponse *, NSData *))block
{
Protocol *delegateProtocol = objc_getProtocol("NSURLConnectionDelegate");
if (!delegateProtocol)
delegateProtocol = @protocol(BKURLConnectionInformalDelegate);
A2DynamicDelegate *dd = [self bk_dynamicDelegateForProtocol:delegateProtocol];
if (block)
dd.handlers[kSuccessBlockKey] = [block copy];
return (self = [self initWithRequest:request delegate:dd startImmediately:NO]);
}
- (void)bk_startWithCompletionBlock:(void (^)(NSURLConnection *, NSURLResponse *, NSData *))block
{
self.bk_successBlock = block;
[self start];
}
#pragma mark Properties
- (void (^)(NSURLConnection *, NSURLResponse *, NSData *))bk_successBlock {
return [self.bk_dynamicDelegate handlers][kSuccessBlockKey];
}
- (void)bk_setSuccessBlock:(void (^)(NSURLConnection *, NSURLResponse *, NSData *))block {
if (block)
[self.bk_dynamicDelegate handlers][kSuccessBlockKey] = [block copy];
else
[[self.bk_dynamicDelegate handlers] removeObjectForKey:kSuccessBlockKey];
}
- (void (^)(double))bk_uploadBlock {
return [self.bk_dynamicDelegate handlers][kUploadBlockKey];
}
- (void)bk_setUploadBlock:(void (^)(double))block {
if (block)
[self.bk_dynamicDelegate handlers][kUploadBlockKey] = [block copy];
else
[[self.bk_dynamicDelegate handlers] removeObjectForKey:kUploadBlockKey];
}
- (void (^)(double))bk_downloadBlock {
return [self.bk_dynamicDelegate handlers][kDownloadBlockKey];
}
- (void)bk_setDownloadBlock:(void (^)(double))block {
if (block)
[self.bk_dynamicDelegate handlers][kDownloadBlockKey] = [block copy];
else
[[self.bk_dynamicDelegate handlers] removeObjectForKey:kDownloadBlockKey];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/NSObject+A2BlockDelegate.h
================================================
//
// NSObject+A2BlockDelegate.h
// BlocksKit
//
#import <Foundation/Foundation.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)bk_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)bk_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)bk_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)bk_registerDynamicDataSource;
/** Registers a dynamic delegate replacement using the property name `delegate`
and the protocol name `FooBarDelegate` for an instance of `FooBar`. */
+ (void)bk_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)bk_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)bk_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)bk_registerDynamicDelegateNamed:(NSString *)delegateName forProtocol:(Protocol *)protocol;
/** Creates or gets a dynamic delegate, assuring that it is the delegate.
@see bk_dynamicDelegate:
@return A dynamic delegate.
*/
- (id)bk_ensuredDynamicDelegate;
/** Creates or gets a dynamic protocol implementation, assuring that it is
assigned to the delegate property correspending to that protocol
@see bk_dynamicDelegateForProtocol:
@return A dynamic delegate.
*/
- (id)bk_ensuredDynamicDelegateForProtocol:(Protocol *)protocol;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/NSObject+A2BlockDelegate.m
================================================
//
// NSObject+A2BlockDelegate.m
// BlocksKit
//
#import <objc/message.h>
#import "NSObject+A2BlockDelegate.h"
#import "NSObject+A2DynamicDelegate.h"
#pragma mark - Declarations and macros
extern Protocol *a2_dataSourceProtocol(Class cls);
extern Protocol *a2_delegateProtocol(Class cls);
#pragma mark - Functions
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;
}
static Protocol *a2_protocolForDelegatingObject(id obj, Protocol *protocol)
{
NSString *protocolName = NSStringFromProtocol(protocol);
if ([protocolName hasSuffix:@"Delegate"]) {
Protocol *p = a2_delegateProtocol([obj class]);
if (p) return p;
} else if ([protocolName hasSuffix:@"DataSource"]) {
Protocol *p = a2_dataSourceProtocol([obj class]);
if (p) return p;
}
return protocol;
}
static inline BOOL isValidIMP(IMP impl) {
#if defined(__arm64__)
if (impl == NULL || impl == _objc_msgForward) return NO;
#else
if (impl == NULL || impl == _objc_msgForward || impl == (IMP)_objc_msgForward_stret) return NO;
#endif
return YES;
}
static BOOL addMethodWithIMP(Class cls, SEL oldSel, SEL newSel, IMP newIMP, const char *types, BOOL aggressive) {
if (!class_addMethod(cls, oldSel, newIMP, types)) {
return NO;
}
// We just ended up implementing a method that doesn't exist
// (-[NSURLConnection setDelegate:]) or overrode a superclass
// version (-[UIImagePickerController setDelegate:]).
IMP parentIMP = NULL;
Class superclass = class_getSuperclass(cls);
while (superclass && !isValidIMP(parentIMP)) {
parentIMP = class_getMethodImplementation(superclass, oldSel);
if (isValidIMP(parentIMP)) {
break;
} else {
parentIMP = NULL;
}
superclass = class_getSuperclass(superclass);
}
if (parentIMP) {
if (aggressive) {
return class_addMethod(cls, newSel, parentIMP, types);
}
class_replaceMethod(cls, newSel, newIMP, types);
class_replaceMethod(cls, oldSel, parentIMP, types);
}
return YES;
}
static BOOL swizzleWithIMP(Class cls, SEL oldSel, SEL newSel, IMP newIMP, const char *types, BOOL aggressive) {
Method origMethod = class_getInstanceMethod(cls, oldSel);
if (addMethodWithIMP(cls, oldSel, newSel, newIMP, types, aggressive)) {
return YES;
}
// common case, actual swap
BOOL ret = class_addMethod(cls, newSel, newIMP, types);
Method newMethod = class_getInstanceMethod(cls, newSel);
method_exchangeImplementations(origMethod, newMethod);
return ret;
}
static SEL selectorWithPattern(const char *prefix, const char *key, const char *suffix) {
size_t prefixLength = prefix ? strlen(prefix) : 0;
size_t suffixLength = suffix ? strlen(suffix) : 0;
char initial = key[0];
if (prefixLength) initial = (char)toupper(initial);
size_t initialLength = 1;
const char *rest = key + initialLength;
size_t restLength = strlen(rest);
char selector[prefixLength + initialLength + restLength + suffixLength + 1];
memcpy(selector, prefix, prefixLength);
selector[prefixLength] = initial;
memcpy(selector + prefixLength + initialLength, rest, restLength);
memcpy(selector + prefixLength + initialLength + restLength, suffix, suffixLength);
selector[prefixLength + initialLength + restLength + suffixLength] = '\0';
return sel_registerName(selector);
}
static SEL getterForProperty(objc_property_t property, const char *name)
{
if (property) {
char *getterName = property_copyAttributeValue(property, "G");
if (getterName) {
SEL getter = sel_getUid(getterName);
free(getterName);
if (getter) return getter;
}
}
const char *propertyName = property ? property_getName(property) : name;
return sel_registerName(propertyName);
}
static SEL setterForProperty(objc_property_t property, const char *name)
{
if (property) {
char *setterName = property_copyAttributeValue(property, "S");
if (setterName) {
SEL setter = sel_getUid(setterName);
free(setterName);
if (setter) return setter;
}
}
const char *propertyName = property ? property_getName(property) : name;
return selectorWithPattern("set", propertyName, ":");
}
static inline SEL prefixedSelector(SEL original) {
return selectorWithPattern("a2_", sel_getName(original), NULL);
}
#pragma mark -
typedef struct {
SEL setter;
SEL a2_setter;
SEL getter;
} A2BlockDelegateInfo;
static NSUInteger A2BlockDelegateInfoSize(const void *__unused item) {
return sizeof(A2BlockDelegateInfo);
}
static NSString *A2BlockDelegateInfoDescribe(const void *__unused item) {
if (!item) { return nil; }
const A2BlockDelegateInfo *info = item;
return [NSString stringWithFormat:@"(setter: %s, getter: %s)", sel_getName(info->setter), sel_getName(info->getter)];
}
static inline A2DynamicDelegate *getDynamicDelegate(NSObject *delegatingObject, Protocol *protocol, const A2BlockDelegateInfo *info, BOOL ensuring) {
A2DynamicDelegate *dynamicDelegate = [delegatingObject bk_dynamicDelegateForProtocol:a2_protocolForDelegatingObject(delegatingObject, protocol)];
if (!info || !info->setter || !info->getter) {
return dynamicDelegate;
}
if (!info->a2_setter && !info->setter) { return dynamicDelegate; }
id (*getterDispatch)(id, SEL) = (id (*)(id, SEL)) objc_msgSend;
id originalDelegate = getterDispatch(delegatingObject, info->getter);
if (bk_object_isKindOfClass(originalDelegate, A2DynamicDelegate.class)) { return dynamicDelegate; }
void (*setterDispatch)(id, SEL, id) = (void (*)(id, SEL, id)) objc_msgSend;
setterDispatch(delegatingObject, info->a2_setter ?: info->setter, dynamicDelegate);
return dynamicDelegate;
}
typedef A2DynamicDelegate *(^A2GetDynamicDelegateBlock)(NSObject *, BOOL);
@interface A2DynamicDelegate ()
@property (nonatomic, weak, readwrite) id realDelegate;
@end
#pragma mark -
@implementation NSObject (A2BlockDelegate)
#pragma mark Helpers
+ (NSMapTable *)bk_delegateInfoByProtocol:(BOOL)createIfNeeded
{
NSMapTable *delegateInfo = objc_getAssociatedObject(self, _cmd);
if (delegateInfo || !createIfNeeded) { return delegateInfo; }
NSPointerFunctions *protocols = [NSPointerFunctions pointerFunctionsWithOptions:NSPointerFunctionsOpaqueMemory|NSPointerFunctionsObjectPointerPersonality];
NSPointerFunctions *infoStruct = [NSPointerFunctions pointerFunctionsWithOptions:NSPointerFunctionsMallocMemory|NSPointerFunctionsStructPersonality|NSPointerFunctionsCopyIn];
infoStruct.sizeFunction = A2BlockDelegateInfoSize;
infoStruct.descriptionFunction = A2BlockDelegateInfoDescribe;
delegateInfo = [[NSMapTable alloc] initWithKeyPointerFunctions:protocols valuePointerFunctions:infoStruct capacity:0];
objc_setAssociatedObject(self, _cmd, delegateInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return delegateInfo;
}
+ (const A2BlockDelegateInfo *)bk_delegateInfoForProtocol:(Protocol *)protocol
{
A2BlockDelegateInfo *infoAsPtr = NULL;
Class cls = self;
while ((infoAsPtr == NULL || infoAsPtr->getter == NULL) && cls != nil && cls != NSObject.class) {
NSMapTable *map = [cls bk_delegateInfoByProtocol:NO];
infoAsPtr = (__bridge void *)[map objectForKey:protocol];
cls = [cls superclass];
}
NSCAssert(infoAsPtr != NULL, @"Class %@ not assigned dynamic delegate for protocol %@", NSStringFromClass(self), NSStringFromProtocol(protocol));
return infoAsPtr;
}
#pragma mark Linking block properties
+ (void)bk_linkDataSourceMethods:(NSDictionary *)dictionary
{
[self bk_linkProtocol:a2_dataSourceProtocol(self) methods:dictionary];
}
+ (void)bk_linkDelegateMethods:(NSDictionary *)dictionary
{
[self bk_linkProtocol:a2_delegateProtocol(self) methods:dictionary];
}
+ (void)bk_linkProtocol:(Protocol *)protocol methods:(NSDictionary *)dictionary
{
[dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *propertyName, NSString *selectorName, BOOL *stop) {
const char *name = propertyName.UTF8String;
objc_property_t property = class_getProperty(self, name);
NSCAssert(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(property, name);
SEL setter = setterForProperty(property, name);
if (class_respondsToSelector(self, setter) || class_respondsToSelector(self, getter)) { return; }
const A2BlockDelegateInfo *info = [self bk_delegateInfoForProtocol:protocol];
IMP getterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject) {
A2DynamicDelegate *delegate = getDynamicDelegate(delegatingObject, protocol, info, NO);
return [delegate blockImplementationForMethod:selector];
});
if (!class_addMethod(self, getter, getterImplementation, "@@:")) {
NSCAssert(NO, @"Could not implement getter for \"%@\" property.", propertyName);
}
IMP setterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject, id block) {
A2DynamicDelegate *delegate = getDynamicDelegate(delegatingObject, protocol, info, YES);
[delegate implementMethod:selector withBlock:block];
});
if (!class_addMethod(self, setter, setterImplementation, "v@:@")) {
NSCAssert(NO, @"Could not implement setter for \"%@\" property.", propertyName);
}
}];
}
#pragma mark Dynamic Delegate Replacement
+ (void)bk_registerDynamicDataSource
{
[self bk_registerDynamicDelegateNamed:@"dataSource" forProtocol:a2_dataSourceProtocol(self)];
}
+ (void)bk_registerDynamicDelegate
{
[self bk_registerDynamicDelegateNamed:@"delegate" forProtocol:a2_delegateProtocol(self)];
}
+ (void)bk_registerDynamicDataSourceNamed:(NSString *)dataSourceName
{
[self bk_registerDynamicDelegateNamed:dataSourceName forProtocol:a2_dataSourceProtocol(self)];
}
+ (void)bk_registerDynamicDelegateNamed:(NSString *)delegateName
{
[self bk_registerDynamicDelegateNamed:delegateName forProtocol:a2_delegateProtocol(self)];
}
+ (void)bk_registerDynamicDelegateNamed:(NSString *)delegateName forProtocol:(Protocol *)protocol
{
NSMapTable *propertyMap = [self bk_delegateInfoByProtocol:YES];
A2BlockDelegateInfo *infoAsPtr = (__bridge void *)[propertyMap objectForKey:protocol];
if (infoAsPtr != NULL) { return; }
const char *name = delegateName.UTF8String;
objc_property_t property = class_getProperty(self, name);
SEL setter = setterForProperty(property, name);
SEL a2_setter = prefixedSelector(setter);
SEL getter = getterForProperty(property, name);
A2BlockDelegateInfo info = {
setter, a2_setter, getter
};
[propertyMap setObject:(__bridge id)&info forKey:protocol];
infoAsPtr = (__bridge void *)[propertyMap objectForKey:protocol];
IMP setterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject, id delegate) {
A2DynamicDelegate *dynamicDelegate = getDynamicDelegate(delegatingObject, protocol, infoAsPtr, YES);
if ([delegate isEqual:dynamicDelegate]) {
delegate = nil;
}
dynamicDelegate.realDelegate = delegate;
});
if (!swizzleWithIMP(self, setter, a2_setter, setterImplementation, "v@:@", YES)) {
bzero(infoAsPtr, sizeof(A2BlockDelegateInfo));
return;
}
if (![self instancesRespondToSelector:getter]) {
IMP getterImplementation = imp_implementationWithBlock(^(NSObject *delegatingObject) {
return [delegatingObject bk_dynamicDelegateForProtocol:a2_protocolForDelegatingObject(delegatingObject, protocol)];
});
addMethodWithIMP(self, getter, NULL, getterImplementation, "@@:", NO);
}
}
- (id)bk_ensuredDynamicDelegate
{
Protocol *protocol = a2_delegateProtocol(self.class);
return [self bk_ensuredDynamicDelegateForProtocol:protocol];
}
- (id)bk_ensuredDynamicDelegateForProtocol:(Protocol *)protocol
{
const A2BlockDelegateInfo *info = [self.class bk_delegateInfoForProtocol:protocol];
return getDynamicDelegate(self, protocol, info, YES);
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/NSObject+A2DynamicDelegate.h
================================================
//
// NSObject+A2DynamicDelegate.h
// BlocksKit
//
#import <BlocksKit/A2DynamicDelegate.h>
#import <Foundation/Foundation.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)bk_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)bk_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)bk_dynamicDelegateForProtocol:(Protocol *)protocol;
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/DynamicDelegate/NSObject+A2DynamicDelegate.m
================================================
//
// NSObject+A2DynamicDelegate.m
// BlocksKit
//
#import <objc/runtime.h>
#import "NSObject+A2DynamicDelegate.h"
extern Protocol *a2_dataSourceProtocol(Class cls);
extern Protocol *a2_delegateProtocol(Class cls);
static Class a2_dynamicDelegateClass(Class cls, NSString *suffix)
{
while (cls) {
NSString *className = [NSString stringWithFormat:@"A2Dynamic%@%@", NSStringFromClass(cls), suffix];
Class ddClass = NSClassFromString(className);
if (ddClass) return ddClass;
cls = class_getSuperclass(cls);
}
return [A2DynamicDelegate class];
}
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("BlocksKit.DynamicDelegate.Queue", DISPATCH_QUEUE_SERIAL);
});
return backgroundQueue;
}
@implementation NSObject (A2DynamicDelegate)
- (id)bk_dynamicDataSource
{
Protocol *protocol = a2_dataSourceProtocol([self class]);
Class class = a2_dynamicDelegateClass([self class], @"DataSource");
return [self bk_dynamicDelegateWithClass:class forProtocol:protocol];
}
- (id)bk_dynamicDelegate
{
Protocol *protocol = a2_delegateProtocol([self class]);
Class class = a2_dynamicDelegateClass([self class], @"Delegate");
return [self bk_dynamicDelegateWithClass:class forProtocol:protocol];
}
- (id)bk_dynamicDelegateForProtocol:(Protocol *)protocol
{
Class class = [A2DynamicDelegate class];
NSString *protocolName = NSStringFromProtocol(protocol);
if ([protocolName hasSuffix:@"Delegate"]) {
class = a2_dynamicDelegateClass([self class], @"Delegate");
} else if ([protocolName hasSuffix:@"DataSource"]) {
class = a2_dynamicDelegateClass([self class], @"DataSource");
}
return [self bk_dynamicDelegateWithClass:class forProtocol:protocol];
}
- (id)bk_dynamicDelegateWithClass:(Class)cls forProtocol:(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 = objc_getAssociatedObject(self, (__bridge const void *)protocol);
if (!dynamicDelegate)
{
dynamicDelegate = [[cls alloc] initWithProtocol:protocol];
objc_setAssociatedObject(self, (__bridge const void *)protocol, dynamicDelegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
});
return dynamicDelegate;
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.h
================================================
//
// MFMailComposeViewController+BlocksKit.h
// BlocksKit
//
#import <MessageUI/MessageUI.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 MFMailComposeViewController is only available on a platform with MessageUI.
*/
@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, setter = bk_setCompletionBlock:) void (^bk_completionBlock)(MFMailComposeViewController *controller, MFMailComposeResult result, NSError *error);
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.m
================================================
//
// MFMailComposeViewController+BlocksKit.m
// BlocksKit
//
#import "A2DynamicDelegate.h"
#import "MFMailComposeViewController+BlocksKit.h"
#import "NSObject+A2BlockDelegate.h"
#pragma mark Custom delegate
@interface A2DynamicMFMailComposeViewControllerDelegate : A2DynamicDelegate <MFMailComposeViewControllerDelegate>
@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 (shouldDismiss) {
if (block) block(controller, result, error);
} else {
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000
__weak typeof(controller) weakController = controller;
[controller dismissViewControllerAnimated:YES completion:^{
typeof(&*weakController) strongController = weakController;
if (block) block(strongController, result, error);
}];
#else
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
if ([controller respondsToSelector:@selector(dismissViewControllerAnimated:completion:)]) {
__weak typeof(controller) weakController = controller;
[controller dismissViewControllerAnimated:YES completion:^{
typeof(&*weakController) strongController = weakController;
if (block) block(strongController, result, error);
}];
} else {
#endif
[controller dismissModalViewControllerAnimated:YES];
if (block) block(controller, result, error);
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
}
#endif
#endif
}
}
@end
#pragma mark Category
@implementation MFMailComposeViewController (BlocksKit)
@dynamic bk_completionBlock;
+ (void)load
{
@autoreleasepool {
[self bk_registerDynamicDelegateNamed:@"mailComposeDelegate"];
[self bk_linkDelegateMethods:@{ @"bk_completionBlock": @"mailComposeController:didFinishWithResult:error:" }];
}
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.h
================================================
//
// MFMessageComposeViewController+BlocksKit.h
// BlocksKit
//
#import <MessageUI/MessageUI.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 MFMessageComposeViewController is only available on a platform with MessageUI.
*/
@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, setter = bk_setCompletionBlock:) void (^bk_completionBlock)(MFMessageComposeViewController *controller, MessageComposeResult result);
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.m
================================================
//
// MFMessageComposeViewController+BlocksKit.m
// BlocksKit
//
#import "A2DynamicDelegate.h"
#import "MFMessageComposeViewController+BlocksKit.h"
#import "NSObject+A2BlockDelegate.h"
#pragma mark Custom delegate
@interface A2DynamicMFMessageComposeViewControllerDelegate : A2DynamicDelegate <MFMessageComposeViewControllerDelegate>
@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 (shouldDismiss) {
if (block) block(controller, result);
} else {
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000
__weak typeof(controller) weakController = controller;
[controller dismissViewControllerAnimated:YES completion:^{
typeof(&*weakController) strongController = weakController;
if (block) block(strongController, result);
}];
#else
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
if ([controller respondsToSelector:@selector(dismissViewControllerAnimated:completion:)]) {
__weak typeof(controller) weakController = controller;
[controller dismissViewControllerAnimated:YES completion:^{
typeof(&*weakController) strongController = weakController;
if (block) block(strongController, result);
}];
} else {
#endif
[controller dismissModalViewControllerAnimated:YES];
if (block) block(controller, result);
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
}
#endif
#endif
}
}
@end
#pragma mark - Category
@implementation MFMessageComposeViewController (BlocksKit)
@dynamic bk_completionBlock;
+ (void)load
{
@autoreleasepool {
[self bk_registerDynamicDelegateNamed:@"messageComposeDelegate"];
[self bk_linkDelegateMethods:@{ @"bk_completionBlock": @"messageComposeViewController:didFinishWithResult:" }];
}
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.h
================================================
//
// UIActionSheet+BlocksKit.h
// BlocksKit
//
#import <UIKit/UIKit.h>
/** UIActionSheet without delegates!
This set of extensions and convenience classes allows
for an instance of UIActionSheet without the implementation
of a delegate. Any time you instantiate a UIActionSheet
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)bk_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)bk_initWithTitle:(NSString *)title NS_REPLACES_RECEIVER;
///-----------------------------------
/// @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)bk_addButtonWithTitle:(NSString *)title handler:(void (^)(void))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)bk_setDestructiveButtonWithTitle:(NSString *)title handler:(void (^)(void))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)bk_setCancelButtonWithTitle:(NSString *)title handler:(void (^)(void))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)bk_setHandler:(void (^)(void))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.
*/
- (void (^)(void))bk_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, setter = bk_setCancelBlock:) void (^bk_cancelBlock)(void);
/** The block to be fired before the action sheet will show. */
@property (nonatomic, copy, setter = bk_setWillShowBlock:) void (^bk_willShowBlock)(UIActionSheet *actionSheet);
/** The block to be fired when the action sheet shows. */
@property (nonatomic, copy, setter = bk_setDidShowBlock:) void (^bk_didShowBlock)(UIActionSheet *actionSheet);
/** The block to be fired before the action sheet will dismiss. */
@property (nonatomic, copy, setter = bk_setWillDismissBlock:) void (^bk_willDismissBlock)(UIActionSheet *actionSheet, NSInteger buttonIndex);
/** The block to be fired after the action sheet dismisses. */
@property (nonatomic, copy, setter = bk_setDidDismissBlock:) void (^bk_didDismissBlock)(UIActionSheet *actionSheet, NSInteger buttonIndex);
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.m
================================================
//
// UIActionSheet+BlocksKit.m
// BlocksKit
//
#import "NSObject+A2BlockDelegate.h"
#import "NSObject+A2DynamicDelegate.h"
#import "UIActionSheet+BlocksKit.h"
#pragma mark Custom delegate
@interface A2DynamicUIActionSheetDelegate : A2DynamicDelegate <UIActionSheetDelegate>
@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];
void (^block)(void) = self.handlers[@(buttonIndex)];
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];
void (^block)(void) = actionSheet.bk_cancelBlock;
if (block) block();
}
@end
#pragma mark - Category
@implementation UIActionSheet (BlocksKit)
@dynamic bk_willShowBlock, bk_didShowBlock, bk_willDismissBlock, bk_didDismissBlock;
+ (void)load
{
@autoreleasepool {
[self bk_registerDynamicDelegate];
[self bk_linkDelegateMethods:@{
@"bk_willShowBlock": @"willPresentActionSheet:",
@"bk_didShowBlock": @"didPresentActionSheet:",
@"bk_willDismissBlock": @"actionSheet:willDismissWithButtonIndex:",
@"bk_didDismissBlock": @"actionSheet:didDismissWithButtonIndex:"
}];
}
}
#pragma mark Initializers
+ (id)bk_actionSheetWithTitle:(NSString *)title {
return [[[self class] alloc] bk_initWithTitle:title];
}
- (id)bk_initWithTitle:(NSString *)title {
self = [self initWithTitle:title delegate:self.bk_dynamicDelegate cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
if (!self) { return nil; }
self.delegate = self.bk_dynamicDelegate;
return self;
}
#pragma mark Actions
- (NSInteger)bk_addButtonWithTitle:(NSString *)title handler:(void (^)(void))block {
NSAssert(title.length, @"A button without a title cannot be added to an action sheet.");
NSInteger index = [self addButtonWithTitle:title];
[self bk_setHandler:block forButtonAtIndex:index];
return index;
}
- (NSInteger)bk_setDestructiveButtonWithTitle:(NSString *)title handler:(void (^)(void))block {
NSInteger index = [self bk_addButtonWithTitle:title handler:block];
self.destructiveButtonIndex = index;
return index;
}
- (NSInteger)bk_setCancelButtonWithTitle:(NSString *)title handler:(void (^)(void))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 bk_setHandler:block forButtonAtIndex:cancelButtonIndex];
self.cancelButtonIndex = cancelButtonIndex;
return cancelButtonIndex;
}
#pragma mark Properties
- (void)bk_setHandler:(void (^)(void))block forButtonAtIndex:(NSInteger)index {
A2DynamicUIActionSheetDelegate *delegate = self.bk_ensuredDynamicDelegate;
if (block) {
delegate.handlers[@(index)] = [block copy];
} else {
[delegate.handlers removeObjectForKey:@(index)];
}
}
- (void (^)(void))bk_handlerForButtonAtIndex:(NSInteger)index
{
return [self.bk_dynamicDelegate handlers][@(index)];
}
- (void (^)(void))bk_cancelBlock
{
return [self bk_handlerForButtonAtIndex:self.cancelButtonIndex];
}
- (void)bk_setCancelBlock:(void (^)(void))block
{
[self bk_setHandler:block forButtonAtIndex:self.cancelButtonIndex];
}
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.h
================================================
//
// UIAlertView+BlocksKit.h
// BlocksKit
//
#import <UIKit/UIKit.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.
@return The UIAlertView.
*/
+ (UIAlertView*)bk_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)bk_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)bk_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)bk_initWithTitle:(NSString *)title message:(NSString *)message NS_REPLACES_RECEIVER;
///-----------------------------------
/// @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)bk_addButtonWithTitle:(NSString *)title handler:(void (^)(void))block;
/** Set the title and trigger of the cancel button.
@param title The text of the button.
@param block A block of code.
*/
- (NSInteger)bk_setCancelButtonWithTitle:(NSString *)title handler:(void (^)(void))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)bk_setHandler:(void (^)(void))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.
*/
- (void (^)(void))bk_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, setter = bk_setCancelBlock:) void (^bk_cancelBlock)(void);
/** The block to be fired before the alert view will show. */
@property (nonatomic, copy, setter = bk_setWillShowBlock:) void (^bk_willShowBlock)(UIAlertView *alertView);
/** The block to be fired when the alert view shows. */
@property (nonatomic, copy, setter = bk_setDidShowBlock:) void (^bk_didShowBlock)(UIAlertView *alertView);
/** The block to be fired before the alert view will dismiss. */
@property (nonatomic, copy, setter = bk_setWillDismissBlock:) void (^bk_willDismissBlock)(UIAlertView *alertView, NSInteger buttonIndex);
/** The block to be fired after the alert view dismisses. */
@property (nonatomic, copy, setter = bk_setDidDismissBlock:) void (^bk_didDismissBlock)(UIAlertView *alertView, NSInteger buttonIndex);
/** The block to be fired to determine whether the first non-cancel should be enabled */
@property (nonatomic, copy, setter = bk_SetShouldEnableFirstOtherButtonBlock:) BOOL (^bk_shouldEnableFirstOtherButtonBlock)(UIAlertView *alertView) NS_AVAILABLE_IOS(5_0);
@end
================================================
FILE: Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.m
================================================
//
// UIAlertView+BlocksKit.m
// BlocksKit
//
#import "A2DynamicDelegate.h"
#import "NSObject+A2BlockDelegate.h"
#import "NSObject+A2DynamicDelegate.h"
#import "UIAlertView+BlocksKit.h"
#pragma mark Delegate
@interface A2DynamicUIAlertViewDelegate : A2DynamicDelegate <UIAlertViewDelegate>
@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);
void (^cancelBlock)(void) = (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 didDism
gitextract_v1bw8za9/
├── Podfile
├── Pods/
│ ├── BlocksKit/
│ │ ├── BlocksKit/
│ │ │ ├── BlocksKit+MessageUI.h
│ │ │ ├── BlocksKit+UIKit.h
│ │ │ ├── BlocksKit.h
│ │ │ ├── Core/
│ │ │ │ ├── BKMacros.h
│ │ │ │ ├── NSArray+BlocksKit.h
│ │ │ │ ├── NSArray+BlocksKit.m
│ │ │ │ ├── NSDictionary+BlocksKit.h
│ │ │ │ ├── NSDictionary+BlocksKit.m
│ │ │ │ ├── NSIndexSet+BlocksKit.h
│ │ │ │ ├── NSIndexSet+BlocksKit.m
│ │ │ │ ├── NSInvocation+BlocksKit.h
│ │ │ │ ├── NSInvocation+BlocksKit.m
│ │ │ │ ├── NSMutableArray+BlocksKit.h
│ │ │ │ ├── NSMutableArray+BlocksKit.m
│ │ │ │ ├── NSMutableDictionary+BlocksKit.h
│ │ │ │ ├── NSMutableDictionary+BlocksKit.m
│ │ │ │ ├── NSMutableIndexSet+BlocksKit.h
│ │ │ │ ├── NSMutableIndexSet+BlocksKit.m
│ │ │ │ ├── NSMutableOrderedSet+BlocksKit.h
│ │ │ │ ├── NSMutableOrderedSet+BlocksKit.m
│ │ │ │ ├── NSMutableSet+BlocksKit.h
│ │ │ │ ├── NSMutableSet+BlocksKit.m
│ │ │ │ ├── NSObject+BKAssociatedObjects.h
│ │ │ │ ├── NSObject+BKAssociatedObjects.m
│ │ │ │ ├── NSObject+BKBlockExecution.h
│ │ │ │ ├── NSObject+BKBlockExecution.m
│ │ │ │ ├── NSObject+BKBlockObservation.h
│ │ │ │ ├── NSObject+BKBlockObservation.m
│ │ │ │ ├── NSOrderedSet+BlocksKit.h
│ │ │ │ ├── NSOrderedSet+BlocksKit.m
│ │ │ │ ├── NSSet+BlocksKit.h
│ │ │ │ ├── NSSet+BlocksKit.m
│ │ │ │ ├── NSTimer+BlocksKit.h
│ │ │ │ └── NSTimer+BlocksKit.m
│ │ │ ├── DynamicDelegate/
│ │ │ │ ├── A2BlockInvocation.h
│ │ │ │ ├── A2BlockInvocation.m
│ │ │ │ ├── A2DynamicDelegate.h
│ │ │ │ ├── A2DynamicDelegate.m
│ │ │ │ ├── Foundation/
│ │ │ │ │ ├── NSCache+BlocksKit.h
│ │ │ │ │ ├── NSCache+BlocksKit.m
│ │ │ │ │ ├── NSURLConnection+BlocksKit.h
│ │ │ │ │ └── NSURLConnection+BlocksKit.m
│ │ │ │ ├── NSObject+A2BlockDelegate.h
│ │ │ │ ├── NSObject+A2BlockDelegate.m
│ │ │ │ ├── NSObject+A2DynamicDelegate.h
│ │ │ │ └── NSObject+A2DynamicDelegate.m
│ │ │ ├── MessageUI/
│ │ │ │ ├── MFMailComposeViewController+BlocksKit.h
│ │ │ │ ├── MFMailComposeViewController+BlocksKit.m
│ │ │ │ ├── MFMessageComposeViewController+BlocksKit.h
│ │ │ │ └── MFMessageComposeViewController+BlocksKit.m
│ │ │ └── UIKit/
│ │ │ ├── UIActionSheet+BlocksKit.h
│ │ │ ├── UIActionSheet+BlocksKit.m
│ │ │ ├── UIAlertView+BlocksKit.h
│ │ │ ├── UIAlertView+BlocksKit.m
│ │ │ ├── UIBarButtonItem+BlocksKit.h
│ │ │ ├── UIBarButtonItem+BlocksKit.m
│ │ │ ├── UIControl+BlocksKit.h
│ │ │ ├── UIControl+BlocksKit.m
│ │ │ ├── UIGestureRecognizer+BlocksKit.h
│ │ │ ├── UIGestureRecognizer+BlocksKit.m
│ │ │ ├── UIImagePickerController+BlocksKit.h
│ │ │ ├── UIImagePickerController+BlocksKit.m
│ │ │ ├── UIPopoverController+BlocksKit.h
│ │ │ ├── UIPopoverController+BlocksKit.m
│ │ │ ├── UITextField+BlocksKit.h
│ │ │ ├── UITextField+BlocksKit.m
│ │ │ ├── UIView+BlocksKit.h
│ │ │ ├── UIView+BlocksKit.m
│ │ │ ├── UIWebView+BlocksKit.h
│ │ │ └── UIWebView+BlocksKit.m
│ │ ├── LICENSE
│ │ └── README.md
│ ├── Local Podspecs/
│ │ └── NBSwipePageView.podspec.json
│ ├── NBSwipePageView/
│ │ ├── NBSwipePageView/
│ │ │ ├── NBSwipePageView.h
│ │ │ ├── NBSwipePageView.m
│ │ │ ├── NBSwipePageViewSheet.h
│ │ │ └── NBSwipePageViewSheet.m
│ │ └── README.md
│ ├── Pods.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── xcuserdata/
│ │ ├── vipstore.xcuserdatad/
│ │ │ └── xcschemes/
│ │ │ ├── BlocksKit.xcscheme
│ │ │ ├── NBSwipePageView.xcscheme
│ │ │ ├── Pods-testPasterImage.xcscheme
│ │ │ └── xcschememanagement.plist
│ │ └── wangyingbo.xcuserdatad/
│ │ └── xcschemes/
│ │ ├── BlocksKit.xcscheme
│ │ ├── NBSwipePageView.xcscheme
│ │ ├── Pods-testPasterImage.xcscheme
│ │ └── xcschememanagement.plist
│ └── Target Support Files/
│ ├── BlocksKit/
│ │ ├── BlocksKit-dummy.m
│ │ ├── BlocksKit-prefix.pch
│ │ └── BlocksKit.xcconfig
│ ├── NBSwipePageView/
│ │ ├── NBSwipePageView-dummy.m
│ │ ├── NBSwipePageView-prefix.pch
│ │ └── NBSwipePageView.xcconfig
│ └── Pods-testPasterImage/
│ ├── Pods-testPasterImage-acknowledgements.markdown
│ ├── Pods-testPasterImage-acknowledgements.plist
│ ├── Pods-testPasterImage-dummy.m
│ ├── Pods-testPasterImage-frameworks.sh
│ ├── Pods-testPasterImage-resources.sh
│ ├── Pods-testPasterImage.debug.xcconfig
│ └── Pods-testPasterImage.release.xcconfig
├── README.md
├── files/
│ └── README发帖专用.md
├── testPasterImage/
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets/
│ │ ├── 1.imageset/
│ │ │ └── Contents.json
│ │ ├── 2.imageset/
│ │ │ └── Contents.json
│ │ ├── 3.imageset/
│ │ │ └── Contents.json
│ │ ├── 4.imageset/
│ │ │ └── Contents.json
│ │ ├── 5.imageset/
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── bt_paster_delete.imageset/
│ │ │ └── Contents.json
│ │ ├── bt_paster_transform.imageset/
│ │ │ └── Contents.json
│ │ ├── dogs.imageset/
│ │ │ └── Contents.json
│ │ ├── gao4.imageset/
│ │ │ └── Contents.json
│ │ └── gaoyuanyuan.imageset/
│ │ └── Contents.json
│ ├── Base.lproj/
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Categories/
│ │ ├── UIImage+AddFunction.h
│ │ ├── UIImage+AddFunction.m
│ │ ├── UIViewController+Example.h
│ │ ├── UIViewController+Example.m
│ │ ├── UIViewController+Extension.h
│ │ ├── UIViewController+Extension.m
│ │ ├── UIViewController+Swizzling.h
│ │ └── UIViewController+Swizzling.m
│ ├── Controllers/
│ │ ├── ViewController.h
│ │ ├── ViewController.m
│ │ ├── YBBaseViewController.h
│ │ ├── YBBaseViewController.m
│ │ ├── YBPasterImageVC.h
│ │ └── YBPasterImageVC.m
│ ├── Info.plist
│ ├── Libs/
│ │ └── FilterImageLibs/
│ │ ├── ColorMatrix.h
│ │ ├── ImageUtil.h
│ │ ├── ImageUtil.m
│ │ └── UIImage-Extensions/
│ │ ├── .svn/
│ │ │ ├── entries
│ │ │ ├── format
│ │ │ └── pristine/
│ │ │ ├── 06/
│ │ │ │ └── 062d14b8b3d1573c2d8c9d30257fd9b0b84bd59c.svn-base
│ │ │ ├── 39/
│ │ │ │ └── 3944926a8fe582382d834a9fecb902c171a9a76e.svn-base
│ │ │ ├── 43/
│ │ │ │ └── 43a6e58f03ebdbe417f3c5028d4dc1b936e030b4.svn-base
│ │ │ ├── 5d/
│ │ │ │ └── 5deb2d07c4dd4089e7ade0df1f5278a51efb71cf.svn-base
│ │ │ ├── 74/
│ │ │ │ └── 7403967df71a9ffaa67500af6a610523742bfd53.svn-base
│ │ │ ├── 9e/
│ │ │ │ └── 9e08c4f172f233df24ad098fd5059cdaf5ad8268.svn-base
│ │ │ ├── a3/
│ │ │ │ └── a31a6fddf40b76b94df05097d799e55a769d8440.svn-base
│ │ │ ├── be/
│ │ │ │ └── becc3c813720214cae048c91b03d26dba76ff1ca.svn-base
│ │ │ ├── c8/
│ │ │ │ └── c8496f35a02cbd4ef1b2a81af9b5ca802b339a3a.svn-base
│ │ │ ├── d8/
│ │ │ │ └── d878290233a5ccddb800ee8a4f409b373e187859.svn-base
│ │ │ ├── dc/
│ │ │ │ └── dc06ddf7d7a2ad296ab0a741fcc7c3bc6d34b0e3.svn-base
│ │ │ └── ee/
│ │ │ └── ee255ad5f9f4f575fb733f734606d7eb9e0efeac.svn-base
│ │ ├── UIImage+Alpha.h
│ │ ├── UIImage+Alpha.m
│ │ ├── UIImage+Cut.h
│ │ ├── UIImage+Cut.m
│ │ ├── UIImage+Resize.h
│ │ ├── UIImage+Resize.m
│ │ ├── UIImage+RoundedCorner.h
│ │ ├── UIImage+RoundedCorner.m
│ │ ├── UIImage+SplitImageIntoTwoParts.h
│ │ └── UIImage+SplitImageIntoTwoParts.m
│ ├── Views/
│ │ ├── YBCustomViews/
│ │ │ ├── YBCustomButton.h
│ │ │ └── YBCustomButton.m
│ │ ├── YBFilterImage/
│ │ │ ├── YBFilterScrollView.h
│ │ │ └── YBFilterScrollView.m
│ │ └── YBPasterImage/
│ │ ├── YBPasterScrollView.h
│ │ ├── YBPasterScrollView.m
│ │ ├── YBPasterView.h
│ │ └── YBPasterView.m
│ └── main.m
├── testPasterImage.xcodeproj/
│ ├── project.pbxproj
│ ├── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata/
│ │ ├── vipstore.xcuserdatad/
│ │ │ └── UserInterfaceState.xcuserstate
│ │ └── wangyingbo.xcuserdatad/
│ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata/
│ ├── vipstore.xcuserdatad/
│ │ ├── xcdebugger/
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes/
│ │ ├── testPasterImage.xcscheme
│ │ └── xcschememanagement.plist
│ └── wangyingbo.xcuserdatad/
│ └── xcschemes/
│ ├── testPasterImage.xcscheme
│ └── xcschememanagement.plist
├── testPasterImage.xcworkspace/
│ ├── contents.xcworkspacedata
│ ├── xcshareddata/
│ │ └── testPasterImage.xcscmblueprint
│ └── xcuserdata/
│ ├── vipstore.xcuserdatad/
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── xcdebugger/
│ │ └── Breakpoints_v2.xcbkptlist
│ └── wangyingbo.xcuserdatad/
│ └── UserInterfaceState.xcuserstate
├── testPasterImageTests/
│ ├── Info.plist
│ └── testPasterImageTests.m
└── testPasterImageUITests/
├── Info.plist
└── testPasterImageUITests.m
SYMBOL INDEX (4 symbols across 3 files)
FILE: Pods/BlocksKit/BlocksKit/Core/BKMacros.h
function id (line 41) | static inline id BKNextHelper(NSArray *array, CFMutableDictionaryRef *ea...
FILE: Pods/NBSwipePageView/NBSwipePageView/NBSwipePageView.h
type NBSwipePageViewPageAnimation (line 12) | typedef enum {
type NBSwipePageViewMode (line 23) | typedef enum {
FILE: Pods/NBSwipePageView/NBSwipePageView/NBSwipePageViewSheet.h
type NBSwipePageViewSheetEditingStyle (line 11) | typedef enum {
Condensed preview — 188 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (614K chars).
[
{
"path": "Podfile",
"chars": 161,
"preview": "platform :ios, '8.0'\ntarget 'testPasterImage' do\n\npod 'BlocksKit', '~> 2.2.5'\npod 'NBSwipePageView', :git => 'https://gi"
},
{
"path": "Pods/BlocksKit/BlocksKit/BlocksKit+MessageUI.h",
"chars": 1411,
"preview": "//\n// BlocksKit+MessageUI\n//\n// The Objective-C block utilities you always wish you had.\n//\n// Copyright (c) 2011-201"
},
{
"path": "Pods/BlocksKit/BlocksKit/BlocksKit+UIKit.h",
"chars": 1793,
"preview": "//\n// BlocksKit+UIKit\n//\n// The Objective-C block utilities you always wish you had.\n//\n// Copyright (c) 2011-2012, 2"
},
{
"path": "Pods/BlocksKit/BlocksKit/BlocksKit.h",
"chars": 2000,
"preview": "//\n// BlocksKit\n//\n// The Objective-C block utilities you always wish you had.\n//\n// Copyright (c) 2011-2012, 2013-20"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/BKMacros.h",
"chars": 2906,
"preview": "//\n// BKMacros.h\n// BlocksKit\n//\n// Includes code by Michael Ash. <https://github.com/mikeash>.\n//\n\n#import \"NSArray+"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSArray+BlocksKit.h",
"chars": 7336,
"preview": "//\n// NSArray+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n#import <CoreGraphics/CGBase.h>\n\n/** Bloc"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSArray+BlocksKit.m",
"chars": 3140,
"preview": "//\n// NSArray+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSArray+BlocksKit.h\"\n\n@implementation NSArray (BlocksKit)\n\n- (void"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSDictionary+BlocksKit.h",
"chars": 3926,
"preview": "//\n// NSDictionary+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extension for NSDictionar"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSDictionary+BlocksKit.m",
"chars": 2108,
"preview": "//\n// NSDictionary+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSDictionary+BlocksKit.h\"\n\n@implementation NSDictionary (Bloc"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSIndexSet+BlocksKit.h",
"chars": 4192,
"preview": "//\n// NSIndexSet+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extensions for NSIndexSet.\n"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSIndexSet+BlocksKit.m",
"chars": 2228,
"preview": "//\n// NSIndexSet+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSIndexSet+BlocksKit.h\"\n\n@implementation NSIndexSet (BlocksKit)"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSInvocation+BlocksKit.h",
"chars": 1091,
"preview": "//\n// NSInvocation+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** BlocksKit extensions for NSInvo"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSInvocation+BlocksKit.m",
"chars": 1091,
"preview": "//\n// NSInvocation+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSInvocation+BlocksKit.h\"\n\n@interface BKInvocationGrabber : N"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableArray+BlocksKit.h",
"chars": 1418,
"preview": "//\n// NSMutableArray+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extensions for NSMutabl"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableArray+BlocksKit.m",
"chars": 906,
"preview": "//\n// NSMutableArray+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSMutableArray+BlocksKit.h\"\n\n@implementation NSMutableArray"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableDictionary+BlocksKit.h",
"chars": 1369,
"preview": "//\n// NSMutableDictionary+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extensions for NSM"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableDictionary+BlocksKit.m",
"chars": 977,
"preview": "//\n// NSMutableDictionary+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSMutableDictionary+BlocksKit.h\"\n\n@implementation NSMu"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableIndexSet+BlocksKit.h",
"chars": 1205,
"preview": "//\n// NSMutableIndexSet+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extensions for NSMut"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableIndexSet+BlocksKit.m",
"chars": 890,
"preview": "//\n// NSMutableIndexSet+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSMutableIndexSet+BlocksKit.h\"\n\n@implementation NSMutabl"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableOrderedSet+BlocksKit.h",
"chars": 1473,
"preview": "//\n// NSMutableOrderedSet+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extensions for NSM"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableOrderedSet+BlocksKit.m",
"chars": 1102,
"preview": "//\n// NSMutableOrderedSet+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSMutableOrderedSet+BlocksKit.h\"\n\n@implementation NSMu"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableSet+BlocksKit.h",
"chars": 1373,
"preview": "//\n// NSMutableSet+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extensions for NSMutableS"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSMutableSet+BlocksKit.m",
"chars": 798,
"preview": "//\n// NSMutableSet+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSMutableSet+BlocksKit.h\"\n\n@implementation NSMutableSet (Bloc"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSObject+BKAssociatedObjects.h",
"chars": 5162,
"preview": "//\n// NSObject+BKAssociatedObjects.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Objective-C wrapper for 1"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSObject+BKAssociatedObjects.m",
"chars": 2819,
"preview": "//\n// NSObject+BKAssociatedObjects.m\n// BlocksKit\n//\n\n#import <objc/runtime.h>\n#import \"NSObject+BKAssociatedObjects.h"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSObject+BKBlockExecution.h",
"chars": 4591,
"preview": "//\n// NSObject+BKBlockExecution.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block execution on *any* obj"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSObject+BKBlockExecution.m",
"chars": 1942,
"preview": "//\n// NSObject+BKBlockExecution.m\n// BlocksKit\n//\n\n#import \"NSObject+BKBlockExecution.h\"\n\n#define BKTimeDelay(t) dispa"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSObject+BKBlockObservation.h",
"chars": 5834,
"preview": "//\n// NSObject+BKBlockObservation.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Blocks wrapper for key-val"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSObject+BKBlockObservation.m",
"chars": 9879,
"preview": "//\n// NSObject+BKBlockObservation.m\n// BlocksKit\n//\n\n#import <objc/runtime.h>\n#import <objc/message.h>\n#import \"NSArra"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSOrderedSet+BlocksKit.h",
"chars": 6114,
"preview": "//\n// NSOrderedSet+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extensions for NSOrderedS"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSOrderedSet+BlocksKit.m",
"chars": 2698,
"preview": "//\n// NSOrderedSet+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSOrderedSet+BlocksKit.h\"\n\n@implementation NSOrderedSet (Bloc"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSSet+BlocksKit.h",
"chars": 4572,
"preview": "//\n// NSSet+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Block extensions for NSSet.\n\n Both ins"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSSet+BlocksKit.m",
"chars": 1991,
"preview": "//\n// NSSet+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSSet+BlocksKit.h\"\n\n@implementation NSSet (BlocksKit)\n\n- (void)bk_ea"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSTimer+BlocksKit.h",
"chars": 1655,
"preview": "//\n// NSTimer+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** Simple category on NSTimer to give i"
},
{
"path": "Pods/BlocksKit/BlocksKit/Core/NSTimer+BlocksKit.m",
"chars": 992,
"preview": "//\n// NSTimer+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSTimer+BlocksKit.h\"\n\n@interface NSTimer (BlocksKitPrivate)\n\n+ (vo"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/A2BlockInvocation.h",
"chars": 3860,
"preview": "//\n// A2BlockInvocation.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/// If a block invocation is instiated w"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/A2BlockInvocation.m",
"chars": 7836,
"preview": "//\n// A2BlockInvocation.m\n// BlocksKit\n//\n\n#import \"A2BlockInvocation.h\"\n\nNSString *const A2IncompatibleMethodSignatur"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/A2DynamicDelegate.h",
"chars": 4893,
"preview": "//\n// A2DynamicDelegate.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n#import <BlocksKit/NSObject+A2BlockDelega"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/A2DynamicDelegate.m",
"chars": 9285,
"preview": "//\n// A2DynamicDelegate.m\n// BlocksKit\n//\n\n#import <objc/message.h>\n#import \"A2BlockInvocation.h\"\n#import \"A2DynamicDe"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/Foundation/NSCache+BlocksKit.h",
"chars": 1525,
"preview": "//\n// NSCache+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** NSCache with block adding of objects"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/Foundation/NSCache+BlocksKit.m",
"chars": 1148,
"preview": "//\n// NSCache+BlocksKit.m\n// BlocksKit\n//\n\n#import \"A2DynamicDelegate.h\"\n#import \"NSCache+BlocksKit.h\"\n#import \"NSObje"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/Foundation/NSURLConnection+BlocksKit.h",
"chars": 6271,
"preview": "//\n// NSURLConnection+BlocksKit.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** NSURLConnection with both de"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/Foundation/NSURLConnection+BlocksKit.m",
"chars": 16186,
"preview": "//\n// NSURLConnection+BlocksKit.m\n// BlocksKit\n//\n\n#import <objc/runtime.h>\n#import \"A2DynamicDelegate.h\"\n#import \"NSO"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/NSObject+A2BlockDelegate.h",
"chars": 4731,
"preview": "//\n// NSObject+A2BlockDelegate.h\n// BlocksKit\n//\n\n#import <Foundation/Foundation.h>\n\n/** The A2BlockDelegate category "
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/NSObject+A2BlockDelegate.m",
"chars": 12208,
"preview": "//\n// NSObject+A2BlockDelegate.m\n// BlocksKit\n//\n\n#import <objc/message.h>\n#import \"NSObject+A2BlockDelegate.h\"\n#impor"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/NSObject+A2DynamicDelegate.h",
"chars": 2388,
"preview": "//\n// NSObject+A2DynamicDelegate.h\n// BlocksKit\n//\n\n#import <BlocksKit/A2DynamicDelegate.h>\n#import <Foundation/Founda"
},
{
"path": "Pods/BlocksKit/BlocksKit/DynamicDelegate/NSObject+A2DynamicDelegate.m",
"chars": 2852,
"preview": "//\n// NSObject+A2DynamicDelegate.m\n// BlocksKit\n//\n\n#import <objc/runtime.h>\n#import \"NSObject+A2DynamicDelegate.h\"\n\ne"
},
{
"path": "Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.h",
"chars": 1055,
"preview": "//\n// MFMailComposeViewController+BlocksKit.h\n// BlocksKit\n//\n\n#import <MessageUI/MessageUI.h>\n\n/** MFMailComposeViewC"
},
{
"path": "Pods/BlocksKit/BlocksKit/MessageUI/MFMailComposeViewController+BlocksKit.m",
"chars": 2237,
"preview": "//\n// MFMailComposeViewController+BlocksKit.m\n// BlocksKit\n//\n\n#import \"A2DynamicDelegate.h\"\n#import \"MFMailComposeVie"
},
{
"path": "Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.h",
"chars": 1098,
"preview": "//\n// MFMessageComposeViewController+BlocksKit.h\n// BlocksKit\n//\n\n#import <MessageUI/MessageUI.h>\n\n/** MFMessageCompos"
},
{
"path": "Pods/BlocksKit/BlocksKit/MessageUI/MFMessageComposeViewController+BlocksKit.m",
"chars": 2210,
"preview": "//\n// MFMessageComposeViewController+BlocksKit.m\n// BlocksKit\n//\n\n#import \"A2DynamicDelegate.h\"\n#import \"MFMessageComp"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.h",
"chars": 4905,
"preview": "//\n// UIActionSheet+BlocksKit.h\n// BlocksKit\n//\n\n#import <UIKit/UIKit.h>\n\n/** UIActionSheet without delegates!\n\n This "
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIActionSheet+BlocksKit.m",
"chars": 5287,
"preview": "//\n// UIActionSheet+BlocksKit.m\n// BlocksKit\n//\n\n#import \"NSObject+A2BlockDelegate.h\"\n#import \"NSObject+A2DynamicDeleg"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.h",
"chars": 5507,
"preview": "//\n// UIAlertView+BlocksKit.h\n// BlocksKit\n//\n\n#import <UIKit/UIKit.h>\n\n/** UIAlertView without delegates!\n\n This set "
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIAlertView+BlocksKit.m",
"chars": 6822,
"preview": "//\n// UIAlertView+BlocksKit.m\n// BlocksKit\n//\n\n#import \"A2DynamicDelegate.h\"\n#import \"NSObject+A2BlockDelegate.h\"\n#imp"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIBarButtonItem+BlocksKit.h",
"chars": 2832,
"preview": "//\n// UIBarButtonItem+BlocksKit.h\n// BlocksKit\n//\n\n#import <UIKit/UIKit.h>\n\n/** Block event initialization for UIBarBu"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIBarButtonItem+BlocksKit.m",
"chars": 1994,
"preview": "//\n// UIBarButtonItem+BlocksKit.m\n// BlocksKit\n//\n\n#import <objc/runtime.h>\n#import \"UIBarButtonItem+BlocksKit.h\"\n\nsta"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIControl+BlocksKit.h",
"chars": 1550,
"preview": "//\n// UIControl+BlocksKit.h\n// BlocksKit\n//\n\n#import <UIKit/UIKit.h>\n\n/** Block control event handling for UIControl.\n"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIControl+BlocksKit.m",
"chars": 2820,
"preview": "//\n// UIControl+BlocksKit.m\n// BlocksKit\n//\n\n#import <objc/runtime.h>\n#import \"UIControl+BlocksKit.h\"\n\nstatic const vo"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIGestureRecognizer+BlocksKit.h",
"chars": 4413,
"preview": "//\n// UIGestureRecognizer+BlocksKit.h\n// BlocksKit\n//\n\n#import <UIKit/UIKit.h>\n\n/** Block functionality for UIGestureR"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIGestureRecognizer+BlocksKit.m",
"chars": 3310,
"preview": "//\n// UIGestureRecognizer+BlocksKit.m\n// BlocksKit\n//\n\n#import <objc/runtime.h>\n#import \"UIGestureRecognizer+BlocksKit"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIImagePickerController+BlocksKit.h",
"chars": 739,
"preview": "//\n// UIImagePickerController+BlocksKit.h\n// BlocksKit\n//\n// Contributed by Yas Kuraishi.\n//\n\n#import <UIKit/UIKit.h>"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIImagePickerController+BlocksKit.m",
"chars": 1717,
"preview": "//\n// UIImagePickerController+BlocksKit.m\n// BlocksKit\n//\n\n#import \"A2DynamicDelegate.h\"\n#import \"NSObject+A2BlockDele"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIPopoverController+BlocksKit.h",
"chars": 898,
"preview": "//\n// UIPopoverController+BlocksKit.h\n// BlocksKit\n//\n\n#import <UIKit/UIKit.h>\n\n/** Block functionality for UIPopoverC"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIPopoverController+BlocksKit.m",
"chars": 1651,
"preview": "//\n// UIPopoverController+BlocksKit.m\n// BlocksKit\n//\n\n#import \"A2DynamicDelegate.h\"\n#import \"NSObject+A2BlockDelegate"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UITextField+BlocksKit.h",
"chars": 1925,
"preview": "//\n// UITextField+BlocksKit.h\n// BlocksKit\n//\n// Contributed by Samuel E. Giddins.\n//\n\n#import <UIKit/UITextField.h>\n"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UITextField+BlocksKit.m",
"chars": 4058,
"preview": "//\n// UITextField+BlocksKit.m\n// BlocksKit\n//\n\n#import \"UITextField+BlocksKit.h\"\n#import \"A2DynamicDelegate.h\"\n#import"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIView+BlocksKit.h",
"chars": 2203,
"preview": "//\n// UIView+BlocksKit.h\n// BlocksKit\n//\n\n#import <UIKit/UIKit.h>\n\n/** Convenience on-touch methods for UIView.\n\n Incl"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIView+BlocksKit.m",
"chars": 1509,
"preview": "//\n// UIView+BlocksKit.m\n// BlocksKit\n//\n\n#import \"UIGestureRecognizer+BlocksKit.h\"\n#import \"UIView+BlocksKit.h\"\n\n@imp"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIWebView+BlocksKit.h",
"chars": 1215,
"preview": "//\n// UIWebView+BlocksKit.h\n// BlocksKit\n//\n\n#import <UIKit/UIKit.h>\n\n/** Block callbacks for UIWebView.\n\n @warning UI"
},
{
"path": "Pods/BlocksKit/BlocksKit/UIKit/UIWebView+BlocksKit.m",
"chars": 2535,
"preview": "//\n// UIWebView+BlocksKit.m\n// BlocksKit\n//\n\n#import \"A2DynamicDelegate.h\"\n#import \"NSObject+A2BlockDelegate.h\"\n#impor"
},
{
"path": "Pods/BlocksKit/LICENSE",
"chars": 1149,
"preview": "//\n// LICENSE\n// BlocksKit\n//\n\nCopyright (c) 2011-2014 Zachary Waldowski, Alexsander Akers, and the BlocksKit Contribu"
},
{
"path": "Pods/BlocksKit/README.md",
"chars": 2347,
"preview": "[BlocksKit](https://zwaldowski.github.io/BlocksKit)\n===================================================\n\nBlocks in C and"
},
{
"path": "Pods/Local Podspecs/NBSwipePageView.podspec.json",
"chars": 529,
"preview": "{\n \"name\": \"NBSwipePageView\",\n \"version\": \"0.1\",\n \"license\": \"zlib\",\n \"summary\": \"NBSwipePageView is an Objective-C "
},
{
"path": "Pods/NBSwipePageView/NBSwipePageView/NBSwipePageView.h",
"chars": 6838,
"preview": "//\n// NBSwipePageView.h\n// NBSwipePageView\n//\n// Created by 徐 哲 on 4/25/12.\n// Copyright (c) 2012 ラクラクテクノロジーズ株式会社 XU"
},
{
"path": "Pods/NBSwipePageView/NBSwipePageView/NBSwipePageView.m",
"chars": 29477,
"preview": "//\n// NBSwipePageView.m\n// NBSwipePageView\n//\n// Created by 徐 哲 on 4/25/12.\n// Copyright (c) 2012 ラクラクテクノロジーズ株式会社 XU"
},
{
"path": "Pods/NBSwipePageView/NBSwipePageView/NBSwipePageViewSheet.h",
"chars": 746,
"preview": "//\n// NBSwipePageSheetView.h\n// NBSwipePageView\n//\n// Created by 徐 哲 on 4/25/12.\n// Copyright (c) 2012 ラクラクテクノロジーズ株式"
},
{
"path": "Pods/NBSwipePageView/NBSwipePageView/NBSwipePageViewSheet.m",
"chars": 1584,
"preview": "//\n// NBSwipePageSheetView.m\n// NBSwipePageView\n//\n// Created by 徐 哲 on 4/25/12.\n// Copyright (c) 2012 ラクラクテクノロジーズ株式"
},
{
"path": "Pods/NBSwipePageView/README.md",
"chars": 671,
"preview": "# About NBSwipePageView\n\nThis is the same page view using in [iWeekly](http://itunes.apple.com/cn/app/iweekly-zhou-mo-hu"
},
{
"path": "Pods/Pods.xcodeproj/project.pbxproj",
"chars": 71702,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Pods/Pods.xcodeproj/xcuserdata/vipstore.xcuserdatad/xcschemes/BlocksKit.xcscheme",
"chars": 2091,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Pods/Pods.xcodeproj/xcuserdata/vipstore.xcuserdatad/xcschemes/NBSwipePageView.xcscheme",
"chars": 2103,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Pods/Pods.xcodeproj/xcuserdata/vipstore.xcuserdatad/xcschemes/Pods-testPasterImage.xcscheme",
"chars": 2113,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0700\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Pods/Pods.xcodeproj/xcuserdata/vipstore.xcuserdatad/xcschemes/xcschememanagement.plist",
"chars": 858,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Pods/Pods.xcodeproj/xcuserdata/wangyingbo.xcuserdatad/xcschemes/BlocksKit.xcscheme",
"chars": 2862,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0730\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Pods/Pods.xcodeproj/xcuserdata/wangyingbo.xcuserdatad/xcschemes/NBSwipePageView.xcscheme",
"chars": 2898,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0730\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Pods/Pods.xcodeproj/xcuserdata/wangyingbo.xcuserdatad/xcschemes/Pods-testPasterImage.xcscheme",
"chars": 2928,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0730\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "Pods/Pods.xcodeproj/xcuserdata/wangyingbo.xcuserdatad/xcschemes/xcschememanagement.plist",
"chars": 900,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Pods/Target Support Files/BlocksKit/BlocksKit-dummy.m",
"chars": 122,
"preview": "#import <Foundation/Foundation.h>\n@interface PodsDummy_BlocksKit : NSObject\n@end\n@implementation PodsDummy_BlocksKit\n@en"
},
{
"path": "Pods/Target Support Files/BlocksKit/BlocksKit-prefix.pch",
"chars": 48,
"preview": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#endif\n\n"
},
{
"path": "Pods/Target Support Files/BlocksKit/BlocksKit.xcconfig",
"chars": 607,
"preview": "CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/BlocksKit\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS="
},
{
"path": "Pods/Target Support Files/NBSwipePageView/NBSwipePageView-dummy.m",
"chars": 134,
"preview": "#import <Foundation/Foundation.h>\n@interface PodsDummy_NBSwipePageView : NSObject\n@end\n@implementation PodsDummy_NBSwipe"
},
{
"path": "Pods/Target Support Files/NBSwipePageView/NBSwipePageView-prefix.pch",
"chars": 48,
"preview": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#endif\n\n"
},
{
"path": "Pods/Target Support Files/NBSwipePageView/NBSwipePageView.xcconfig",
"chars": 580,
"preview": "CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/NBSwipePageView\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCO"
},
{
"path": "Pods/Target Support Files/Pods-testPasterImage/Pods-testPasterImage-acknowledgements.markdown",
"chars": 1298,
"preview": "# Acknowledgements\nThis application makes use of the following third party libraries:\n\n## BlocksKit\n\n//\n// LICENSE\n// "
},
{
"path": "Pods/Target Support Files/Pods-testPasterImage/Pods-testPasterImage-acknowledgements.plist",
"chars": 2125,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Pods/Target Support Files/Pods-testPasterImage/Pods-testPasterImage-dummy.m",
"chars": 144,
"preview": "#import <Foundation/Foundation.h>\n@interface PodsDummy_Pods_testPasterImage : NSObject\n@end\n@implementation PodsDummy_Po"
},
{
"path": "Pods/Target Support Files/Pods-testPasterImage/Pods-testPasterImage-frameworks.sh",
"chars": 3374,
"preview": "#!/bin/sh\nset -e\n\necho \"mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\nmkdir -p \"${CONFIGURATION_BUILD_D"
},
{
"path": "Pods/Target Support Files/Pods-testPasterImage/Pods-testPasterImage-resources.sh",
"chars": 5137,
"preview": "#!/bin/sh\nset -e\n\nmkdir -p \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\"\n\nRESOURCES_TO_COPY=${PODS_ROOT}/re"
},
{
"path": "Pods/Target Support Files/Pods-testPasterImage/Pods-testPasterImage.debug.xcconfig",
"chars": 742,
"preview": "GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_ROOT}/Headers/Public\""
},
{
"path": "Pods/Target Support Files/Pods-testPasterImage/Pods-testPasterImage.release.xcconfig",
"chars": 742,
"preview": "GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nHEADER_SEARCH_PATHS = $(inherited) \"${PODS_ROOT}/Headers/Public\""
},
{
"path": "README.md",
"chars": 582,
"preview": "# YBPasterImage\n### ***给图片添加滤镜和贴纸,支持14种滤镜效果***\n\n\n### 一、介绍\n##### 这是一个关于在图片上添加贴纸的demo,动图里演示了操作方法。\n\n>+ 项目里要求,要实现下面三种功能:\n>+ "
},
{
"path": "files/README发帖专用.md",
"chars": 722,
"preview": "# YBPasterImage\n## ***给图片添加滤镜和贴纸,支持14种滤镜效果***\n\n####修复了一些已知的bug,重新发帖上传,欢迎大家提意见。\n\n###项目地址[DEMO](https://github.com/wangyin"
},
{
"path": "testPasterImage/AppDelegate.h",
"chars": 269,
"preview": "//\n// AppDelegate.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights reserved"
},
{
"path": "testPasterImage/AppDelegate.m",
"chars": 705,
"preview": "//\n// AppDelegate.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights reserved"
},
{
"path": "testPasterImage/Assets.xcassets/1.imageset/Contents.json",
"chars": 298,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"1.png\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/2.imageset/Contents.json",
"chars": 298,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"2.png\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/3.imageset/Contents.json",
"chars": 298,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"3.png\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/4.imageset/Contents.json",
"chars": 298,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"4.png\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/5.imageset/Contents.json",
"chars": 298,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"5.png\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 585,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"iphone\",\n \"size\" : \"29x29\",\n \"scale\" : \"2x\"\n },\n {\n \"idiom\""
},
{
"path": "testPasterImage/Assets.xcassets/Contents.json",
"chars": 62,
"preview": "{\n \"info\" : {\n \"version\" : 1,\n \"author\" : \"xcode\"\n }\n}"
},
{
"path": "testPasterImage/Assets.xcassets/bt_paster_delete.imageset/Contents.json",
"chars": 363,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"删除.png\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/bt_paster_transform.imageset/Contents.json",
"chars": 363,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"大小.png\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/dogs.imageset/Contents.json",
"chars": 302,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"dogs.jpeg\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/gao4.imageset/Contents.json",
"chars": 301,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"gao4.jpg\",\n \"scale\" : \"1x\"\n },\n {\n "
},
{
"path": "testPasterImage/Assets.xcassets/gaoyuanyuan.imageset/Contents.json",
"chars": 308,
"preview": "{\n \"images\" : [\n {\n \"idiom\" : \"universal\",\n \"filename\" : \"gaoyuanyuan.png\",\n \"scale\" : \"1x\"\n },\n "
},
{
"path": "testPasterImage/Base.lproj/LaunchScreen.storyboard",
"chars": 1665,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "testPasterImage/Base.lproj/Main.storyboard",
"chars": 5621,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
},
{
"path": "testPasterImage/Categories/UIImage+AddFunction.h",
"chars": 350,
"preview": "// UIImage+AddFunction.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights res"
},
{
"path": "testPasterImage/Categories/UIImage+AddFunction.m",
"chars": 2173,
"preview": "// UIImage+AddFunction.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights res"
},
{
"path": "testPasterImage/Categories/UIViewController+Example.h",
"chars": 243,
"preview": "//\n// UIViewController+Example.h\n// Kergou\n//\n// Created by 王迎博 on 16/4/28.\n// Copyright © 2016年 张帅. All rights rese"
},
{
"path": "testPasterImage/Categories/UIViewController+Example.m",
"chars": 840,
"preview": "//\n// UIViewController+Example.m\n// Kergou\n//\n// Created by 王迎博 on 16/4/28.\n// Copyright © 2016年 张帅. All rights rese"
},
{
"path": "testPasterImage/Categories/UIViewController+Extension.h",
"chars": 2013,
"preview": "//\n// UIViewController+Extension.h\n// Kergou\n//\n// Created by 王迎博 on 16/4/28.\n// Copyright © 2016年 张帅. All rights re"
},
{
"path": "testPasterImage/Categories/UIViewController+Extension.m",
"chars": 7110,
"preview": "//\n// UIViewController+Extension.m\n// Kergou\n//\n// Created by 王迎博 on 16/4/28.\n// Copyright © 2016年 张帅. All rights re"
},
{
"path": "testPasterImage/Categories/UIViewController+Swizzling.h",
"chars": 238,
"preview": "//\n// UIViewController+Swizzling.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/10/19.\n// Copyright © 2016年 王迎博. Al"
},
{
"path": "testPasterImage/Categories/UIViewController+Swizzling.m",
"chars": 1043,
"preview": "//\n// UIViewController+Swizzling.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/10/19.\n// Copyright © 2016年 王迎博. Al"
},
{
"path": "testPasterImage/Controllers/ViewController.h",
"chars": 209,
"preview": "//\n// ViewController.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights reser"
},
{
"path": "testPasterImage/Controllers/ViewController.m",
"chars": 919,
"preview": "//\n// ViewController.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights reser"
},
{
"path": "testPasterImage/Controllers/YBBaseViewController.h",
"chars": 219,
"preview": "//\n// YBBaseViewController.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/10/19.\n// Copyright © 2016年 王迎博. All righ"
},
{
"path": "testPasterImage/Controllers/YBBaseViewController.m",
"chars": 887,
"preview": "//\n// YBBaseViewController.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/10/19.\n// Copyright © 2016年 王迎博. All righ"
},
{
"path": "testPasterImage/Controllers/YBPasterImageVC.h",
"chars": 841,
"preview": "//\n// YBPasterImageVC.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights rese"
},
{
"path": "testPasterImage/Controllers/YBPasterImageVC.m",
"chars": 12339,
"preview": "//\n// YBPasterImageVC.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights rese"
},
{
"path": "testPasterImage/Info.plist",
"chars": 1205,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/ColorMatrix.h",
"chars": 2364,
"preview": "//\n// RootViewController.h\n// pictureProcess\n//\n// Created by Ibokan on 12-9-7.\n// Copyright (c) 2012年 __MyCompanyNa"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/ImageUtil.h",
"chars": 388,
"preview": "//\n// RootViewController.h\n// pictureProcess\n//\n// Created by Ibokan on 12-9-7.\n// Copyright (c) 2012年 __MyCompanyNa"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/ImageUtil.m",
"chars": 4461,
"preview": "//\n// RootViewController.h\n// pictureProcess\n//\n// Created by Ibokan on 12-9-7.\n// Copyright (c) 2012年 __MyCompanyNa"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/entries",
"chars": 3,
"preview": "12\n"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/format",
"chars": 3,
"preview": "12\n"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/06/062d14b8b3d1573c2d8c9d30257fd9b0b84bd59c.svn-base",
"chars": 3379,
"preview": "// UIImage+RoundedCorner.m\n// Created by Trevor Harmon on 9/20/09.\n// Free for personal or commercial use, with or witho"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/39/3944926a8fe582382d834a9fecb902c171a9a76e.svn-base",
"chars": 1086,
"preview": "// UIImage+Resize.h\n// Created by Trevor Harmon on 8/5/09.\n// Free for personal or commercial use, with or without modif"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/43/43a6e58f03ebdbe417f3c5028d4dc1b936e030b4.svn-base",
"chars": 435,
"preview": "// UIImage+Alpha.h\n// Created by Trevor Harmon on 9/20/09.\n// Free for personal or commercial use, with or without modif"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/5d/5deb2d07c4dd4089e7ade0df1f5278a51efb71cf.svn-base",
"chars": 760,
"preview": "//\n// UIImage-Extensions.h\n//\n// Created by Hardy Macia on 7/1/09.\n// Copyright 2009 Catamount Software. All rights r"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/74/7403967df71a9ffaa67500af6a610523742bfd53.svn-base",
"chars": 290,
"preview": "//\n// UIImage+SplitImageIntoTwoParts.h\n// TapRepublic\n//\n// Created by Terry Lin on 12-5-11.\n// Copyright (c) 2012年 "
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/9e/9e08c4f172f233df24ad098fd5059cdaf5ad8268.svn-base",
"chars": 2408,
"preview": "//\n// UIImage+SplitImageIntoTwoParts.m\n// TapRepublic\n//\n// Created by Terry Lin on 12-5-11.\n// Copyright (c) 2012年 "
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/a3/a31a6fddf40b76b94df05097d799e55a769d8440.svn-base",
"chars": 503,
"preview": "// UIImage+RoundedCorner.h\n// Created by Trevor Harmon on 9/20/09.\n// Free for personal or commercial use, with or witho"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/be/becc3c813720214cae048c91b03d26dba76ff1ca.svn-base",
"chars": 1787,
"preview": "//\n// UIImage+Cut.m\n// MeiJiaLove\n//\n// Created by Wu.weibin on 13-5-17.\n// Copyright (c) 2013年 Wu.weibin. All right"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/c8/c8496f35a02cbd4ef1b2a81af9b5ca802b339a3a.svn-base",
"chars": 9273,
"preview": "//\n// UIImage-Extensions.m\n//\n// Created by Hardy Macia on 7/1/09.\n// Copyright 2009 Catamount Software. All rights r"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/d8/d878290233a5ccddb800ee8a4f409b373e187859.svn-base",
"chars": 394,
"preview": "//\n// UIImage+Cut.h\n// MeiJiaLove\n//\n// Created by Wu.weibin on 13-5-17.\n// Copyright (c) 2013年 Wu.weibin. All right"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/dc/dc06ddf7d7a2ad296ab0a741fcc7c3bc6d34b0e3.svn-base",
"chars": 8147,
"preview": "// UIImage+Resize.m\n// Created by Trevor Harmon on 8/5/09.\n// Free for personal or commercial use, with or without modif"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/.svn/pristine/ee/ee255ad5f9f4f575fb733f734606d7eb9e0efeac.svn-base",
"chars": 5633,
"preview": "// UIImage+Alpha.m\n// Created by Trevor Harmon on 9/20/09.\n// Free for personal or commercial use, with or without modif"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+Alpha.h",
"chars": 459,
"preview": "// UIImage+Alpha.h\n// Created by Trevor Harmon on 9/20/09.\n// Free for personal or commercial use, with or without modif"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+Alpha.m",
"chars": 5633,
"preview": "// UIImage+Alpha.m\n// Created by Trevor Harmon on 9/20/09.\n// Free for personal or commercial use, with or without modif"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+Cut.h",
"chars": 417,
"preview": "//\n// UIImage+Cut.h\n// MeiJiaLove\n//\n// Created by Wu.weibin on 13-5-17.\n// Copyright (c) 2013年 Wu.weibin. All right"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+Cut.m",
"chars": 1787,
"preview": "//\n// UIImage+Cut.m\n// MeiJiaLove\n//\n// Created by Wu.weibin on 13-5-17.\n// Copyright (c) 2013年 Wu.weibin. All right"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+Resize.h",
"chars": 1110,
"preview": "// UIImage+Resize.h\n// Created by Trevor Harmon on 8/5/09.\n// Free for personal or commercial use, with or without modif"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+Resize.m",
"chars": 8154,
"preview": "// UIImage+Resize.m\n// Created by Trevor Harmon on 8/5/09.\n// Free for personal or commercial use, with or without modif"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+RoundedCorner.h",
"chars": 527,
"preview": "// UIImage+RoundedCorner.h\n// Created by Trevor Harmon on 9/20/09.\n// Free for personal or commercial use, with or witho"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+RoundedCorner.m",
"chars": 3379,
"preview": "// UIImage+RoundedCorner.m\n// Created by Trevor Harmon on 9/20/09.\n// Free for personal or commercial use, with or witho"
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+SplitImageIntoTwoParts.h",
"chars": 290,
"preview": "//\n// UIImage+SplitImageIntoTwoParts.h\n// TapRepublic\n//\n// Created by Terry Lin on 12-5-11.\n// Copyright (c) 2012年 "
},
{
"path": "testPasterImage/Libs/FilterImageLibs/UIImage-Extensions/UIImage+SplitImageIntoTwoParts.m",
"chars": 2408,
"preview": "//\n// UIImage+SplitImageIntoTwoParts.m\n// TapRepublic\n//\n// Created by Terry Lin on 12-5-11.\n// Copyright (c) 2012年 "
},
{
"path": "testPasterImage/Views/YBCustomViews/YBCustomButton.h",
"chars": 301,
"preview": "//\n// YBCustomButton.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/27.\n// Copyright © 2016年 王迎博. All rights rese"
},
{
"path": "testPasterImage/Views/YBCustomViews/YBCustomButton.m",
"chars": 197,
"preview": "//\n// YBCustomButton.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/27.\n// Copyright © 2016年 王迎博. All rights rese"
},
{
"path": "testPasterImage/Views/YBFilterImage/YBFilterScrollView.h",
"chars": 943,
"preview": "//\n// YBFilterScrollView.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/27.\n// Copyright © 2016年 王迎博. All rights "
},
{
"path": "testPasterImage/Views/YBFilterImage/YBFilterScrollView.m",
"chars": 5659,
"preview": "//\n// YBFilterScrollView.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/27.\n// Copyright © 2016年 王迎博. All rights "
},
{
"path": "testPasterImage/Views/YBPasterImage/YBPasterScrollView.h",
"chars": 933,
"preview": "//\n// YBPasterScrollView.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights r"
},
{
"path": "testPasterImage/Views/YBPasterImage/YBPasterScrollView.m",
"chars": 2512,
"preview": "//\n// YBPasterScrollView.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights r"
},
{
"path": "testPasterImage/Views/YBPasterImage/YBPasterView.h",
"chars": 519,
"preview": "//\n// YBPasterView.h\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/6.\n// Copyright © 2016年 王迎博. All rights reserve"
},
{
"path": "testPasterImage/Views/YBPasterImage/YBPasterView.m",
"chars": 11234,
"preview": "//\n// YBPasterView.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/6.\n// Copyright © 2016年 王迎博. All rights reserve"
},
{
"path": "testPasterImage/main.m",
"chars": 326,
"preview": "//\n// main.m\n// testPasterImage\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All rights reserved.\n//\n\n#"
},
{
"path": "testPasterImage.xcodeproj/project.pbxproj",
"chars": 38268,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "testPasterImage.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 160,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:testPasterImage"
},
{
"path": "testPasterImage.xcodeproj/xcuserdata/vipstore.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist",
"chars": 91,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Bucket\n type = \"1\"\n version = \"2.0\">\n</Bucket>\n"
},
{
"path": "testPasterImage.xcodeproj/xcuserdata/vipstore.xcuserdatad/xcschemes/testPasterImage.xcscheme",
"chars": 4311,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0730\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "testPasterImage.xcodeproj/xcuserdata/vipstore.xcuserdatad/xcschemes/xcschememanagement.plist",
"chars": 667,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "testPasterImage.xcodeproj/xcuserdata/wangyingbo.xcuserdatad/xcschemes/testPasterImage.xcscheme",
"chars": 4311,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"0730\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "testPasterImage.xcodeproj/xcuserdata/wangyingbo.xcuserdatad/xcschemes/xcschememanagement.plist",
"chars": 667,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "testPasterImage.xcworkspace/contents.xcworkspacedata",
"chars": 233,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:testPasterImag"
},
{
"path": "testPasterImage.xcworkspace/xcshareddata/testPasterImage.xcscmblueprint",
"chars": 1795,
"preview": "{\n \"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey\" : \"537B6586F05AEB9F89F52A1E940931332B028804\",\n \"DVTS"
},
{
"path": "testPasterImage.xcworkspace/xcuserdata/vipstore.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist",
"chars": 91,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Bucket\n type = \"0\"\n version = \"2.0\">\n</Bucket>\n"
},
{
"path": "testPasterImageTests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "testPasterImageTests/testPasterImageTests.m",
"chars": 915,
"preview": "//\n// testPasterImageTests.m\n// testPasterImageTests\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. All r"
},
{
"path": "testPasterImageUITests/Info.plist",
"chars": 733,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "testPasterImageUITests/testPasterImageUITests.m",
"chars": 1222,
"preview": "//\n// testPasterImageUITests.m\n// testPasterImageUITests\n//\n// Created by 王迎博 on 16/9/5.\n// Copyright © 2016年 王迎博. A"
}
]
// ... and 4 more files (download for full content)
About this extraction
This page contains the full source code of the wangyingbo/YBPasterImage GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 188 files (550.8 KB), approximately 160.0k tokens, and a symbol index with 4 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.