diff --git a/.circleci/config.yml b/.circleci/config.yml index 86b7191b3..83f3dfbf4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,6 @@ version: 2 jobs: - build-and-test-swift-4.0: + build-and-test-swift-4.2: macos: xcode: "10.0.0" environment: @@ -8,11 +8,10 @@ jobs: LANG: en_US.UTF-8 steps: - checkout - - run: | + - run: | brew install swiftlint bundle install --without=development grep -lR "shouldUseLaunchSchemeArgsEnv" *.* --null | xargs -0 sed -i '' -e 's/shouldUseLaunchSchemeArgsEnv = "YES"/shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES"/g' - sed -i "" 's/SWIFT_VERSION = 3.0/SWIFT_VERSION = 4.0/g' "Lock.xcodeproj/project.pbxproj" - run: name: Bootstrap command: bundle exec fastlane ios bootstrap @@ -24,7 +23,36 @@ jobs: DEVICE: iPhone 8 FASTLANE_EXPLICIT_OPEN_SIMULATOR: 2 - run: | - bash <(curl -s https://codecov.io/bash) -J 'Lock' + bash <(curl -s https://codecov.io/bash) -J 'Lock' + - save_cache: + key: dependency-cache + paths: + - Carthage/Build + - store_test_results: + path: fastlane/test_output + build-and-test-swift-4.0: + macos: + xcode: "10.0.0" + environment: + LC_ALL: en_US.UTF-8 + LANG: en_US.UTF-8 + steps: + - checkout + - run: | + brew install swiftlint + bundle install --without=development + grep -lR "shouldUseLaunchSchemeArgsEnv" *.* --null | xargs -0 sed -i '' -e 's/shouldUseLaunchSchemeArgsEnv = "YES"/shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES"/g' + sed -i "" 's/SWIFT_VERSION = 4.2/SWIFT_VERSION = 4.0/g' "Lock.xcodeproj/project.pbxproj" + - run: + name: Bootstrap + command: bundle exec fastlane ios bootstrap + - run: + name: Run test suite + command: bundle exec fastlane ios ci + environment: + SCHEME: Lock + DEVICE: iPhone 8 + FASTLANE_EXPLICIT_OPEN_SIMULATOR: 2 - save_cache: key: dependency-cache paths: @@ -39,11 +67,12 @@ jobs: LANG: en_US.UTF-8 steps: - checkout - - run: | + - run: | brew install swiftlint sudo gem install bundler bundle install --without=development grep -lR "shouldUseLaunchSchemeArgsEnv" *.* --null | xargs -0 sed -i '' -e 's/shouldUseLaunchSchemeArgsEnv = "YES"/shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES"/g' + sed -i "" 's/SWIFT_VERSION = 4.2/SWIFT_VERSION = 3.0/g' "Lock.xcodeproj/project.pbxproj" - run: name: Bootstrap command: bundle exec fastlane ios bootstrap @@ -63,9 +92,12 @@ jobs: workflows: version: 2 - build-test-report: + build-test-4.2: + jobs: + - build-and-test-swift-4.2 + build-test-4.0: jobs: - build-and-test-swift-4.0 - build-test: + build-test-3.0: jobs: - build-and-test-swift-3.0 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 70291de7c..c9870d0ec 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ build/ !default.mode2v3 *.perspectivev3 !default.perspectivev3 +IDEWorkspaceChecks.plist xcuserdata *.xccheckout profile @@ -53,4 +54,4 @@ fastlane/screenshots/ vendor/ #Entitlements -LockApp.entitlements \ No newline at end of file +LockApp.entitlements diff --git a/App/AppDelegate.swift b/App/AppDelegate.swift index 042eff524..b35b41fbe 100644 --- a/App/AppDelegate.swift +++ b/App/AppDelegate.swift @@ -8,22 +8,29 @@ import UIKit import Lock +import Auth0 + +#if swift(>=4.2) +typealias A0RestorationHandler = UIUserActivityRestoring +#else +typealias A0RestorationHandler = Any +#endif @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [A0ApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool { + func application(_ app: UIApplication, open url: URL, options: [A0URLOptionsKey : Any]) -> Bool { return Lock.resumeAuth(url, options: options) } - func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { + func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([A0RestorationHandler]?) -> Void) -> Bool { return Lock.continueAuth(using: userActivity) } diff --git a/Cartfile.resolved b/Cartfile.resolved index 657c53742..7168b57e7 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,6 +1,6 @@ github "AliSoftware/OHHTTPStubs" "6.1.0" -github "Quick/Nimble" "v7.3.0" -github "Quick/Quick" "v1.3.1" +github "Quick/Nimble" "v7.3.1" +github "Quick/Quick" "v1.3.2" github "auth0/Auth0.swift" "1.13.0" github "auth0/SimpleKeychain" "0.8.1" github "emaloney/CleanroomLogger" "5.1.2" diff --git a/Lock.xcodeproj/project.pbxproj b/Lock.xcodeproj/project.pbxproj index 78f7d3dbe..ff401911e 100644 --- a/Lock.xcodeproj/project.pbxproj +++ b/Lock.xcodeproj/project.pbxproj @@ -1023,14 +1023,14 @@ TargetAttributes = { 5BEDE1391EC0A9750007300D = { CreatedOnToolsVersion = 8.3.2; - LastSwiftMigration = 0930; + LastSwiftMigration = 1000; ProvisioningStyle = Manual; TestTargetID = 5FEADCF31D1A7EBC0032D810; }; 5FEADCF31D1A7EBC0032D810 = { CreatedOnToolsVersion = 7.3.1; DevelopmentTeam = 86WQXF56BC; - LastSwiftMigration = 0930; + LastSwiftMigration = 1000; ProvisioningStyle = Manual; SystemCapabilities = { com.apple.SafariKeychain = { @@ -1040,11 +1040,11 @@ }; 5FEAE1C51D1A5154005C0028 = { CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0930; + LastSwiftMigration = 1000; }; 5FEAE1CF1D1A5154005C0028 = { CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0920; + LastSwiftMigration = 1000; ProvisioningStyle = Manual; TestTargetID = 5FEADCF31D1A7EBC0032D810; }; @@ -1135,7 +1135,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "AUTH0_PLIST=\"${SRCROOT}/Auth0.plist\"\nif [ -f $AUTH0_PLIST ];\nthen\ncp \"$AUTH0_PLIST\" \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app\"\nfi"; + shellScript = "AUTH0_PLIST=\"${SRCROOT}/Auth0.plist\"\nif [ -f \"$AUTH0_PLIST\" ];\nthen\ncp \"$AUTH0_PLIST\" \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app\"\nfi\n"; }; 5FEADD061D1A7ECA0032D810 /* Carthage */ = { isa = PBXShellScriptBuildPhase; @@ -1411,7 +1411,6 @@ PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.0; TEST_TARGET_NAME = LockApp; }; name = Debug; @@ -1430,7 +1429,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 4.0; TEST_TARGET_NAME = LockApp; }; name = Release; @@ -1454,8 +1452,6 @@ PROVISIONING_PROFILE = "97f7985c-a5ce-42be-a3e5-39a6c818bc78"; PROVISIONING_PROFILE_SPECIFIER = "match Development com.auth0.Lock"; REEXPORTED_LIBRARY_PATHS = ""; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -1478,8 +1474,6 @@ PROVISIONING_PROFILE = "97f7985c-a5ce-42be-a3e5-39a6c818bc78"; PROVISIONING_PROFILE_SPECIFIER = "match Development com.auth0.Lock"; REEXPORTED_LIBRARY_PATHS = ""; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; }; name = Release; }; @@ -1536,6 +1530,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1588,6 +1583,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -1618,8 +1614,6 @@ SKIP_INSTALL = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -1644,8 +1638,6 @@ PRODUCT_NAME = Lock; SKIP_INSTALL = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; }; name = Release; }; @@ -1661,8 +1653,6 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.auth0.LockTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LockApp.app/LockApp"; }; name = Debug; @@ -1679,8 +1669,6 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.auth0.LockTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LockApp.app/LockApp"; }; name = Release; diff --git a/Lock/AuthButton.swift b/Lock/AuthButton.swift index be51d7539..238f71832 100644 --- a/Lock/AuthButton.swift +++ b/Lock/AuthButton.swift @@ -40,7 +40,7 @@ public class AuthButton: UIView { public var normalColor: UIColor = UIColor.a0_orange { didSet { let normal = image(withColor: self.normalColor) - self.button?.setBackgroundImage(normal, for: UIControlState()) + self.button?.setBackgroundImage(normal, for: .normal) } } @@ -150,9 +150,9 @@ public class AuthButton: UIView { iconView.contentMode = .center iconView.tintColor = self.titleColor - button.setBackgroundImage(image(withColor: self.color), for: UIControlState()) + button.setBackgroundImage(image(withColor: self.color), for: .normal) button.setBackgroundImage(image(withColor: self.color.a0_darker(0.3)), for: .highlighted) - button.setTitleColor(self.titleColor, for: UIControlState()) + button.setTitleColor(self.titleColor, for: .normal) button.titleLabel?.font = .systemFont(ofSize: 13.33, weight: UIFont.weightMedium) button.titleLabel?.adjustsFontSizeToFitWidth = true button.titleLabel?.minimumScaleFactor = 0.5 @@ -161,7 +161,7 @@ public class AuthButton: UIView { button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside) if case .big = self.size { - button.setTitle(self.title, for: UIControlState()) + button.setTitle(self.title, for: .normal) } self.button = button diff --git a/Lock/AuthCollectionView.swift b/Lock/AuthCollectionView.swift index 27d08cb8e..415ee7d27 100644 --- a/Lock/AuthCollectionView.swift +++ b/Lock/AuthCollectionView.swift @@ -66,7 +66,7 @@ class AuthCollectionView: UIView, View { } public override var intrinsicContentSize: CGSize { - return CGSize(width: UIViewNoIntrinsicMetric, height: self.height) + return CGSize(width: UIView.viewNoIntrinsicMetric, height: self.height) } private func layout(_ connections: [OAuth2Connection], mode: Mode, insets: UIEdgeInsets) { diff --git a/Lock/DatabaseModeSwitcher.swift b/Lock/DatabaseModeSwitcher.swift index c766e4d93..7d6d61410 100644 --- a/Lock/DatabaseModeSwitcher.swift +++ b/Lock/DatabaseModeSwitcher.swift @@ -84,22 +84,22 @@ class DatabaseModeSwitcher: UIView { dimension(dimension: segmented.heightAnchor, withValue: 45) segmented.translatesAutoresizingMaskIntoConstraints = false - segmented.setDividerImage(image(named: "ic_switcher_left", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: .selected, rightSegmentState: UIControlState(), barMetrics: .default) - segmented.setDividerImage(image(named: "ic_switcher_right", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: UIControlState(), rightSegmentState: .selected, barMetrics: .default) + segmented.setDividerImage(image(named: "ic_switcher_left", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: .selected, rightSegmentState: .normal, barMetrics: .default) + segmented.setDividerImage(image(named: "ic_switcher_right", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: .normal, rightSegmentState: .selected, barMetrics: .default) segmented.setDividerImage(image(named: "ic_switcher_both", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: .selected, rightSegmentState: .selected, barMetrics: .default) segmented.setDividerImage(image(named: "ic_switcher_both", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: .highlighted, rightSegmentState: .selected, barMetrics: .default) segmented.setDividerImage(image(named: "ic_switcher_both", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: .selected, rightSegmentState: .highlighted, barMetrics: .default) - segmented.setDividerImage(image(named: "ic_switcher_none", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: UIControlState(), rightSegmentState: UIControlState(), barMetrics: .default) + segmented.setDividerImage(image(named: "ic_switcher_none", compatibleWithTraitCollection: self.traitCollection), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default) segmented.setBackgroundImage(image(named: "ic_switcher_selected", compatibleWithTraitCollection: self.traitCollection), for: .selected, barMetrics: .default) segmented.setBackgroundImage(image(named: "ic_switcher_selected", compatibleWithTraitCollection: self.traitCollection), for: .highlighted, barMetrics: .default) - segmented.setBackgroundImage(image(named: "ic_switcher_normal", compatibleWithTraitCollection: self.traitCollection), for: UIControlState(), barMetrics: .default) + segmented.setBackgroundImage(image(named: "ic_switcher_normal", compatibleWithTraitCollection: self.traitCollection), for: .normal, barMetrics: .default) segmented.setTitleTextAttributes([ - attributedKeyColor: Style.Auth0.tabTextColor, - attributedFont: mediumSystemFont(size: 15) - ], for: UIControlState()) + NSAttributedString.attributedKeyColor: Style.Auth0.tabTextColor, + NSAttributedString.attributedFont: mediumSystemFont(size: 15) + ], for: .normal) segmented.setTitleTextAttributes([ - attributedKeyColor: Style.Auth0.tabTextColor, - attributedFont: semiBoldSystemFont(size: 15) + NSAttributedString.attributedKeyColor: Style.Auth0.tabTextColor, + NSAttributedString.attributedFont: semiBoldSystemFont(size: 15) ], for: .selected) segmented.tintColor = Style.Auth0.tabTintColor segmented.addTarget(self, action: #selector(selectedIndex), for: .valueChanged) @@ -109,7 +109,7 @@ class DatabaseModeSwitcher: UIView { } override var intrinsicContentSize: CGSize { - return CGSize(width: UIViewNoIntrinsicMetric, height: 55) + return CGSize(width: UIView.viewNoIntrinsicMetric, height: 55) } // MARK: - Internal @@ -124,12 +124,12 @@ extension DatabaseModeSwitcher: Stylable { func apply(style: Style) { self.segmentedControl?.tintColor = style.tabTintColor self.segmentedControl?.setTitleTextAttributes([ - attributedKeyColor: style.tabTextColor, - attributedFont: mediumSystemFont(size: 15) - ], for: UIControlState()) + NSAttributedString.attributedKeyColor: style.tabTextColor, + NSAttributedString.attributedFont: mediumSystemFont(size: 15) + ], for: .normal) self.segmentedControl?.setTitleTextAttributes([ - attributedKeyColor: style.tabTextColor, - attributedFont: semiBoldSystemFont(size: 15) + NSAttributedString.attributedKeyColor: style.tabTextColor, + NSAttributedString.attributedFont: semiBoldSystemFont(size: 15) ], for: .selected) } } diff --git a/Lock/Extensions.swift b/Lock/Extensions.swift index c0cc6169d..8b7aac63b 100644 --- a/Lock/Extensions.swift +++ b/Lock/Extensions.swift @@ -48,9 +48,9 @@ extension UIView { extension UILayoutPriority { #if swift(>=4.0) - static let priorityRequired = UILayoutPriority.required - static let priorityDefaultLow = UILayoutPriority.defaultLow - static let priorityDefaultHigh = UILayoutPriority.defaultHigh + static let priorityRequired = required + static let priorityDefaultLow = defaultLow + static let priorityDefaultHigh = defaultHigh #else static let priorityRequired = UILayoutPriorityRequired static let priorityDefaultLow = UILayoutPriorityDefaultLow @@ -58,20 +58,25 @@ extension UILayoutPriority { #endif } -#if swift(>=4.0) -let attributedKeyColor = NSAttributedStringKey.foregroundColor -let attributedFont = NSAttributedStringKey.font -#else -let attributedKeyColor = NSForegroundColorAttributeName -let attributedFont = NSFontAttributeName -#endif +extension NSAttributedString { + #if swift(>=4.2) + static let attributedKeyColor = Key.foregroundColor + static let attributedFont = Key.font + #elseif swift(>=4.0) + static let attributedKeyColor = NSAttributedStringKey.foregroundColor + static let attributedFont = NSAttributedStringKey.font + #else + static let attributedKeyColor = NSForegroundColorAttributeName + static let attributedFont = NSFontAttributeName + #endif +} extension UIFont { #if swift(>=4.0) - static let weightLight = UIFont.Weight.light - static let weightMedium = UIFont.Weight.medium - static let weightRegular = UIFont.Weight.regular - static let weightSemiBold = UIFont.Weight.semibold + static let weightLight = Weight.light + static let weightMedium = Weight.medium + static let weightRegular = Weight.regular + static let weightSemiBold = Weight.semibold #else static let weightLight = UIFontWeightLight static let weightMedium = UIFontWeightMedium @@ -79,3 +84,85 @@ extension UIFont { static let weightSemiBold = UIFontWeightSemibold #endif } + +#if swift(>=4.2) +let accessibilityIsReduceTransparencyEnabled = UIAccessibility.isReduceTransparencyEnabled +#else +let accessibilityIsReduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled() +#endif + +extension UIView { + #if swift(>=4.2) + static let viewNoIntrinsicMetric = noIntrinsicMetric + #else + static let viewNoIntrinsicMetric = UIViewNoIntrinsicMetric + #endif +} + +// swiftlint:disable identifier_name +extension UIResponder { + #if swift(>=4.2) + static let responderKeyboardWillShowNotification = keyboardWillShowNotification + static let responderKeyboardWillHideNotification = keyboardWillHideNotification + static let responderKeyboardFrameEndUserInfoKey = keyboardFrameEndUserInfoKey + static let responderKeyboardAnimationDurationUserInfoKey = keyboardAnimationDurationUserInfoKey + static let responderKeyboardAnimationCurveUserInfoKey = keyboardAnimationCurveUserInfoKey + #else + static let responderKeyboardWillShowNotification = NSNotification.Name.UIKeyboardWillShow + static let responderKeyboardWillHideNotification = NSNotification.Name.UIKeyboardWillHide + static let responderKeyboardFrameEndUserInfoKey = UIKeyboardFrameEndUserInfoKey + static let responderKeyboardAnimationDurationUserInfoKey = UIKeyboardAnimationDurationUserInfoKey + static let responderKeyboardAnimationCurveUserInfoKey = UIKeyboardAnimationCurveUserInfoKey + #endif +} +// swiftlint:enable identifier_name + +// MARK: - Public Typealiases + +#if swift(>=4.2) +public typealias A0AlertActionStyle = UIAlertAction.Style +#else +public typealias A0AlertActionStyle = UIAlertActionStyle +#endif + +#if swift(>=4.2) +public typealias A0AlertControllerStyle = UIAlertController.Style +#else +public typealias A0AlertControllerStyle = UIAlertControllerStyle +#endif + +#if swift(>=4.2) +public typealias A0URLOptionsKey = UIApplication.OpenURLOptionsKey +#else +public typealias A0URLOptionsKey = UIApplicationOpenURLOptionsKey +#endif + +#if swift(>=4.2) +public typealias A0ApplicationLaunchOptionsKey = UIApplication.LaunchOptionsKey +#else +public typealias A0ApplicationLaunchOptionsKey = UIApplicationLaunchOptionsKey +#endif + +#if swift(>=4.2) +public typealias A0BlurEffectStyle = UIBlurEffect.Style +#else +public typealias A0BlurEffectStyle = UIBlurEffectStyle +#endif + +#if swift(>=4.2) +public typealias A0ControlState = UIControl.State +#else +public typealias A0ControlState = UIControlState +#endif + +#if swift(>=4.2) +public typealias A0SearchBarStyle = UISearchBar.Style +#else +public typealias A0SearchBarStyle = UISearchBarStyle +#endif + +#if swift(>=4.2) +public typealias A0ViewAnimationOptions = UIView.AnimationOptions +#else +public typealias A0ViewAnimationOptions = UIViewAnimationOptions +#endif diff --git a/Lock/HeaderView.swift b/Lock/HeaderView.swift index cfb439b7c..ad03b1dda 100644 --- a/Lock/HeaderView.swift +++ b/Lock/HeaderView.swift @@ -96,7 +96,7 @@ public class HeaderView: UIView { } } - public var blurStyle: UIBlurEffectStyle = .light { + public var blurStyle: A0BlurEffectStyle = .light { didSet { self.applyBackground() self.setNeedsDisplay() @@ -166,9 +166,9 @@ public class HeaderView: UIView { self.apply(style: Style.Auth0) titleView.font = regularSystemFont(size: 20) logoView.image = image(named: "ic_auth0", compatibleWithTraitCollection: self.traitCollection) - closeButton.setBackgroundImage(image(named: "ic_close", compatibleWithTraitCollection: self.traitCollection)?.withRenderingMode(.alwaysOriginal), for: UIControlState()) + closeButton.setBackgroundImage(image(named: "ic_close", compatibleWithTraitCollection: self.traitCollection)?.withRenderingMode(.alwaysOriginal), for: .normal) closeButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside) - backButton.setBackgroundImage(image(named: "ic_back", compatibleWithTraitCollection: self.traitCollection)?.withRenderingMode(.alwaysOriginal), for: UIControlState()) + backButton.setBackgroundImage(image(named: "ic_back", compatibleWithTraitCollection: self.traitCollection)?.withRenderingMode(.alwaysOriginal), for: .normal) backButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside) self.titleView = titleView @@ -197,7 +197,7 @@ public class HeaderView: UIView { // MARK: - Blur private var canBlur: Bool { - return self.blurred && !UIAccessibilityIsReduceTransparencyEnabled() + return self.blurred && !accessibilityIsReduceTransparencyEnabled } private func applyBackground() { diff --git a/Lock/IconButton.swift b/Lock/IconButton.swift index 61a83c72a..24205d333 100644 --- a/Lock/IconButton.swift +++ b/Lock/IconButton.swift @@ -77,6 +77,6 @@ class IconButton: UIView { } override var intrinsicContentSize: CGSize { - return CGSize(width: 50, height: UIViewNoIntrinsicMetric) + return CGSize(width: 50, height: UIView.viewNoIntrinsicMetric) } } diff --git a/Lock/InfoBarView.swift b/Lock/InfoBarView.swift index 4064f2b5d..4cf1acb86 100644 --- a/Lock/InfoBarView.swift +++ b/Lock/InfoBarView.swift @@ -97,7 +97,7 @@ class InfoBarView: UIView { } override var intrinsicContentSize: CGSize { - return CGSize(width: UIViewNoIntrinsicMetric, height: 35) + return CGSize(width: UIView.viewNoIntrinsicMetric, height: 35) } static var ssoInfoBar: InfoBarView { diff --git a/Lock/InputField.swift b/Lock/InputField.swift index 844405970..784aa4bcd 100644 --- a/Lock/InputField.swift +++ b/Lock/InputField.swift @@ -353,7 +353,7 @@ class InputField: UIView, Stylable { self.borderColorError = style.inputBorderColorError self.textField?.textColor = style.inputTextColor self.textField?.attributedPlaceholder = NSAttributedString(string: self.textField?.placeholder ?? "", - attributes: [attributedKeyColor: style.inputPlaceholderTextColor]) + attributes: [NSAttributedString.attributedKeyColor: style.inputPlaceholderTextColor]) self.containerView?.backgroundColor = style.inputBackgroundColor self.containerView?.layer.borderColor = style.inputBorderColor.cgColor self.errorLabel?.textColor = style.inputBorderColorError diff --git a/Lock/LoadingView.swift b/Lock/LoadingView.swift index 331cdb631..05dd01f3c 100644 --- a/Lock/LoadingView.swift +++ b/Lock/LoadingView.swift @@ -47,7 +47,11 @@ class LoadingView: UIView, View { super.init(frame: CGRect.zero) self.backgroundColor = Style.Auth0.backgroundColor + #if swift(>=4.2) + let activityIndicator = UIActivityIndicatorView(style: .whiteLarge) + #else let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge) + #endif apply(style: Style.Auth0) activityIndicator.translatesAutoresizingMaskIntoConstraints = false self.addSubview(activityIndicator) diff --git a/Lock/Lock.swift b/Lock/Lock.swift index 1d2f0fdab..bf92e9fbe 100644 --- a/Lock/Lock.swift +++ b/Lock/Lock.swift @@ -298,7 +298,7 @@ public class Lock: NSObject { - returns: true if the url matched an ongoing Auth session, false otherwise */ - public static func resumeAuth(_ url: URL, options: [UIApplicationOpenURLOptionsKey: Any]) -> Bool { + public static func resumeAuth(_ url: URL, options: [A0URLOptionsKey: Any]) -> Bool { return Auth0.resumeAuth(url, options: options) } diff --git a/Lock/LockViewController.swift b/Lock/LockViewController.swift index bd3805761..f8e7c7400 100644 --- a/Lock/LockViewController.swift +++ b/Lock/LockViewController.swift @@ -115,8 +115,8 @@ public class LockViewController: UIViewController { super.viewDidLoad() let center = NotificationCenter.default - center.addObserver(self, selector: #selector(keyboardWasShown), name: NSNotification.Name.UIKeyboardWillShow, object: nil) - center.addObserver(self, selector: #selector(keyboardWasHidden), name: NSNotification.Name.UIKeyboardWillHide, object: nil) + center.addObserver(self, selector: #selector(keyboardWasShown), name: UIResponder.responderKeyboardWillShowNotification, object: nil) + center.addObserver(self, selector: #selector(keyboardWasHidden), name: UIResponder.responderKeyboardWillHideNotification, object: nil) self.present(self.router.root, title: Route.root.title(withStyle: self.lock.style)) } @@ -156,16 +156,16 @@ public class LockViewController: UIViewController { @objc func keyboardWasShown(_ notification: Notification) { guard - let value = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue, - let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, - let curveValue = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber + let value = notification.userInfo?[UIResponder.responderKeyboardFrameEndUserInfoKey] as? NSValue, + let duration = notification.userInfo?[UIResponder.responderKeyboardAnimationDurationUserInfoKey] as? NSNumber, + let curveValue = notification.userInfo?[UIResponder.responderKeyboardAnimationCurveUserInfoKey] as? NSNumber else { return } let frame = value.cgRectValue let insets = UIEdgeInsets(top: 0, left: 0, bottom: frame.height, right: 0) self.keyboard = true self.scrollView.contentInset = insets - let options = UIViewAnimationOptions(rawValue: UInt(curveValue.intValue << 16)) + let options = A0ViewAnimationOptions(rawValue: UInt(curveValue.intValue << 16)) UIView.animate( withDuration: duration.doubleValue, delay: 0, @@ -178,13 +178,13 @@ public class LockViewController: UIViewController { @objc func keyboardWasHidden(_ notification: Notification) { guard - let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, - let curveValue = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber + let duration = notification.userInfo?[UIResponder.responderKeyboardAnimationDurationUserInfoKey] as? NSNumber, + let curveValue = notification.userInfo?[UIResponder.responderKeyboardAnimationCurveUserInfoKey] as? NSNumber else { return } self.scrollView.contentInset = UIEdgeInsets.zero self.keyboard = false - let options = UIViewAnimationOptions(rawValue: UInt(curveValue.intValue << 16)) + let options = A0ViewAnimationOptions(rawValue: UInt(curveValue.intValue << 16)) UIView.animate( withDuration: duration.doubleValue, delay: 0, diff --git a/Lock/PolicyView.swift b/Lock/PolicyView.swift index 487bb60d8..75ac537bc 100644 --- a/Lock/PolicyView.swift +++ b/Lock/PolicyView.swift @@ -59,7 +59,7 @@ class PolicyView: UIStackView, PasswordPolicyValidatorDelegate { } override var intrinsicContentSize: CGSize { - return CGSize(width: UIViewNoIntrinsicMetric, height: CGFloat(self.views.count * 24)) + return CGSize(width: UIView.viewNoIntrinsicMetric, height: CGFloat(self.views.count * 24)) } } @@ -138,8 +138,8 @@ class RuleView: UIView { attributedText.append(NSAttributedString( string: " " + text, attributes: [ - attributedKeyColor: status.color, - attributedFont: font + NSAttributedString.attributedKeyColor: status.color, + NSAttributedString.attributedFont: font ] )) self.label.attributedText = attributedText diff --git a/Lock/PrimaryButton.swift b/Lock/PrimaryButton.swift index 01c6c8d23..adb63a115 100644 --- a/Lock/PrimaryButton.swift +++ b/Lock/PrimaryButton.swift @@ -75,7 +75,11 @@ class PrimaryButton: UIView, Stylable { private func layoutButton() { let button = UIButton(type: .custom) + #if swift(>=4.2) + let indicator = UIActivityIndicatorView(style: .whiteLarge) + #else let indicator = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge) + #endif self.addSubview(button) self.addSubview(indicator) @@ -106,7 +110,7 @@ class PrimaryButton: UIView, Stylable { button.setAttributedTitle(nil, for: .normal) button.setAttributedTitle(nil, for: .disabled) guard let title = title, !self.hideTitle else { - button.setImage(image(named: "ic_submit", compatibleWithTraitCollection: self.traitCollection), for: UIControlState()) + button.setImage(image(named: "ic_submit", compatibleWithTraitCollection: self.traitCollection), for: .normal) button.setImage(UIImage(), for: .disabled) return } @@ -120,8 +124,8 @@ class PrimaryButton: UIView, Stylable { attributedText.append(NSAttributedString( string: "\(title) ", attributes: [ - attributedKeyColor: self.textColor ?? Style.Auth0.buttonTintColor, - attributedFont: font + NSAttributedString.attributedKeyColor: self.textColor ?? Style.Auth0.buttonTintColor, + NSAttributedString.attributedFont: font ] )) attributedText.append(NSAttributedString(attachment: attachment)) @@ -130,7 +134,7 @@ class PrimaryButton: UIView, Stylable { } override var intrinsicContentSize: CGSize { - return CGSize(width: UIViewNoIntrinsicMetric, height: 95) + return CGSize(width: UIView.viewNoIntrinsicMetric, height: 95) } @objc func pressed(_ sender: Any) { @@ -138,7 +142,7 @@ class PrimaryButton: UIView, Stylable { } func apply(style: Style) { - self.button?.setBackgroundImage(image(withColor: style.primaryColor), for: UIControlState()) + self.button?.setBackgroundImage(image(withColor: style.primaryColor), for: .normal) self.button?.setBackgroundImage(image(withColor: style.primaryColor.a0_darker(0.20)), for: .highlighted) self.button?.setBackgroundImage(image(withColor: style.disabledColor), for: .disabled) self.textColor = style.buttonTintColor diff --git a/Lock/SecondaryButton.swift b/Lock/SecondaryButton.swift index 0cd908eb2..1f4735bc8 100644 --- a/Lock/SecondaryButton.swift +++ b/Lock/SecondaryButton.swift @@ -39,7 +39,7 @@ class SecondaryButton: UIView { return self.button?.currentTitle } set { - self.button?.setTitle(newValue, for: UIControlState()) + self.button?.setTitle(newValue, for: .normal) } } @@ -81,7 +81,7 @@ class SecondaryButton: UIView { } override var intrinsicContentSize: CGSize { - return CGSize(width: UIViewNoIntrinsicMetric, height: 76) + return CGSize(width: UIView.viewNoIntrinsicMetric, height: 76) } @objc func pressed(_ sender: Any) { diff --git a/Lock/Style.swift b/Lock/Style.swift index 41adc3d29..f0b1386c8 100644 --- a/Lock/Style.swift +++ b/Lock/Style.swift @@ -52,7 +52,7 @@ public struct Style { public var headerColor: UIColor? /// Blur effect style used. It can be any value defined in `UIBlurEffectStyle` - public var headerBlur: UIBlurEffectStyle = .light + public var headerBlur: A0BlurEffectStyle = .light /// Header close button image public var headerCloseIcon: LazyImage = lazyImage(named: "ic_close") @@ -125,7 +125,7 @@ public struct Style { public var statusBarStyle: UIStatusBarStyle = .default /// Passwordless search bar style - public var searchBarStyle: UISearchBarStyle = .default + public var searchBarStyle: A0SearchBarStyle = .default /// 1Password Icon color public var onePasswordIconColor = UIColor(red: 0.5725, green: 0.5804, blue: 0.5843, alpha: 1.0) @@ -141,7 +141,7 @@ public struct Style { return image } - func primaryButtonColor(forState state: UIControlState) -> UIColor { + func primaryButtonColor(forState state: A0ControlState) -> UIColor { if state.contains(.highlighted) { return self.primaryColor.a0_darker(0.20) } @@ -153,7 +153,7 @@ public struct Style { return self.primaryColor } - func primaryButtonTintColor(forState state: UIControlState) -> UIColor { + func primaryButtonTintColor(forState state: A0ControlState) -> UIColor { if state.contains(.disabled) { return self.disabledTextColor } diff --git a/LockTests/LockViewControllerSpec.swift b/LockTests/LockViewControllerSpec.swift index 83886e3f7..1a1479e83 100644 --- a/LockTests/LockViewControllerSpec.swift +++ b/LockTests/LockViewControllerSpec.swift @@ -58,16 +58,16 @@ class LockViewControllerSpec: QuickSpec { var frame: CGRect! var duration: TimeInterval! - var curve: UIViewAnimationOptions! + var curve: A0ViewAnimationOptions! beforeEach { frame = CGRect(x: randomInteger(0, to: 200), y: randomInteger(0, to: 200), width: randomInteger(0, to: 200), height: randomInteger(0, to: 200)) duration = randomTimeInterval(0, to: 60) - curve = UIViewAnimationOptions() + curve = A0ViewAnimationOptions() } it("should ignore invalid notification") { - let notification = Notification(name: NSNotification.Name.UIKeyboardWillShow, object: nil) + let notification = Notification(name: UIResponder.responderKeyboardWillShowNotification, object: nil) controller.keyboardWasShown(notification) expect(controller.keyboard) == false } @@ -95,15 +95,15 @@ class LockViewControllerSpec: QuickSpec { context("hide") { var duration: TimeInterval! - var curve: UIViewAnimationOptions! + var curve: A0ViewAnimationOptions! beforeEach { duration = randomTimeInterval(0, to: 60) - curve = UIViewAnimationOptions() + curve = A0ViewAnimationOptions() } it("should ignore invalid notification") { - let notification = Notification(name: NSNotification.Name.UIKeyboardWillHide, object: nil) + let notification = Notification(name: UIResponder.responderKeyboardWillHideNotification, object: nil) controller.keyboardWasHidden(notification) expect(controller.keyboard) == false } @@ -142,26 +142,26 @@ func randomTimeInterval(_ from: Int, to: Int) -> TimeInterval { return Double(value) } -func willShowNotification(frame: CGRect, duration: TimeInterval, curve: UIViewAnimationOptions) -> Notification { +func willShowNotification(frame: CGRect, duration: TimeInterval, curve: A0ViewAnimationOptions) -> Notification { let notification = Notification( - name: NSNotification.Name.UIKeyboardWillShow, + name: UIResponder.responderKeyboardWillShowNotification, object: nil, userInfo: [ - UIKeyboardFrameEndUserInfoKey: NSValue(cgRect: frame), - UIKeyboardAnimationDurationUserInfoKey: NSNumber(value: duration as Double), - UIKeyboardAnimationCurveUserInfoKey: NSNumber(value: curve.rawValue as UInt), + UIResponder.responderKeyboardFrameEndUserInfoKey: NSValue(cgRect: frame), + UIResponder.responderKeyboardAnimationDurationUserInfoKey: NSNumber(value: duration as Double), + UIResponder.responderKeyboardAnimationCurveUserInfoKey: NSNumber(value: curve.rawValue as UInt), ] ) return notification } -func willHideNotification(duration: TimeInterval, curve: UIViewAnimationOptions) -> Notification { +func willHideNotification(duration: TimeInterval, curve: A0ViewAnimationOptions) -> Notification { let notification = Notification( - name: NSNotification.Name.UIKeyboardWillHide, + name: UIResponder.responderKeyboardWillHideNotification, object: nil, userInfo: [ - UIKeyboardAnimationDurationUserInfoKey: NSNumber(value: duration as Double), - UIKeyboardAnimationCurveUserInfoKey: NSNumber(value: curve.rawValue as UInt), + UIResponder.responderKeyboardAnimationDurationUserInfoKey: NSNumber(value: duration as Double), + UIResponder.responderKeyboardAnimationCurveUserInfoKey: NSNumber(value: curve.rawValue as UInt), ] ) return notification diff --git a/LockTests/Presenters/DatabasePresenterSpec.swift b/LockTests/Presenters/DatabasePresenterSpec.swift index 5eaba48fe..1df1f234d 100644 --- a/LockTests/Presenters/DatabasePresenterSpec.swift +++ b/LockTests/Presenters/DatabasePresenterSpec.swift @@ -828,7 +828,7 @@ class DatabasePresenterSpec: QuickSpec { it("should have actions") { let alert = navigator.presented as? UIAlertController expect(alert?.message).toEventually(beNil()) - expect(alert?.preferredStyle) == UIAlertControllerStyle.actionSheet + expect(alert?.preferredStyle) == A0AlertControllerStyle.actionSheet expect(alert?.actions).to(haveAction("Cancel", style: .cancel)) expect(alert?.actions).to(haveAction("Terms of Service", style: .default)) expect(alert?.actions).to(haveAction("Privacy Policy", style: .default)) @@ -956,7 +956,7 @@ class DatabasePresenterSpec: QuickSpec { } } -func haveAction(_ title: String, style: UIAlertActionStyle) -> Predicate<[UIAlertAction]> { +func haveAction(_ title: String, style: A0AlertActionStyle) -> Predicate<[UIAlertAction]> { return Predicate<[UIAlertAction]>.define("have action with title \(title) and style \(style)") { expression, failureMessage -> PredicateResult in if let actions = try expression.evaluate() { if actions.contains(where: { alert in diff --git a/LockTests/Utils/Mocks.swift b/LockTests/Utils/Mocks.swift index ea7b6b2f1..91dcf3d2e 100644 --- a/LockTests/Utils/Mocks.swift +++ b/LockTests/Utils/Mocks.swift @@ -446,7 +446,7 @@ class MockNativeAuthTransaction: NativeAuthTransaction { self.delayed = { _ in } } - func resume(_ url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool { + func resume(_ url: URL, options: [A0URLOptionsKey : Any]) -> Bool { self.delayed(self.onNativeAuth()) self.delayed = { _ in } return true diff --git a/LockUITests/LockUITests.swift b/LockUITests/LockUITests.swift index b2389fd66..46f885729 100644 --- a/LockUITests/LockUITests.swift +++ b/LockUITests/LockUITests.swift @@ -151,7 +151,13 @@ extension XCUIElement { } self.tap() + #if swift(>=4.0) + let deleteString = stringValue.map { _ in XCUIKeyboardKey.delete.rawValue }.joined(separator: "") + #elseif swift(>=3.2) + let deleteString = stringValue.map { _ in XCUIKeyboardKeyDelete }.joined(separator: "") + #else let deleteString = stringValue.characters.map { _ in XCUIKeyboardKeyDelete }.joined(separator: "") + #endif self.typeText(deleteString) self.typeText(text) } diff --git a/README.md b/README.md index 69113933c..1e519798e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![License](https://img.shields.io/cocoapods/l/Lock.svg?style=flat-square)](http://cocoadocs.org/docsets/Lock) [![Platform](https://img.shields.io/cocoapods/p/Lock.svg?style=flat-square)](http://cocoadocs.org/docsets/Lock) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat-square)](https://github.com/Carthage/Carthage) -![Swift 3.2](https://img.shields.io/badge/Swift-3.2-orange.svg?style=flat-square) +![Swift 4.2](https://img.shields.io/badge/Swift-4.2-orange.svg?style=flat-square) [Auth0](https://auth0.com) is an authentication broker that supports social identity providers as well as enterprise identity providers such as Active Directory, LDAP, Google Apps and Salesforce.