Improve protection window (#273)

* Improve protection window

Move splash screen into separate window and lock screen. In this case you won't see transactions screen and splash screen always works if you even have face id disabled.

* Revert provision settings

* Update of the unit tests.
pull/2/head
Michael Scoff 7 years ago committed by Oleg Gordiichuk
parent b39c792068
commit 1ccb96207a
  1. 20
      Trust.xcodeproj/project.pbxproj
  2. 5
      Trust/AppDelegate.swift
  3. 6
      Trust/Lock/Coordinators/LockEnterPasscodeCoordinator.swift
  4. 26
      Trust/Protection/Coordinators/ProtectionCoordinator.swift
  5. 14
      Trust/Protection/Coordinators/SplashCoordinator.swift
  6. 23
      Trust/Protection/ViewControllers/SplashViewController.swift
  7. 11
      TrustTests/Coordinators/LockEnterPasscodeCoordinatorTest.swift
  8. 3
      TrustTests/Coordinators/SplashCoordinatorTests.swift

@ -312,6 +312,7 @@
77872D292025116E0032D687 /* EnterPasswordCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77872D282025116E0032D687 /* EnterPasswordCoordinator.swift */; };
77872D2D202514AD0032D687 /* EnterPasswordCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77872D2C202514AD0032D687 /* EnterPasswordCoordinatorTests.swift */; };
77872D322027AA4A0032D687 /* SliderTextFieldRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77872D312027AA4A0032D687 /* SliderTextFieldRow.swift */; };
77872D302026DC570032D687 /* SplashViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77872D2F2026DC570032D687 /* SplashViewController.swift */; };
778EAF7D1FF10AF400C8E2AB /* SettingsCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 778EAF7C1FF10AF400C8E2AB /* SettingsCoordinatorTests.swift */; };
77B3BF352017D0D000EEC15A /* MarketplaceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77B3BF342017D0D000EEC15A /* MarketplaceViewModel.swift */; };
77B3BF3C201908ED00EEC15A /* ConfirmCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77B3BF3B201908ED00EEC15A /* ConfirmCoordinator.swift */; };
@ -664,6 +665,7 @@
77872D282025116E0032D687 /* EnterPasswordCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterPasswordCoordinator.swift; sourceTree = "<group>"; };
77872D2C202514AD0032D687 /* EnterPasswordCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnterPasswordCoordinatorTests.swift; sourceTree = "<group>"; };
77872D312027AA4A0032D687 /* SliderTextFieldRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SliderTextFieldRow.swift; sourceTree = "<group>"; };
77872D2F2026DC570032D687 /* SplashViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashViewController.swift; sourceTree = "<group>"; };
778EAF7C1FF10AF400C8E2AB /* SettingsCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCoordinatorTests.swift; sourceTree = "<group>"; };
77B3BF342017D0D000EEC15A /* MarketplaceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketplaceViewModel.swift; sourceTree = "<group>"; };
77B3BF3B201908ED00EEC15A /* ConfirmCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmCoordinator.swift; sourceTree = "<group>"; };
@ -1783,6 +1785,7 @@
732086B2201506AA0047F605 /* Protection */ = {
isa = PBXGroup;
children = (
77872D2E2026DC4E0032D687 /* ViewControllers */,
732086B3201507220047F605 /* Coordinators */,
732086B5201507220047F605 /* Views */,
);
@ -1896,6 +1899,14 @@
path = Coordinators;
sourceTree = "<group>";
};
77872D2E2026DC4E0032D687 /* ViewControllers */ = {
isa = PBXGroup;
children = (
77872D2F2026DC570032D687 /* SplashViewController.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
};
778EAF7B1FF10AE000C8E2AB /* Coordinators */ = {
isa = PBXGroup;
children = (
@ -2523,6 +2534,7 @@
29BE3FD01F7071A200F6BFC2 /* UIColor.swift in Sources */,
73ACEEFB20163C94003DD71D /* LockView.swift in Sources */,
771AA964200D5EDB00D25403 /* WordCollectionViewCell.swift in Sources */,
77872D302026DC570032D687 /* SplashViewController.swift in Sources */,
2996F1481F6C9AE5005C33AE /* SettingsCoordinator.swift in Sources */,
29C80D4D1FB5202C0037B1E0 /* BalanceBaseViewModel.swift in Sources */,
29E14FD11F7F457D00185568 /* TransactionsStorage.swift in Sources */,
@ -2880,7 +2892,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Trust/Trust.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 141;
DEVELOPMENT_TEAM = 9873B38DWV;
@ -2890,8 +2902,8 @@
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" -D DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = com.sixdays.trust;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "09b158f8-8b12-4ed4-8489-9514fc5e69aa";
PROVISIONING_PROFILE_SPECIFIER = "match Development com.sixdays.trust";
PROVISIONING_PROFILE = "7edbff9c-3e3f-4ba3-b84f-19ac095b8e95";
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.sixdays.trust";
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 armv7 armv7s";
VERSIONING_SYSTEM = "apple-generic";
@ -2913,7 +2925,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.sixdays.trust;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "36d4af79-beee-452d-a1eb-76d840b41c13";
PROVISIONING_PROFILE = "7edbff9c-3e3f-4ba3-b84f-19ac095b8e95";
PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.sixdays.trust";
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 armv7 armv7s";

@ -20,6 +20,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele
} catch {
print("EtherKeystore init issue.")
}
protectionCoordinator.didFinishLaunchingWithOptions()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
@ -32,6 +33,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDele
Lokalise.shared.checkForUpdates { _, _ in }
protectionCoordinator.applicationDidBecomeActive()
}
func applicationDidEnterBackground(_ application: UIApplication) {
protectionCoordinator.applicationDidEnterBackground()
}
func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplicationExtensionPointIdentifier) -> Bool {
if extensionPointIdentifier == UIApplicationExtensionPointIdentifier.keyboard {
return false

@ -5,14 +5,14 @@ import UIKit
class LockEnterPasscodeCoordinator: Coordinator {
var coordinators: [Coordinator] = []
var protectionWasShown = false
private let window: UIWindow
private let window: UIWindow = UIWindow()
private let model: LockEnterPasscodeViewModel
private let lock: LockInterface
private lazy var lockEnterPasscodeViewController: LockEnterPasscodeViewController = {
return LockEnterPasscodeViewController(model: model)
}()
init(window: UIWindow, model: LockEnterPasscodeViewModel, lock: LockInterface = Lock()) {
self.window = window
init(model: LockEnterPasscodeViewModel, lock: LockInterface = Lock()) {
self.window.windowLevel = UIWindowLevelStatusBar + 1.0
self.model = model
self.lock = lock
lockEnterPasscodeViewController.unlockWithResult = { [weak self] (state, bioUnlock) in

@ -8,27 +8,35 @@ class ProtectionCoordinator: Coordinator {
return SplashCoordinator(window: self.protectionWindow)
}()
lazy var lockEnterPasscodeCoordinator: LockEnterPasscodeCoordinator = {
return LockEnterPasscodeCoordinator(window: self.protectionWindow, model: LockEnterPasscodeViewModel())
return LockEnterPasscodeCoordinator(model: LockEnterPasscodeViewModel())
}()
let protectionWindow = UIWindow()
init() {
protectionWindow.windowLevel = UIWindowLevelStatusBar + 1.0
protectionWindow.windowLevel = UIWindowLevelStatusBar + 2.0
}
func applicationWillResignActive() {
//We should show spalsh screen when protection is on. And app is susepndet.
guard Lock().isPasscodeSet() else {
return
func didFinishLaunchingWithOptions() {
splashCoordinator.start()
lockEnterPasscodeCoordinator.start()
}
func applicationWillResignActive() {
splashCoordinator.start()
}
func applicationDidBecomeActive() {
//We should dismiss spalsh screen when app become active.
splashCoordinator.stop()
//We track protectionWasShown becouse of the TouchId that will trigger applicationDidBecomeActive method after valdiation.
//We track protectionWasShown because of the Touch ID that will trigger applicationDidBecomeActive method after valdiation.
if !lockEnterPasscodeCoordinator.protectionWasShown {
lockEnterPasscodeCoordinator.start()
} else {
lockEnterPasscodeCoordinator.protectionWasShown = false
}
//We should dismiss spalsh screen when app become active.
splashCoordinator.stop()
}
func applicationDidEnterBackground() {
splashCoordinator.start()
}
}

@ -5,24 +5,14 @@ import UIKit
class SplashCoordinator: Coordinator {
var coordinators: [Coordinator] = []
private let window: UIWindow
private var splashView: SplashView
init(window: UIWindow) {
self.window = window
self.splashView = SplashView()
}
func start() {
window.rootViewController = SplashViewController()
window.isHidden = false
window.addSubview(splashView)
window.bringSubview(toFront: splashView)
splashView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
splashView.topAnchor.constraint(equalTo: window.topAnchor),
splashView.leadingAnchor.constraint(equalTo: window.leadingAnchor),
splashView.bottomAnchor.constraint(equalTo: window.bottomAnchor),
splashView.trailingAnchor.constraint(equalTo: window.trailingAnchor),
])
}
func stop() {
splashView.removeFromSuperview()
window.isHidden = true
}
}

@ -0,0 +1,23 @@
// Copyright SIX DAY LLC. All rights reserved.
import Foundation
import UIKit
class SplashViewController: UIViewController {
private var splashView = SplashView()
init() {
super.init(nibName: nil, bundle: nil)
splashView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(splashView)
NSLayoutConstraint.activate([
splashView.topAnchor.constraint(equalTo: view.topAnchor),
splashView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
splashView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
splashView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

@ -5,32 +5,27 @@ import XCTest
class LockEnterPasscodeCoordinatorTest: XCTestCase {
func testStart() {
let window = UIWindow()
let viewModel = LockEnterPasscodeViewModel()
let fakeLock = FakeLockProtocol()
let coordinator = LockEnterPasscodeCoordinator(window: window, model: viewModel, lock: fakeLock)
let coordinator = LockEnterPasscodeCoordinator(model: viewModel, lock: fakeLock)
XCTAssertFalse(coordinator.protectionWasShown)
coordinator.start()
XCTAssertTrue(coordinator.protectionWasShown)
XCTAssertTrue(window.rootViewController is LockEnterPasscodeViewController)
}
func testStop() {
let window = UIWindow()
let viewModel = LockEnterPasscodeViewModel()
let fakeLock = FakeLockProtocol()
let coordinator = LockEnterPasscodeCoordinator(window: window, model: viewModel, lock: fakeLock)
let coordinator = LockEnterPasscodeCoordinator(model: viewModel, lock: fakeLock)
XCTAssertFalse(coordinator.protectionWasShown)
coordinator.start()
XCTAssertTrue(coordinator.protectionWasShown)
coordinator.stop()
XCTAssertTrue(window.isHidden)
}
func testDisableLock() {
let window = UIWindow()
let viewModel = LockEnterPasscodeViewModel()
let fakeLock = FakeLockProtocol()
fakeLock.passcodeSet = false
let coordinator = LockEnterPasscodeCoordinator(window: window, model: viewModel, lock: fakeLock)
let coordinator = LockEnterPasscodeCoordinator(model: viewModel, lock: fakeLock)
XCTAssertFalse(coordinator.protectionWasShown)
coordinator.start()
XCTAssertFalse(coordinator.protectionWasShown)

@ -10,13 +10,12 @@ class SplashCoordinatorTests: XCTestCase {
let coordinator = SplashCoordinator(window: window)
coordinator.start()
XCTAssertFalse(window.isHidden)
XCTAssertNotNil(window.subviews.first)
}
func testStop() {
let window = UIWindow()
let coordinator = SplashCoordinator(window: window)
coordinator.start()
coordinator.stop()
XCTAssertNil(window.subviews.first)
XCTAssertTrue(window.isHidden)
}
}

Loading…
Cancel
Save