diff --git a/Simplicity.xcodeproj/project.pbxproj b/Simplicity.xcodeproj/project.pbxproj
index 14421cd..5d705d1 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;
};
};
};
@@ -165,6 +165,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
+ English,
en,
);
mainGroup = DF74EC261CE2A8BB008F16BF;
@@ -218,14 +219,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 +279,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 +341,8 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 3.0;
+ SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -344,7 +362,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 = 5.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 @@
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.flatMap({($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)
+ }
+ }
- return urlSchemes.flatMap({closure($0) ? $0 : nil})
+ // Filter schemes with parameter block
+ return urlSchemes.compactMap({closure($0) ? $0 : nil})
}
/**
@@ -36,7 +42,7 @@ class Helpers {
- returns: A query string
*/
static func queryString(_ parts: [String: String?]) -> 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..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
}
@@ -53,7 +58,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
})
diff --git a/Simplicity/Simplicity.swift b/Simplicity/Simplicity.swift
index 347a888..f668cee 100644
--- a/Simplicity/Simplicity.swift
+++ b/Simplicity/Simplicity.swift
@@ -12,43 +12,61 @@ 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
+ 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
}
- 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
}
/// 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) {
@@ -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()
+
+ }
}