diff --git a/UIKit/Spec/Fixtures/tvOS/OuterView.xib b/UIKit/Spec/Fixtures/tvOS/OuterView.xib index f48ed31..32b9f05 100644 --- a/UIKit/Spec/Fixtures/tvOS/OuterView.xib +++ b/UIKit/Spec/Fixtures/tvOS/OuterView.xib @@ -30,7 +30,7 @@ - + diff --git a/UIKit/Spec/Stubs/UIViewControllerSpec+Spec.mm b/UIKit/Spec/Stubs/UIViewControllerSpec+Spec.mm index d0b5a58..aff1e54 100644 --- a/UIKit/Spec/Stubs/UIViewControllerSpec+Spec.mm +++ b/UIKit/Spec/Stubs/UIViewControllerSpec+Spec.mm @@ -142,11 +142,11 @@ it(@"should use the default UIKit version of presentViewController:animated:completion: " @"(which does not unset the presentedViewController property synchronously)", ^{ - [controller presentViewController:modalController animated:YES completion:nil]; - controller.presentedViewController should be_same_instance_as(modalController); - [UIViewController pck_useSpecStubs:NO]; + [controller presentViewController:modalController animated:NO completion:nil]; + controller.presentedViewController should be_same_instance_as(modalController); + __block BOOL completionBlockCalled = NO; [controller dismissViewControllerAnimated:YES completion:^{ completionBlockCalled = YES; diff --git a/UIKit/SpecHelper/Stubs/UIAlertController+Spec.m b/UIKit/SpecHelper/Stubs/UIAlertController+Spec.m index 6173ff5..f49fbf0 100644 --- a/UIKit/SpecHelper/Stubs/UIAlertController+Spec.m +++ b/UIKit/SpecHelper/Stubs/UIAlertController+Spec.m @@ -11,7 +11,7 @@ - (void)dismissByTappingCancelButton { } [self.presentingViewController dismissViewControllerAnimated:NO completion:^{ - UIAlertAction *cancelAction = [self cancelAction]; + UIAlertAction *cancelAction = [self pck_cancelAction]; if (cancelAction.handler) { cancelAction.handler(cancelAction); } @@ -26,7 +26,7 @@ - (void)dismissByTappingButtonWithTitle:(NSString *)title { } [self.presentingViewController dismissViewControllerAnimated:NO completion:^{ - UIAlertAction *action = [self actionWithButtonTitle:title]; + UIAlertAction *action = [self pck_actionWithButtonTitle:title]; if (action.handler) { action.handler(action); } @@ -35,7 +35,7 @@ - (void)dismissByTappingButtonWithTitle:(NSString *)title { #pragma mark - Private -- (UIAlertAction *)cancelAction { +- (UIAlertAction *)pck_cancelAction { NSPredicate *cancelPredicate = [NSPredicate predicateWithBlock:^BOOL(UIAlertAction *action, NSDictionary *bindings) { return action.style == UIAlertActionStyleCancel; }]; @@ -47,7 +47,7 @@ - (UIAlertAction *)cancelAction { return cancelAction; } -- (UIAlertAction *)actionWithButtonTitle:(NSString *)title { +- (UIAlertAction *)pck_actionWithButtonTitle:(NSString *)title { NSArray *buttonTitles = [self.actions valueForKey:@"title"]; NSUInteger buttonIndex = [buttonTitles indexOfObject:title]; if (buttonIndex == NSNotFound) { diff --git a/UIKit/SpecHelper/Stubs/UIApplication+Spec.m b/UIKit/SpecHelper/Stubs/UIApplication+Spec.m index abb301f..66b8a52 100644 --- a/UIKit/SpecHelper/Stubs/UIApplication+Spec.m +++ b/UIKit/SpecHelper/Stubs/UIApplication+Spec.m @@ -1,4 +1,5 @@ #import "UIApplication+Spec.h" +#import "PCKMethodRedirector.h" #import @implementation UIApplication (Spec) @@ -11,6 +12,7 @@ + (void)load { if (cedarHooksProtocol) { class_addProtocol(self, cedarHooksProtocol); } + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:self]; } + (void)afterEach { @@ -27,7 +29,7 @@ + (NSURL *)lastOpenedURL { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" -- (void)openURL:(NSURL *)url { +- (void)pck_replace_openURL:(NSURL *)url { [URLs addObject:url]; } #pragma clang diagnostic pop diff --git a/UIKit/SpecHelper/Stubs/UINavigationController+Spec.m b/UIKit/SpecHelper/Stubs/UINavigationController+Spec.m index db5609c..75f5757 100644 --- a/UIKit/SpecHelper/Stubs/UINavigationController+Spec.m +++ b/UIKit/SpecHelper/Stubs/UINavigationController+Spec.m @@ -55,6 +55,10 @@ + (void)load { @implementation UINavigationController (Spec) ++ (void)load { + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:self]; +} + - (void)pushViewController:(UIViewController *)viewController ignoringAnimated:(BOOL)animated { [self originalPushViewController:viewController animated:NO]; } @@ -76,10 +80,7 @@ - (void)setViewControllers:(NSArray *)viewControllers ignoringAnimated:(BOOL)ani [self originalSetViewControllers:viewControllers animated:NO]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" - -- (UIViewController *)visibleViewController { +- (UIViewController *)pck_replace_visibleViewController { if (self.presentedViewController) { return self.presentedViewController; } else { @@ -92,6 +93,4 @@ - (UIViewController *)visibleViewController { return self.topViewController; } -#pragma clang diagnostic pop - @end diff --git a/UIKit/SpecHelper/Stubs/UIPopoverController+Spec.m b/UIKit/SpecHelper/Stubs/UIPopoverController+Spec.m index 9eed020..ccec947 100644 --- a/UIKit/SpecHelper/Stubs/UIPopoverController+Spec.m +++ b/UIKit/SpecHelper/Stubs/UIPopoverController+Spec.m @@ -3,6 +3,7 @@ #endif #import "UIPopoverController+Spec.h" +#import "PCKMethodRedirector.h" #import #pragma clang diagnostic push @@ -19,6 +20,7 @@ + (void)load { if (cedarHooksProtocol) { class_addProtocol(self, cedarHooksProtocol); } + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:self]; } + (instancetype)currentPopoverController { @@ -36,27 +38,27 @@ + (void)afterEach { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" -- (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated { +- (void)pck_replace_presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated { currentPopoverController__ = self; arrowDirectionMask__ = arrowDirections; } -- (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated { +- (void)pck_replace_presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated { currentPopoverController__ = self; arrowDirectionMask__ = arrowDirections; } -- (void)dismissPopoverAnimated:(BOOL)animated { +- (void)pck_replace_dismissPopoverAnimated:(BOOL)animated { if ([self isPopoverVisible]) { [[self class] reset]; } } -- (BOOL)isPopoverVisible { +- (BOOL)pck_replace_isPopoverVisible { return (self == currentPopoverController__); } -- (UIPopoverArrowDirection)popoverArrowDirection { +- (UIPopoverArrowDirection)pck_replace_popoverArrowDirection { return arrowDirectionMask__; } diff --git a/UIKit/SpecHelper/Stubs/UIView+StubbedAnimation.m b/UIKit/SpecHelper/Stubs/UIView+StubbedAnimation.m index d5181d6..d93a4d4 100644 --- a/UIKit/SpecHelper/Stubs/UIView+StubbedAnimation.m +++ b/UIKit/SpecHelper/Stubs/UIView+StubbedAnimation.m @@ -1,4 +1,5 @@ #import "UIView+StubbedAnimation.h" +#import "PCKMethodRedirector.h" #import static BOOL shouldImmediatelyExecuteAnimationBlocks__ = YES; @@ -11,6 +12,7 @@ + (void)load { if (cedarHooksProtocol) { class_addProtocol(self, cedarHooksProtocol); } + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:objc_getMetaClass(class_getName(self))]; } + (UIView*)lastWithView { @@ -75,19 +77,19 @@ + (void)resetAnimations { #pragma mark - Overrides -+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL))completion { ++ (void)pck_replace_animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL))completion { [self animateWithDuration:duration delay:0 usingSpringWithDamping:0 initialSpringVelocity:0 options:0 animations:animations completion:completion]; } -+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations { ++ (void)pck_replace_animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations { [self animateWithDuration:duration delay:0 usingSpringWithDamping:0 initialSpringVelocity:0 options:0 animations:animations completion:nil]; } -+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL))completion { ++ (void)pck_replace_animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL))completion { [self animateWithDuration:duration delay:delay usingSpringWithDamping:0 initialSpringVelocity:0 options:options animations:animations completion:completion]; } -+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL))completion { ++ (void)pck_replace_animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL))completion { PCKViewAnimation *animation = [[PCKViewAnimation alloc] init]; animation.duration = duration; @@ -105,11 +107,11 @@ + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay } } -+ (void)transitionWithView:(UIView *)view - duration:(NSTimeInterval)duration - options:(UIViewAnimationOptions)options - animations:(void (^)(void))animations - completion:(void (^)(BOOL finished))completion { ++ (void)pck_replace_transitionWithView:(UIView *)view + duration:(NSTimeInterval)duration + options:(UIViewAnimationOptions)options + animations:(void (^)(void))animations + completion:(void (^)(BOOL finished))completion { PCKViewAnimation *animation = [[PCKViewAnimation alloc] init]; animation.withView = view; @@ -125,11 +127,11 @@ + (void)transitionWithView:(UIView *)view } } -+ (void)transitionFromView:(UIView *)fromView - toView:(UIView *)toView - duration:(NSTimeInterval)duration - options:(UIViewAnimationOptions)options - completion:(void (^)(BOOL finished))completion { ++ (void)pck_replace_transitionFromView:(UIView *)fromView + toView:(UIView *)toView + duration:(NSTimeInterval)duration + options:(UIViewAnimationOptions)options + completion:(void (^)(BOOL finished))completion { PCKViewAnimation *animation = [[PCKViewAnimation alloc] init]; animation.fromView = fromView; diff --git a/UIKit/SpecHelper/Stubs/iOS/UIActionSheet+Spec.m b/UIKit/SpecHelper/Stubs/iOS/UIActionSheet+Spec.m index 33c2ea9..852e9b2 100644 --- a/UIKit/SpecHelper/Stubs/iOS/UIActionSheet+Spec.m +++ b/UIKit/SpecHelper/Stubs/iOS/UIActionSheet+Spec.m @@ -3,6 +3,7 @@ #endif #import "UIActionSheet+Spec.h" +#import "PCKMethodRedirector.h" #import #pragma clang diagnostic push @@ -18,6 +19,7 @@ + (void)load { if (cedarHooksProtocol) { class_addProtocol(self, cedarHooksProtocol); } + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:self]; } + (void)afterEach { @@ -36,39 +38,36 @@ + (void)reset { [self setCurrentActionSheet:nil forView:nil]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" - + (void)setCurrentActionSheet:(UIActionSheet *)actionSheet forView:(UIView *)view { currentActionSheet__ = actionSheet; currentActionSheetView__ = view; } -- (void)showInView:(UIView *)view { +- (void)pck_replace_showInView:(UIView *)view { [UIActionSheet setCurrentActionSheet:self forView:view]; } -- (void)showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { +- (void)pck_replace_showFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { [UIActionSheet setCurrentActionSheet:self forView:(id)item]; } -- (void)showFromToolbar:(UIToolbar *)view { +- (void)pck_replace_showFromToolbar:(UIToolbar *)view { [UIActionSheet setCurrentActionSheet:self forView:view]; } -- (void)showFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated { +- (void)pck_replace_showFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated { [UIActionSheet setCurrentActionSheet:self forView:view]; } -- (void)showFromTabBar:(UITabBar *)view { +- (void)pck_replace_showFromTabBar:(UITabBar *)view { [UIActionSheet setCurrentActionSheet:self forView:view]; } -- (BOOL)isVisible { +- (BOOL)pck_replace_isVisible { return [UIActionSheet currentActionSheet] == self; } -- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { +- (void)pck_replace_dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { if ([self.delegate respondsToSelector:@selector(actionSheet:clickedButtonAtIndex:)]) { [self.delegate actionSheet:self clickedButtonAtIndex:buttonIndex]; } @@ -81,8 +80,6 @@ - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)anim [UIActionSheet reset]; } -#pragma clang diagnostic pop - - (NSArray *)buttonTitles { NSMutableArray *titles = [NSMutableArray array]; diff --git a/UIKit/SpecHelper/Stubs/iOS/UIAlertView+Spec.m b/UIKit/SpecHelper/Stubs/iOS/UIAlertView+Spec.m index 5a66ace..900b881 100644 --- a/UIKit/SpecHelper/Stubs/iOS/UIAlertView+Spec.m +++ b/UIKit/SpecHelper/Stubs/iOS/UIAlertView+Spec.m @@ -3,6 +3,7 @@ #endif #import "UIAlertView+Spec.h" +#import "PCKMethodRedirector.h" #import #pragma clang diagnostic push @@ -17,6 +18,7 @@ + (void)load { if (cedarHooksProtocol) { class_addProtocol(self, cedarHooksProtocol); } + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:self]; } + (void)afterEach { @@ -38,20 +40,18 @@ + (void)setCurrentAlertView:(UIAlertView *)alertView { [alertViewStack__ addObject:alertView]; } -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" -- (void)show { +- (void)pck_replace_show { [UIAlertView setCurrentAlertView:self]; if ([self.delegate respondsToSelector:@selector(willPresentAlertView:)]) { [self.delegate willPresentAlertView:self]; } } -- (BOOL)isVisible { +- (BOOL)pck_replace_isVisible { return [UIAlertView currentAlertView] == self; } -- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { +- (void)pck_replace_dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated { if ([self.delegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) { [self.delegate alertView:self clickedButtonAtIndex:buttonIndex]; } @@ -63,7 +63,6 @@ - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)anim } [alertViewStack__ removeObject:self]; } -#pragma clang diagnostic pop // "-Wobjc-protocol-method-implementation" - (void)dismissWithOkButton { [self dismissWithClickedButtonIndex:self.firstOtherButtonIndex animated:NO]; diff --git a/UIKit/SpecHelper/Stubs/iOS/UIImagePickerController+Spec.h b/UIKit/SpecHelper/Stubs/iOS/UIImagePickerController+Spec.h index 4847aaa..9edff2e 100644 --- a/UIKit/SpecHelper/Stubs/iOS/UIImagePickerController+Spec.h +++ b/UIKit/SpecHelper/Stubs/iOS/UIImagePickerController+Spec.h @@ -8,8 +8,6 @@ NS_ASSUME_NONNULL_BEGIN + (void)setCameraAvailable:(BOOL)available; + (void)setSavedPhotosAlbumAvailable:(BOOL)available; -+ (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType; - @end NS_ASSUME_NONNULL_END diff --git a/UIKit/SpecHelper/Stubs/iOS/UIImagePickerController+Spec.m b/UIKit/SpecHelper/Stubs/iOS/UIImagePickerController+Spec.m index 5a03fc3..316816b 100644 --- a/UIKit/SpecHelper/Stubs/iOS/UIImagePickerController+Spec.m +++ b/UIKit/SpecHelper/Stubs/iOS/UIImagePickerController+Spec.m @@ -1,4 +1,5 @@ #import "UIImagePickerController+Spec.h" +#import "PCKMethodRedirector.h" #import static BOOL isCameraAvailable__, isPhotoLibraryAvailable__, isSavedPhotosAlbumAvailable__; @@ -11,6 +12,8 @@ + (void)load { if (cedarHooksProtocol) { class_addProtocol(self, cedarHooksProtocol); } + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:self]; + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:objc_getMetaClass(class_getName(self))]; } + (void)afterEach { @@ -37,19 +40,17 @@ + (void)setSavedPhotosAlbumAvailable:(BOOL)available { isSavedPhotosAlbumAvailable__ = available; } -- (void)setCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice { +- (void)pck_replace_setCameraDevice:(UIImagePickerControllerCameraDevice)cameraDevice { objc_setAssociatedObject(self, &cameraDevice__, [NSNumber numberWithInteger:cameraDevice], OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -- (UIImagePickerControllerCameraDevice)cameraDevice { +#pragma mark - Overrides + +- (UIImagePickerControllerCameraDevice)pck_replace_cameraDevice { return (UIImagePickerControllerCameraDevice)[objc_getAssociatedObject(self, &cameraDevice__) integerValue]; } -#pragma mark - Overrides - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" -+ (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType { ++ (BOOL)pck_replace_isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType { switch (sourceType) { case UIImagePickerControllerSourceTypePhotoLibrary: return isPhotoLibraryAvailable__; @@ -61,5 +62,4 @@ + (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType { return NO; } } -#pragma clang diagnostic pop @end diff --git a/UIKit/SpecHelper/Stubs/iOS/UIWebView+Spec.h b/UIKit/SpecHelper/Stubs/iOS/UIWebView+Spec.h index 2eb95c5..6c95b9e 100644 --- a/UIKit/SpecHelper/Stubs/iOS/UIWebView+Spec.h +++ b/UIKit/SpecHelper/Stubs/iOS/UIWebView+Spec.h @@ -2,7 +2,7 @@ NS_ASSUME_NONNULL_BEGIN -typedef NSString * __nullable (^UIWebViewJavaScriptReturnBlock)(); +typedef NSString * __nullable (^UIWebViewJavaScriptReturnBlock)(void); @interface UIWebView (Spec) diff --git a/UIKit/SpecHelper/Stubs/iOS/UIWebView+Spec.m b/UIKit/SpecHelper/Stubs/iOS/UIWebView+Spec.m index 0003ca7..c078b7f 100644 --- a/UIKit/SpecHelper/Stubs/iOS/UIWebView+Spec.m +++ b/UIKit/SpecHelper/Stubs/iOS/UIWebView+Spec.m @@ -3,6 +3,7 @@ #endif #import "UIWebView+Spec.h" +#import "PCKMethodRedirector.h" #import @interface UIWebViewAttributes : NSObject @@ -43,15 +44,20 @@ - (void)log:(NSString *)message, ...; @implementation UIWebView (Spec) + ++ (void)load { + [PCKMethodRedirector redirectPCKReplaceSelectorsForClass:self]; +} + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" #pragma mark Property overrides -- (BOOL)canGoBack { +- (BOOL)pck_replace_canGoBack { return self.attributes.canGoBack; } -- (BOOL)canGoForward { +- (BOOL)pck_replace_canGoForward { return self.attributes.canGoForward; } @@ -67,11 +73,11 @@ - (void)setRequest:(NSURLRequest *)request { self.attributes.request = request; } -- (NSURLRequest *)request { +- (NSURLRequest *)pck_replace_request { return self.attributes.request; } -- (BOOL)isLoading { +- (BOOL)pck_replace_isLoading { return self.attributes.loading; } @@ -80,18 +86,18 @@ - (void)setLoading:(BOOL)loading { } #pragma mark Method overrides -- (void)loadRequest:(NSURLRequest *)request { +- (void)pck_replace_loadRequest:(NSURLRequest *)request { [self log:@"loadRequest: %@", request]; [self loadRequest:request withNavigationType:UIWebViewNavigationTypeOther]; } -- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL { +- (void)pck_replace_loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL { self.attributes.loadedHTMLString = string; self.attributes.loadedBaseURL = baseURL; [self log:@"loadHTMLString:%@ baseURL:%@", string, baseURL]; } -- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL { +- (void)pck_replace_loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL { self.attributes.loadedData = data; self.attributes.loadedMIMEType = MIMEType; self.attributes.loadedTextEncodingName = textEncodingName; @@ -99,7 +105,7 @@ - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:( [self log:@"loadData:%@ MIMEType:%@ textEncodingName:%@ baseURL:%@", data, MIMEType, textEncodingName, baseURL]; } -- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)javaScript { +- (NSString *)pck_replace_stringByEvaluatingJavaScriptFromString:(NSString *)javaScript { [self.attributes.javaScripts addObject:javaScript]; UIWebViewJavaScriptReturnBlock block = [self.attributes.returnValueBlocksByJavaScript objectForKey:javaScript]; if (block) { diff --git a/UIKit/SpecHelper/Support/PCKMethodRedirector.h b/UIKit/SpecHelper/Support/PCKMethodRedirector.h index 689a557..196afe3 100644 --- a/UIKit/SpecHelper/Support/PCKMethodRedirector.h +++ b/UIKit/SpecHelper/Support/PCKMethodRedirector.h @@ -5,6 +5,8 @@ NS_ASSUME_NONNULL_BEGIN @interface PCKMethodRedirector : NSObject + (void)redirectSelector:(SEL)originalSelector forClass:(Class)klass to:(SEL)newSelector andRenameItTo:(SEL)renamedSelector; ++ (void)redirectPCKReplaceSelectorsForClass:(Class)klass; ++ (void)redirectSelectorsWithPrefix:(NSString *)prefix forClass:(Class)klass andRenamePrefixTo:(NSString *)newPrefix; @end diff --git a/UIKit/SpecHelper/Support/PCKMethodRedirector.m b/UIKit/SpecHelper/Support/PCKMethodRedirector.m index 5026df8..02311a1 100644 --- a/UIKit/SpecHelper/Support/PCKMethodRedirector.m +++ b/UIKit/SpecHelper/Support/PCKMethodRedirector.m @@ -1,6 +1,13 @@ #import "PCKMethodRedirector.h" #import + +bool startsWith(const char *pre, const char *str) { + size_t lenpre = strlen(pre), + lenstr = strlen(str); + return lenstr < lenpre ? false : memcmp(pre, str, lenpre) == 0; +} + @implementation PCKMethodRedirector + (void)redirectSelector:(SEL)originalSelector forClass:(Class)klass to:(SEL)newSelector andRenameItTo:(SEL)renamedSelector { @@ -15,4 +22,31 @@ + (void)redirectSelector:(SEL)originalSelector forClass:(Class)klass to:(SEL)new class_replaceMethod(klass, originalSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)); } ++ (void)redirectPCKReplaceSelectorsForClass:(Class)klass { + [self redirectSelectorsWithPrefix:@"pck_replace_" forClass:klass andRenamePrefixTo:@"_pck_preserved_"]; +} + ++ (void)redirectSelectorsWithPrefix:(NSString *)prefix forClass:(Class)klass andRenamePrefixTo:(NSString *)newPrefix { + unsigned int methodCount = 0; + Method *methods = class_copyMethodList(klass, &methodCount); + + for (unsigned int i = 0; i < methodCount; i++) { + Method method = methods[i]; + + SEL sel = method_getName(method); + const char *cName = sel_getName(sel); + if (startsWith([prefix cStringUsingEncoding:NSUTF8StringEncoding], cName)) { + NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding]; + NSString *withoutPrefix = [name substringFromIndex:prefix.length]; + NSString *replacedPrefix = [newPrefix stringByAppendingString:withoutPrefix]; + [self redirectSelector:NSSelectorFromString(withoutPrefix) + forClass:klass + to:sel + andRenameItTo:NSSelectorFromString(replacedPrefix)]; + } + } + + free(methods); +} + @end diff --git a/UIKit/UIKit.xcodeproj/project.pbxproj b/UIKit/UIKit.xcodeproj/project.pbxproj index a84d14c..30b1a24 100644 --- a/UIKit/UIKit.xcodeproj/project.pbxproj +++ b/UIKit/UIKit.xcodeproj/project.pbxproj @@ -121,7 +121,6 @@ 34A664D21BE027B600EF0FEA /* UIKit_PivotalCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34A6645D1BDFE6AD00EF0FEA /* UIKit_PivotalCore.framework */; }; 34A664D81BE027C200EF0FEA /* UIKit_PivotalSpecHelper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34A6646A1BDFE6D400EF0FEA /* UIKit_PivotalSpecHelper.framework */; }; 34A664D91BE027C700EF0FEA /* UIKit_PivotalSpecHelperStubs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34A664771BDFE6E500EF0FEA /* UIKit_PivotalSpecHelperStubs.framework */; }; - 34A664DE1BE0291100EF0FEA /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEBCCC01168B98110056EE83 /* Cedar.framework */; }; 34A664DF1BE0291C00EF0FEA /* NSAttributedString+PivotalCoreKit_UIKitSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA91AAA31867383E00925A6B /* NSAttributedString+PivotalCoreKit_UIKitSpec.mm */; }; 34A664E01BE0291C00EF0FEA /* NSString+PivotalCoreKit_UIKitSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA91AA9D1867260400925A6B /* NSString+PivotalCoreKit_UIKitSpec.mm */; }; 34A664E11BE0291C00EF0FEA /* UIBarButtonItem+ButtonSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBCCC92168B9C530056EE83 /* UIBarButtonItem+ButtonSpec.mm */; }; @@ -431,6 +430,7 @@ B8C62E7216BC04940009CDAD /* Target.m in Sources */ = {isa = PBXBuildFile; fileRef = B8C62E7116BC04940009CDAD /* Target.m */; }; B8C62E7316BC07F60009CDAD /* UIBarButtonItem+Spec.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = B8C62E6B16BC03420009CDAD /* UIBarButtonItem+Spec.h */; }; DE99CA8267EEACF8EE9A941F /* UIGestureRecognizer+Spec.m in Sources */ = {isa = PBXBuildFile; fileRef = DE99CB8E2255BDC5D711130D /* UIGestureRecognizer+Spec.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + F8F78FED2434901700B1E461 /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3431FCFB1BE302B400740FFB /* Cedar.framework */; }; FA07586B18120E47001817BF /* UICollectionViewCellSpec+Spec.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA07586618120BB1001817BF /* UICollectionViewCellSpec+Spec.mm */; }; FA1A516A186290C800C22BA8 /* UIImageView+PivotalCore.m in Sources */ = {isa = PBXBuildFile; fileRef = FA1A5169186290C800C22BA8 /* UIImageView+PivotalCore.m */; }; FA1A5179186290E600C22BA8 /* UIImageView+PivotalCoreSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA1A5178186290E600C22BA8 /* UIImageView+PivotalCoreSpec.mm */; }; @@ -955,9 +955,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F8F78FED2434901700B1E461 /* Cedar.framework in Frameworks */, 34A665031BE0589B00EF0FEA /* CoreGraphics.framework in Frameworks */, 34A665011BE0561C00EF0FEA /* UIKit.framework in Frameworks */, - 34A664DE1BE0291100EF0FEA /* Cedar.framework in Frameworks */, 34A664D91BE027C700EF0FEA /* UIKit_PivotalSpecHelperStubs.framework in Frameworks */, 34A664D81BE027C200EF0FEA /* UIKit_PivotalSpecHelper.framework in Frameworks */, 34A664D21BE027B600EF0FEA /* UIKit_PivotalCore.framework in Frameworks */,