Skip to content

Update minimum iOS version from 10 to 12. #918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AppAuth.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ It follows the OAuth 2.0 for Native Apps best current practice
# classes of AppAuth with tokens on watchOS and tvOS, but currently the
# library won't help you obtain authorization grants on those platforms.

ios_deployment_target = "10.0"
ios_deployment_target = "12.0"
osx_deployment_target = "10.12"
s.ios.deployment_target = ios_deployment_target
s.osx.deployment_target = osx_deployment_target
Expand Down
24 changes: 12 additions & 12 deletions AppAuth.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2815,7 +2815,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -2873,7 +2873,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MACOSX_DEPLOYMENT_TARGET = 10.12;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -2909,7 +2909,7 @@
CLANG_ENABLE_MODULES = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/";
INFOPLIST_FILE = UnitTests/UnitTestsInfo.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.openid.appauth.AppAuthTests;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -2926,7 +2926,7 @@
CLANG_ENABLE_MODULES = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/";
INFOPLIST_FILE = UnitTests/UnitTestsInfo.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.openid.appauth.AppAuthTests;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -3040,7 +3040,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Sources/CoreFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.openid.AppAuthCore;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -3066,7 +3066,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Sources/CoreFramework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.openid.AppAuthCore;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -3091,7 +3091,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Sources/Framework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.openid.AppAuth-iOS";
PRODUCT_NAME = AppAuth;
Expand All @@ -3116,7 +3116,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Sources/Framework/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.openid.AppAuth-iOS";
PRODUCT_NAME = AppAuth;
Expand All @@ -3135,7 +3135,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
HEADER_SEARCH_PATHS = .;
INFOPLIST_FILE = UnitTests/UnitTestsInfo.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.openid.AppAuth-iOSTests";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -3149,7 +3149,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
HEADER_SEARCH_PATHS = .;
INFOPLIST_FILE = UnitTests/UnitTestsInfo.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.openid.AppAuth-iOSTests";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -3403,7 +3403,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
HEADER_SEARCH_PATHS = .;
INFOPLIST_FILE = UnitTests/UnitTestsInfo.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.openid.AppAuth-ExtensionTests";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -3417,7 +3417,7 @@
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
HEADER_SEARCH_PATHS = .;
INFOPLIST_FILE = UnitTests/UnitTestsInfo.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "net.openid.AppAuth-ExtensionTests";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let package = Package(
name: "AppAuth",
platforms: [
.macOS(.v10_12),
.iOS(.v10),
.iOS(.v12),
.tvOS(.v9),
.watchOS(.v2)
],
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ For tvOS, AppAuth implements [OAuth 2.0 Device Authorization Grant

#### Supported Versions

AppAuth supports iOS 10 and above.
AppAuth supports iOS 12 and above.

iOS 9+ uses the in-app browser tab pattern
(via `SFSafariViewController`), and falls back to the system browser (mobile
Expand Down
6 changes: 2 additions & 4 deletions Sources/AppAuth/iOS/OIDExternalUserAgentIOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,8 @@ API_UNAVAILABLE(macCatalyst)
/*! @brief The designated initializer.
@param presentingViewController The view controller from which to present the authentication UI.
@discussion The specific authentication UI used depends on the iOS version and accessibility
options. iOS 8 uses the system browser, iOS 9-10 use @c SFSafariViewController, iOS 11 uses
@c SFAuthenticationSession
(unless Guided Access is on which does not work) or uses @c SFSafariViewController, and iOS
12+ uses @c ASWebAuthenticationSession (unless Guided Access is on).
options. iOS 12+ uses @c ASWebAuthenticationSession (unless Guided Access is on),
otherwise local browser is used.
*/
- (nullable instancetype)initWithPresentingViewController:
(UIViewController *)presentingViewController
Expand Down
48 changes: 0 additions & 48 deletions Sources/AppAuth/iOS/OIDExternalUserAgentIOS.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ @implementation OIDExternalUserAgentIOS {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
__weak SFSafariViewController *_safariVC;
SFAuthenticationSession *_authenticationVC;
ASWebAuthenticationSession *_webAuthenticationVC;
#pragma clang diagnostic pop
}
Expand Down Expand Up @@ -134,47 +133,6 @@ - (BOOL)presentExternalUserAgentRequest:(id<OIDExternalUserAgentRequest>)request
openedUserAgent = [authenticationVC start];
}
}
// iOS 11, use SFAuthenticationSession
if (@available(iOS 11.0, *)) {
// SFAuthenticationSession doesn't work with guided access (rdar://40809553)
if (!openedUserAgent && !UIAccessibilityIsGuidedAccessEnabled()) {
__weak OIDExternalUserAgentIOS *weakSelf = self;
NSString *redirectScheme = request.redirectScheme;
SFAuthenticationSession *authenticationVC =
[[SFAuthenticationSession alloc] initWithURL:requestURL
callbackURLScheme:redirectScheme
completionHandler:^(NSURL * _Nullable callbackURL,
NSError * _Nullable error) {
__strong OIDExternalUserAgentIOS *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
strongSelf->_authenticationVC = nil;
if (callbackURL) {
[strongSelf->_session resumeExternalUserAgentFlowWithURL:callbackURL];
} else {
NSError *safariError =
[OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
underlyingError:error
description:@"User cancelled."];
[strongSelf->_session failExternalUserAgentFlowWithError:safariError];
}
}];
_authenticationVC = authenticationVC;
openedUserAgent = [authenticationVC start];
}
}
// iOS 9 and 10, use SFSafariViewController
if (@available(iOS 9.0, *)) {
if (!openedUserAgent && _presentingViewController) {
SFSafariViewController *safariVC =
[[SFSafariViewController alloc] initWithURL:requestURL];
safariVC.delegate = self;
_safariVC = safariVC;
[_presentingViewController presentViewController:safariVC animated:YES completion:nil];
openedUserAgent = YES;
}
}
// If all else failed use the local browser.
if (!openedUserAgent){
[[UIApplication sharedApplication] openURL:requestURL
Expand All @@ -196,7 +154,6 @@ - (void)dismissExternalUserAgentAnimated:(BOOL)animated completion:(void (^)(voi
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpartial-availability"
SFSafariViewController *safariVC = _safariVC;
SFAuthenticationSession *authenticationVC = _authenticationVC;
ASWebAuthenticationSession *webAuthenticationVC = _webAuthenticationVC;
#pragma clang diagnostic pop

Expand All @@ -206,10 +163,6 @@ - (void)dismissExternalUserAgentAnimated:(BOOL)animated completion:(void (^)(voi
// dismiss the ASWebAuthenticationSession
[webAuthenticationVC cancel];
if (completion) completion();
} else if (authenticationVC) {
// dismiss the SFAuthenticationSession
[authenticationVC cancel];
if (completion) completion();
} else if (safariVC) {
// dismiss the SFSafariViewController
[safariVC dismissViewControllerAnimated:YES completion:completion];
Expand All @@ -222,7 +175,6 @@ - (void)cleanUp {
// The weak references to |_safariVC| and |_session| are set to nil to avoid accidentally using
// them while not in an authorization flow.
_safariVC = nil;
_authenticationVC = nil;
_webAuthenticationVC = nil;
_session = nil;
_externalUserAgentFlowInProgress = NO;
Expand Down
15 changes: 9 additions & 6 deletions Sources/AppAuthCore/OIDRegistrationRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,15 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder {
forKey:kConfigurationKey];
NSString *initialAccessToken = [aDecoder decodeObjectOfClass:[NSString class]
forKey:kInitialAccessToken];
NSArray<NSURL *> *redirectURIs = [aDecoder decodeObjectOfClass:[NSArray<NSURL *> class]
forKey:kRedirectURIsKey];
NSArray<NSString *> *responseTypes = [aDecoder decodeObjectOfClass:[NSArray<NSString *> class]
forKey:kResponseTypesKey];
NSArray<NSString *> *grantTypes = [aDecoder decodeObjectOfClass:[NSArray<NSString *> class]
forKey:kGrantTypesKey];
NSArray<NSURL *> *redirectURIs =
[aDecoder decodeObjectOfClasses:[NSSet setWithArray:@[[NSArray class], [NSURL class]]]
forKey:kRedirectURIsKey];
NSArray<NSString *> *responseTypes =
[aDecoder decodeObjectOfClasses:[NSSet setWithArray:@[[NSArray class], [NSString class]]]
forKey:kResponseTypesKey];
NSArray<NSString *> *grantTypes =
[aDecoder decodeObjectOfClasses:[NSSet setWithArray:@[[NSArray class], [NSString class]]]
forKey:kGrantTypesKey];
NSString *subjectType = [aDecoder decodeObjectOfClass:[NSString class]
forKey:kSubjectTypeKey];
NSString *tokenEndpointAuthenticationMethod =
Expand Down
52 changes: 47 additions & 5 deletions UnitTests/OIDAuthStateTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,18 @@ - (void)testNonCompliantNSCodingNSErrors {
NSError *oauthError =
[[self class] OAuthTokenInvalidGrantErrorWithUnderlyingError:nonCompliantError];
[authstate updateWithAuthorizationError:oauthError];
XCTAssertNoThrow([NSKeyedArchiver archivedDataWithRootObject:authstate], @"");
NSError *error;
NSData *data;
if (@available(iOS 12.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)) {
data = [NSKeyedArchiver archivedDataWithRootObject:authstate
requiringSecureCoding:YES
error:&error];
XCTAssertNoThrow(data, @"");
} else {
#if !TARGET_OS_IOS
XCTAssertNoThrow([NSKeyedArchiver archivedDataWithRootObject:authstate], @"");
#endif
}
}

/*! @brief Tests @c OIDAuthState.updateWithAuthorizationResponse:error: with a success response.
Expand Down Expand Up @@ -358,8 +369,22 @@ - (void)testSecureCoding {
XCTAssert([OIDAuthState supportsSecureCoding], @"");

OIDAuthState *authState = [[self class] testInstance];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:authState];
OIDAuthState *authStateCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
OIDAuthState *authStateCopy;
NSError *error;
NSData *data;
if (@available(iOS 12.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)) {
data = [NSKeyedArchiver archivedDataWithRootObject:authState
requiringSecureCoding:YES
error:&error];
authStateCopy = [NSKeyedUnarchiver unarchivedObjectOfClass:[OIDAuthState class]
fromData:data
error:&error];
} else {
#if !TARGET_OS_IOS
data = [NSKeyedArchiver archivedDataWithRootObject:authState];
authStateCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
#endif
}

XCTAssertEqualObjects(authStateCopy.refreshToken, authState.refreshToken, @"");
XCTAssertEqualObjects(authStateCopy.scope, authState.scope, @"");
Expand All @@ -375,9 +400,26 @@ - (void)testSecureCoding {
// Verify the error object is indeed restored.
NSError *oauthError = [[self class] OAuthTokenInvalidGrantErrorWithUnderlyingError:nil];
[authState updateWithTokenResponse:nil error:oauthError];
data = [NSKeyedArchiver archivedDataWithRootObject:authState];
if (@available(iOS 12.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)) {
data = [NSKeyedArchiver archivedDataWithRootObject:authState
requiringSecureCoding:YES
error:&error];
} else {
#if !TARGET_OS_IOS
data = [NSKeyedArchiver archivedDataWithRootObject:authState];
#endif
}
XCTAssertNotNil(authState.authorizationError, @"");
authStateCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];

if (@available(iOS 12.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)) {
authStateCopy = [NSKeyedUnarchiver unarchivedObjectOfClass:[OIDAuthState class]
fromData:data
error:&error];
} else {
#if !TARGET_OS_IOS
authStateCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
#endif
}
XCTAssertEqualObjects(authStateCopy.authorizationError.domain,
authState.authorizationError.domain, @"");
XCTAssertEqual(authStateCopy.authorizationError.code, authState.authorizationError.code, @"");
Expand Down
18 changes: 16 additions & 2 deletions UnitTests/OIDAuthorizationRequestTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,22 @@ - (void)testSecureCoding {
XCTAssertEqualObjects(request.additionalParameters[kTestAdditionalParameterKey],
kTestAdditionalParameterValue, @"");

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:request];
OIDAuthorizationRequest *requestCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
OIDAuthorizationRequest *requestCopy;
NSError *error;
NSData *data;
if (@available(iOS 12.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)) {
data = [NSKeyedArchiver archivedDataWithRootObject:request
requiringSecureCoding:YES
error:&error];
requestCopy = [NSKeyedUnarchiver unarchivedObjectOfClass:[OIDAuthorizationRequest class]
fromData:data
error:&error];
} else {
#if !TARGET_OS_IOS
data = [NSKeyedArchiver archivedDataWithRootObject:request];
requestCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
#endif
}

// Not a full test of the configuration deserialization, but should be sufficient as a smoke test
// to make sure the configuration IS actually getting serialized and deserialized in the
Expand Down
18 changes: 16 additions & 2 deletions UnitTests/OIDAuthorizationResponseTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,22 @@ - (void)testCopying {
*/
- (void)testSecureCoding {
OIDAuthorizationResponse *response = [[self class] testInstance];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:response];
OIDAuthorizationResponse *responseCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
OIDAuthorizationResponse *responseCopy;
NSError *error;
NSData *data;
if (@available(iOS 12.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *)) {
data = [NSKeyedArchiver archivedDataWithRootObject:response
requiringSecureCoding:YES
error:&error];
responseCopy = [NSKeyedUnarchiver unarchivedObjectOfClass:[OIDAuthorizationResponse class]
fromData:data
error:&error];
} else {
#if !TARGET_OS_IOS
data = [NSKeyedArchiver archivedDataWithRootObject:response];
responseCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
#endif
}

// Not a full test of the request deserialization, but should be sufficient as a smoke test
// to make sure the request IS actually getting serialized and deserialized in the
Expand Down
Loading