diff --git a/Package.swift b/Package.swift index 5bc0747b..a0e883ce 100644 --- a/Package.swift +++ b/Package.swift @@ -1,11 +1,11 @@ -// swift-tools-version:5.3 +// swift-tools-version:5.9 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "KIF", platforms: [ - .iOS(.v13) + .iOS(.v15) ], products: [ .library( diff --git a/README.md b/README.md index c7750eee..f0f350b9 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ KIF builds and performs the tests using a standard `XCTest` testing target. Tes **KIF uses undocumented Apple APIs.** This is true of most iOS testing frameworks, and is safe for testing purposes, but it's important that KIF does not make it into production code, as it will get your app submission denied by Apple. Follow the instructions below to ensure that KIF is configured correctly for your project. -**Actively supports Xcode 11.6 and iOS 11-13 if you need support for an earlier version please use [v3.7.9](https://github.com/kif-framework/KIF/releases/tag/v3.7.9) or an [earlier release](https://github.com/kif-framework/KIF/releases).** +**Actively supports Xcode 16 and iOS 15 if you need support for an earlier version please use an [earlier release](https://github.com/kif-framework/KIF/releases).** Features -------- diff --git a/Scripts/ci.sh b/Scripts/ci.sh index 57f75f64..97da1a42 100755 --- a/Scripts/ci.sh +++ b/Scripts/ci.sh @@ -21,9 +21,6 @@ if [ $RUN_EXTRA_VALIDATIONS != "true" ]; then exit 0 fi -# Compile the KIF SPM package directly -swift build -Xcc "-isysroot" -Xcc "$(xcrun --sdk iphonesimulator --show-sdk-path)" -Xcc "-target" -Xcc "x86_64-apple-ios$(xcrun --sdk iphonesimulator --show-sdk-version)-simulator" - # Consume KIF via Swift Package Manager in an Xcode project env NSUnbufferedIO=YES xcodebuild test -project "Documentation/Examples/SPMIntegration/SPMIntegration.xcodeproj" -scheme "SPMIntegration" -derivedDataPath=${PWD}/build/SPMIntegration -destination "platform=iOS Simulator,${SIMULATOR}" CODE_SIGNING_ALLOWED=NO | xcbeautify diff --git a/Sources/KIF/Additions/UIAccessibilityElement-KIFAdditions.m b/Sources/KIF/Additions/UIAccessibilityElement-KIFAdditions.m index 51c36254..1cdda39c 100644 --- a/Sources/KIF/Additions/UIAccessibilityElement-KIFAdditions.m +++ b/Sources/KIF/Additions/UIAccessibilityElement-KIFAdditions.m @@ -218,16 +218,7 @@ + (UIView *)viewContainingAccessibilityElement:(UIAccessibilityElement *)element CGRect elementFrame = [view.window convertRect:element.accessibilityFrame toView:scrollView]; CGRect visibleRect = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, CGRectGetWidth(scrollView.bounds), CGRectGetHeight(scrollView.bounds)); - UIEdgeInsets contentInset; - #ifdef __IPHONE_11_0 - if (@available(iOS 11.0, *)) { - contentInset = scrollView.adjustedContentInset; - } else { - contentInset = scrollView.contentInset; - } - #else - contentInset = scrollView.contentInset; - #endif + UIEdgeInsets contentInset = scrollView.adjustedContentInset; visibleRect = UIEdgeInsetsInsetRect(visibleRect, contentInset); // Only call scrollRectToVisible if the element isn't already visible diff --git a/Sources/KIF/Additions/UIApplication-KIFAdditions.m b/Sources/KIF/Additions/UIApplication-KIFAdditions.m index cbfb82e2..15584d6a 100644 --- a/Sources/KIF/Additions/UIApplication-KIFAdditions.m +++ b/Sources/KIF/Additions/UIApplication-KIFAdditions.m @@ -318,7 +318,6 @@ - (BOOL)KIF_openURL:(NSURL *)URL; } } -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 - (BOOL)KIF_openURL:(NSURL *)URL options:(NSDictionary *)options completionHandler:(void (^ __nullable)(BOOL success))completionHandler; { if (_KIF_UIApplicationMockOpenURL) { @@ -328,7 +327,6 @@ - (BOOL)KIF_openURL:(NSURL *)URL options:(NSDictionary *)options return [self KIF_openURL:URL options: options completionHandler: completionHandler]; } } -#endif - (BOOL)KIF_canOpenURL:(NSURL *)URL; { @@ -368,9 +366,7 @@ + (void)startMockingOpenURLWithReturnValue:(BOOL)returnValue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Swizzle(self, @selector(openURL:), @selector(KIF_openURL:)); - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 - Swizzle(self, @selector(openURL:options:completionHandler:), @selector(KIF_openURL:options:completionHandler:)); - #endif + Swizzle(self, @selector(openURL:options:completionHandler:), @selector(KIF_openURL:options:completionHandler:)); Swizzle(self, @selector(canOpenURL:), @selector(KIF_canOpenURL:)); }); diff --git a/Sources/KIF/Additions/UIScrollView-KIFAdditions.m b/Sources/KIF/Additions/UIScrollView-KIFAdditions.m index a502316d..d86c6cfa 100644 --- a/Sources/KIF/Additions/UIScrollView-KIFAdditions.m +++ b/Sources/KIF/Additions/UIScrollView-KIFAdditions.m @@ -35,16 +35,7 @@ - (void)scrollViewToVisible:(UIView *)view animated:(BOOL)animated; contentOffset.y = MAX(CGRectGetMaxY(viewFrame) - CGRectGetHeight(self.bounds), CGRectGetMinY(viewFrame)); } - UIEdgeInsets contentInset; -#ifdef __IPHONE_11_0 - if (@available(iOS 11.0, *)) { - contentInset = self.adjustedContentInset; - } else { - contentInset = self.contentInset; - } -#else - contentInset = self.contentInset; -#endif + UIEdgeInsets contentInset = self.adjustedContentInset; CGFloat minX = -self.contentInset.left; CGFloat maxX = minX + MAX(0, self.contentSize.width + contentInset.left + contentInset.right - CGRectGetWidth(self.bounds)); CGFloat minY = -self.contentInset.top; diff --git a/Sources/KIF/Additions/UIView-KIFAdditions.m b/Sources/KIF/Additions/UIView-KIFAdditions.m index 3d4ed91e..4709eca4 100644 --- a/Sources/KIF/Additions/UIView-KIFAdditions.m +++ b/Sources/KIF/Additions/UIView-KIFAdditions.m @@ -579,10 +579,6 @@ - (void)tapAtPoint:(CGPoint)point; id /*UIWebBrowserView*/ webBrowserView = nil; BOOL isWebView = [self isKindOfClass:[WKWebView class]]; - -#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_12_0 - isWebView = isWebView || [self isKindOfClass:[UIWebView class]]; -#endif if ([NSStringFromClass([self class]) isEqual:@"UIWebBrowserView"]) { webBrowserView = self; diff --git a/Sources/KIF/Additions/XCTestCase-KIFAdditions.m b/Sources/KIF/Additions/XCTestCase-KIFAdditions.m index 6f2d0a37..f12ab588 100644 --- a/Sources/KIF/Additions/XCTestCase-KIFAdditions.m +++ b/Sources/KIF/Additions/XCTestCase-KIFAdditions.m @@ -34,7 +34,6 @@ - (void)failWithException:(NSException *)exception stopTest:(BOOL)stop { self.continueAfterFailure = YES; -#ifdef __IPHONE_14_0 NSString *filePath = exception.userInfo[@"FilenameKey"]; NSInteger lineNumber = [exception.userInfo[@"LineNumberKey"] unsignedIntegerValue]; XCTSourceCodeLocation *location = [[XCTSourceCodeLocation alloc] initWithFilePath:filePath @@ -47,9 +46,6 @@ - (void)failWithException:(NSException *)exception stopTest:(BOOL)stop associatedError:nil attachments:@[]]; [self recordIssue:issue]; -#else - [self recordFailureWithDescription:exception.description inFile:exception.userInfo[@"FilenameKey"] atLine:[exception.userInfo[@"LineNumberKey"] unsignedIntegerValue] expected:NO]; -#endif if (stop) { [self writeScreenshotForException:exception]; @@ -155,7 +151,6 @@ - (void)printViewHierarchyIfOptedIn; @end -#ifdef __IPHONE_8_0 @interface XCTestSuite () - (void)_recordUnexpectedFailureForTestRun:(id)arg1 description:(id)arg2 exception:(id)arg3; @@ -173,7 +168,6 @@ - (void)KIF_recordUnexpectedFailureForTestRun:(XCTestSuiteRun *)arg1 description if (![[arg3 name] isEqualToString:@"KIFFailureException"]) { [self KIF_recordUnexpectedFailureForTestRun:arg1 description:arg2 exception:arg3]; } else { -#ifdef __IPHONE_14_0 NSString *description = [NSString stringWithFormat:@"Test suite stopped on fatal error: %@", arg3.description]; NSString *filePath = arg3.userInfo[@"FilenameKey"]; NSInteger lineNumber = [arg3.userInfo[@"LineNumberKey"] unsignedIntegerValue]; @@ -187,12 +181,7 @@ - (void)KIF_recordUnexpectedFailureForTestRun:(XCTestSuiteRun *)arg1 description associatedError:nil attachments:@[]]; [arg1 recordIssue:issue]; -#else - [arg1 recordFailureWithDescription:[NSString stringWithFormat:@"Test suite stopped on fatal error: %@", arg3.description] inFile:arg3.userInfo[@"FilenameKey"] atLine:[arg3.userInfo[@"LineNumberKey"] unsignedIntegerValue] expected:NO]; -#endif } } @end - -#endif diff --git a/Sources/KIF/Classes/KIFSystemTestActor.m b/Sources/KIF/Classes/KIFSystemTestActor.m index b6baa80d..46adb24f 100644 --- a/Sources/KIF/Classes/KIFSystemTestActor.m +++ b/Sources/KIF/Classes/KIFSystemTestActor.m @@ -58,7 +58,6 @@ - (void)simulateMemoryWarning - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation { -#ifdef __IPHONE_16_0 if (@available(iOS 16.0, *)) { NSSet *scenes = [[UIApplication sharedApplication] connectedScenes]; UIWindowScene* windowScene; @@ -101,11 +100,8 @@ - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation }]; } } else { -#endif [[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"]; -#ifdef __IPHONE_16_0 } -#endif } diff --git a/Sources/KIF/Classes/KIFTextInputTraitsOverrides.m b/Sources/KIF/Classes/KIFTextInputTraitsOverrides.m index c20c2de3..ed9786b6 100644 --- a/Sources/KIF/Classes/KIFTextInputTraitsOverrides.m +++ b/Sources/KIF/Classes/KIFTextInputTraitsOverrides.m @@ -108,68 +108,58 @@ + (void)KIFSwizzleTextInputFieldsAutocorrect + (void)KIFSwizzleTextInputFieldsSmartDashes { - // This #ifdef is necessary for versions of Xcode before Xcode 9. -#ifdef __IPHONE_11_0 - if (@available(iOS 11.0, *)) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - struct objc_method_description smartDashesTypeMethodDescription = protocol_getMethodDescription(@protocol(UITextInputTraits), @selector(smartDashesType), NO, YES); - send_type_uitextfield smartDashesOriginalImp_textField = (send_type_uitextfield)[UITextField instanceMethodForSelector:@selector(smartDashesType)]; - send_type_uitextview smartDashesOriginalImp_textView = (send_type_uitextview)[UITextView instanceMethodForSelector:@selector(smartDashesType)]; - - IMP smartDashesImp_textField = imp_implementationWithBlock(^(UITextField *_self) { - if(self.allowDefaultSmartDashesBehavior) { - return smartDashesOriginalImp_textField(_self, @selector(smartQuotesType)); - } else { - return UITextSmartDashesTypeNo; - } - }); - IMP smartDashesImp_textView = imp_implementationWithBlock(^(UITextView *_self) { - if(self.allowDefaultSmartDashesBehavior) { - return smartDashesOriginalImp_textView(_self, @selector(smartQuotesType)); - } else { - return UITextSmartDashesTypeNo; - } - }); - - class_replaceMethod([UITextField class], @selector(smartDashesType), smartDashesImp_textField, smartDashesTypeMethodDescription.types); - class_replaceMethod([UITextView class], @selector(smartDashesType), smartDashesImp_textView, smartDashesTypeMethodDescription.types); + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + struct objc_method_description smartDashesTypeMethodDescription = protocol_getMethodDescription(@protocol(UITextInputTraits), @selector(smartDashesType), NO, YES); + send_type_uitextfield smartDashesOriginalImp_textField = (send_type_uitextfield)[UITextField instanceMethodForSelector:@selector(smartDashesType)]; + send_type_uitextview smartDashesOriginalImp_textView = (send_type_uitextview)[UITextView instanceMethodForSelector:@selector(smartDashesType)]; + + IMP smartDashesImp_textField = imp_implementationWithBlock(^(UITextField *_self) { + if(self.allowDefaultSmartDashesBehavior) { + return smartDashesOriginalImp_textField(_self, @selector(smartQuotesType)); + } else { + return UITextSmartDashesTypeNo; + } }); - } -#endif + IMP smartDashesImp_textView = imp_implementationWithBlock(^(UITextView *_self) { + if(self.allowDefaultSmartDashesBehavior) { + return smartDashesOriginalImp_textView(_self, @selector(smartQuotesType)); + } else { + return UITextSmartDashesTypeNo; + } + }); + + class_replaceMethod([UITextField class], @selector(smartDashesType), smartDashesImp_textField, smartDashesTypeMethodDescription.types); + class_replaceMethod([UITextView class], @selector(smartDashesType), smartDashesImp_textView, smartDashesTypeMethodDescription.types); + }); } + (void)KIFSwizzleTextInputFieldsSmartQuotes { - // This #ifdef is necessary for versions of Xcode before Xcode 9. -#ifdef __IPHONE_11_0 - if (@available(iOS 11.0, *)) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - struct objc_method_description smartQuotesTypeMethodDescription = protocol_getMethodDescription(@protocol(UITextInputTraits), @selector(smartQuotesType), NO, YES); - send_type_uitextfield smartQuotesOriginalImp_textField = (send_type_uitextfield)[UITextField instanceMethodForSelector:@selector(smartDashesType)]; - send_type_uitextview smartQuotesOriginalImp_textView = (send_type_uitextview)[UITextView instanceMethodForSelector:@selector(smartDashesType)]; - - IMP smartQuotesImp_textField = imp_implementationWithBlock(^(UITextField *_self) { - if(self.allowDefaultSmartQuotesBehavior) { - return smartQuotesOriginalImp_textField(_self, @selector(smartQuotesType)); - } else { - return UITextSmartQuotesTypeNo; - } - }); - IMP smartQuotesImp_textView = imp_implementationWithBlock(^(UITextView *_self) { - if(self.allowDefaultSmartQuotesBehavior) { - return smartQuotesOriginalImp_textView(_self, @selector(smartQuotesType)); - } else { - return UITextSmartQuotesTypeNo; - } - }); - - class_replaceMethod([UITextField class], @selector(smartQuotesType), smartQuotesImp_textField, smartQuotesTypeMethodDescription.types); - class_replaceMethod([UITextView class], @selector(smartQuotesType), smartQuotesImp_textView, smartQuotesTypeMethodDescription.types); - }); - } -#endif + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + struct objc_method_description smartQuotesTypeMethodDescription = protocol_getMethodDescription(@protocol(UITextInputTraits), @selector(smartQuotesType), NO, YES); + send_type_uitextfield smartQuotesOriginalImp_textField = (send_type_uitextfield)[UITextField instanceMethodForSelector:@selector(smartDashesType)]; + send_type_uitextview smartQuotesOriginalImp_textView = (send_type_uitextview)[UITextView instanceMethodForSelector:@selector(smartDashesType)]; + + IMP smartQuotesImp_textField = imp_implementationWithBlock(^(UITextField *_self) { + if(self.allowDefaultSmartQuotesBehavior) { + return smartQuotesOriginalImp_textField(_self, @selector(smartQuotesType)); + } else { + return UITextSmartQuotesTypeNo; + } + }); + IMP smartQuotesImp_textView = imp_implementationWithBlock(^(UITextView *_self) { + if(self.allowDefaultSmartQuotesBehavior) { + return smartQuotesOriginalImp_textView(_self, @selector(smartQuotesType)); + } else { + return UITextSmartQuotesTypeNo; + } + }); + + class_replaceMethod([UITextField class], @selector(smartQuotesType), smartQuotesImp_textField, smartQuotesTypeMethodDescription.types); + class_replaceMethod([UITextView class], @selector(smartQuotesType), smartQuotesImp_textView, smartQuotesTypeMethodDescription.types); + }); } @end diff --git a/Sources/KIF/Classes/UIAutomationHelper.m b/Sources/KIF/Classes/UIAutomationHelper.m index 7779bef3..f51b0416 100644 --- a/Sources/KIF/Classes/UIAutomationHelper.m +++ b/Sources/KIF/Classes/UIAutomationHelper.m @@ -121,7 +121,6 @@ - (UIAAlert *)currentSystemAlert UIAApplication *application = [[self target] frontMostApp]; UIAAlert *alert = application.alert; -#ifdef __IPHONE_13_1 if ([alert isKindOfClass:[self nilElementClass]]) { // application.alert returns UIAElementNil on iOS 13.1 // Instead find the alert by looking for the alert's window and getting the UIAAlert off of it @@ -132,7 +131,6 @@ - (UIAAlert *)currentSystemAlert return [[evaluatedObject valueForKey:@"type"] isEqualToString:@"_UIAlertControllerView"]; }]] firstObject]; } -#endif return alert; }