From ef52ada9326a25bef1166f5c82bf0b9fc37564a6 Mon Sep 17 00:00:00 2001 From: Vinzius Date: Tue, 3 Apr 2018 10:48:35 +0200 Subject: [PATCH 1/5] Updated code for Swift 4.1 --- Simplicity.xcodeproj/project.pbxproj | 26 ++++++++++++++++--- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++ .../xcschemes/Simplicity.xcscheme | 2 +- Simplicity/Helpers.swift | 6 ++--- Simplicity/LoginProviders/Facebook.swift | 2 +- Simplicity/LoginProviders/VKontakte.swift | 2 +- Simplicity/OAuth2.swift | 2 +- 7 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 Simplicity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Simplicity.xcodeproj/project.pbxproj b/Simplicity.xcodeproj/project.pbxproj index 14421cd..67f6265 100644 --- a/Simplicity.xcodeproj/project.pbxproj +++ b/Simplicity.xcodeproj/project.pbxproj @@ -151,12 +151,12 @@ DF74EC271CE2A8BB008F16BF /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0930; ORGANIZATIONNAME = Stormpath; TargetAttributes = { DF74EC2F1CE2A8BB008F16BF = { CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0930; }; }; }; @@ -218,14 +218,22 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -270,14 +278,22 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -324,7 +340,8 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -344,7 +361,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.stormpath.Simplicity; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_SWIFT3_OBJC_INFERENCE = Default; + SWIFT_VERSION = 4.0; }; name = Release; }; diff --git a/Simplicity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Simplicity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Simplicity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Simplicity.xcodeproj/xcshareddata/xcschemes/Simplicity.xcscheme b/Simplicity.xcodeproj/xcshareddata/xcschemes/Simplicity.xcscheme index 6d0e049..3748824 100644 --- a/Simplicity.xcodeproj/xcshareddata/xcschemes/Simplicity.xcscheme +++ b/Simplicity.xcodeproj/xcshareddata/xcschemes/Simplicity.xcscheme @@ -1,6 +1,6 @@ String? { - return parts.flatMap { key, value -> String? in + return parts.compactMap { key, value -> String? in if let value = value { return key + "=" + value } else { diff --git a/Simplicity/LoginProviders/Facebook.swift b/Simplicity/LoginProviders/Facebook.swift index 1bea523..b3469a7 100644 --- a/Simplicity/LoginProviders/Facebook.swift +++ b/Simplicity/LoginProviders/Facebook.swift @@ -53,7 +53,7 @@ public class Facebook: OAuth2 { let range = urlScheme.range(of: "\\d+", options: .regularExpression) else { preconditionFailure("You must configure your Facebook URL Scheme to use Facebook login.") } - let clientId = urlScheme.substring(with: range) + let clientId = String(urlScheme[range.lowerBound.. URLQueryItem? in + url.queryItems = authorizationURLParameters.compactMap({key, value -> URLQueryItem? in return value != nil ? URLQueryItem(name: key, value: value) : nil }) From d7261a1917035067a6b2a7b1b3576080887939b0 Mon Sep 17 00:00:00 2001 From: Vinzius Date: Tue, 3 Apr 2018 11:32:34 +0200 Subject: [PATCH 2/5] Get the full url scheme list and not the first entry --- Simplicity/Helpers.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Simplicity/Helpers.swift b/Simplicity/Helpers.swift index 244d717..ca05719 100644 --- a/Simplicity/Helpers.swift +++ b/Simplicity/Helpers.swift @@ -18,13 +18,19 @@ class Helpers { - returns: A list of URL Schemes that match the filter closure. */ static func registeredURLSchemes(filter closure: (String) -> Bool) -> [String] { + // Retrieve url types from the main bundle guard let urlTypes = Bundle.main.infoDictionary?["CFBundleURLTypes"] as? [[String: AnyObject]] else { return [String]() } // Convert the complex dictionary into an array of URL schemes - let urlSchemes = urlTypes.compactMap({($0["CFBundleURLSchemes"] as? [String])?.first }) + let urlSchemes: [String] = urlTypes.reduce(into: []) { (result, component) in + if let schemes = component["CFBundleURLSchemes"] as? [String] { + result.append(contentsOf: schemes) + } + } + // Filter schemes with parameter block return urlSchemes.compactMap({closure($0) ? $0 : nil}) } From e9eb95a776ed5eb3dce4385135ed937872e127ba Mon Sep 17 00:00:00 2001 From: Vinzius Date: Tue, 3 Apr 2018 15:16:33 +0200 Subject: [PATCH 3/5] Try using SFAuthenticationSession if available --- Simplicity/Simplicity.swift | 50 ++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/Simplicity/Simplicity.swift b/Simplicity/Simplicity.swift index 347a888..d955b72 100644 --- a/Simplicity/Simplicity.swift +++ b/Simplicity/Simplicity.swift @@ -12,36 +12,54 @@ import SafariServices /// Callback handler after an external login completes. public typealias ExternalLoginCallback = (String?, NSError?) -> Void -/** +/** Simplicity is a framework for authenticating with external providers on iOS. */ public final class Simplicity { private static var currentLoginProvider: LoginProvider? private static var callback: ExternalLoginCallback? private static var safari: UIViewController? + @available(iOS 11.0, *) + private static var authSession: SFAuthenticationSession? /** Begin the login flow by redirecting to the LoginProvider's website. - parameters: - - loginProvider: The login provider object configured to be used. - - callback: A callback with the access token, or a SimplicityError. + - loginProvider: The login provider object configured to be used. + - callback: A callback with the access token, or a SimplicityError. */ public static func login(_ loginProvider: LoginProvider, callback: @escaping ExternalLoginCallback) { self.currentLoginProvider = loginProvider self.callback = callback - presentSafariView(loginProvider.authorizationURL) + if #available(iOS 11, *) { + if self.presentAuthentificationSession(url: loginProvider.authorizationURL, callbackURL: loginProvider.urlScheme) == false { + self.presentSafariView(loginProvider.authorizationURL) + } + } else { + self.presentSafariView(loginProvider.authorizationURL) + } } /// Deep link handler (iOS9) public static func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any]) -> Bool { - safari?.dismiss(animated: true, completion: nil) - guard let callback = callback, url.scheme == currentLoginProvider?.urlScheme else { - return false + if let safari = self.safari { + safari.dismiss(animated: true, completion: nil) + self.safari = nil } - currentLoginProvider?.linkHandler(url, callback: callback) - currentLoginProvider = nil + if #available(iOS 11.0, *) { + if let auth = self.authSession { + auth.cancel() + self.authSession = nil + } + } + guard let callback = self.callback, + let currentLoginProvider = self.currentLoginProvider, + url.scheme == currentLoginProvider.urlScheme + else { return false } + currentLoginProvider.linkHandler(url, callback: callback) + self.currentLoginProvider = nil return true } @@ -63,4 +81,18 @@ public final class Simplicity { UIApplication.shared.openURL(url) } } + + @available(iOS 11.0, *) + private static func presentAuthentificationSession(url: URL, callbackURL: String) -> Bool { + + let session = SFAuthenticationSession(url: url, callbackURLScheme: nil) { (url, error) in + self.authSession = nil + if let url = url { + self.application(UIApplication.shared, open: url, options: [:]) + } + } + self.authSession = session + return session.start() + + } } From e3601ebcf85676afaac548ad4331d4f73de05c06 Mon Sep 17 00:00:00 2001 From: Vinzius Date: Tue, 3 Apr 2018 15:17:02 +0200 Subject: [PATCH 4/5] Send more parameters with FB request so button "connect with facebook app" is visible --- Simplicity/LoginProviders/Facebook.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Simplicity/LoginProviders/Facebook.swift b/Simplicity/LoginProviders/Facebook.swift index b3469a7..f5a85db 100644 --- a/Simplicity/LoginProviders/Facebook.swift +++ b/Simplicity/LoginProviders/Facebook.swift @@ -38,7 +38,12 @@ public class Facebook: OAuth2 { /// An array with query string parameters for the authorization URL. override public var authorizationURLParameters: [String : String?] { var result = super.authorizationURLParameters + // Required parameters to have the button to connect via the native fb app result["auth_type"] = authType.rawValue + result["display"] = "touch" + result["sdk"] = "ios" + result["fbapp_pres"] = "1" + result["sdk_version"] = "4.31.1" return result } From 1f84144880bf2b61376146bb1a2d96d1202a5928 Mon Sep 17 00:00:00 2001 From: Vinzius Date: Fri, 21 Jun 2019 17:26:11 +0200 Subject: [PATCH 5/5] Fixes for Swift 5. --- Simplicity.xcodeproj/project.pbxproj | 5 +++-- Simplicity/Simplicity.swift | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Simplicity.xcodeproj/project.pbxproj b/Simplicity.xcodeproj/project.pbxproj index 67f6265..5d705d1 100644 --- a/Simplicity.xcodeproj/project.pbxproj +++ b/Simplicity.xcodeproj/project.pbxproj @@ -165,6 +165,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = DF74EC261CE2A8BB008F16BF; @@ -341,7 +342,7 @@ SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -362,7 +363,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/Simplicity/Simplicity.swift b/Simplicity/Simplicity.swift index d955b72..f668cee 100644 --- a/Simplicity/Simplicity.swift +++ b/Simplicity/Simplicity.swift @@ -43,7 +43,7 @@ public final class Simplicity { } /// Deep link handler (iOS9) - public static func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any]) -> Bool { + public static func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) -> Bool { if let safari = self.safari { safari.dismiss(animated: true, completion: nil) self.safari = nil @@ -66,7 +66,7 @@ public final class Simplicity { /// Deep link handler ( Bool { - return self.application(application, open: url, options: [UIApplicationOpenURLOptionsKey: Any]()) + return self.application(application, open: url, options: [UIApplication.OpenURLOptionsKey: Any]()) } private static func presentSafariView(_ url: URL) { @@ -88,7 +88,7 @@ public final class Simplicity { let session = SFAuthenticationSession(url: url, callbackURLScheme: nil) { (url, error) in self.authSession = nil if let url = url { - self.application(UIApplication.shared, open: url, options: [:]) + _ = self.application(UIApplication.shared, open: url, options: [:]) } } self.authSession = session