[Refactor] Move all code in AppDelegate to AppCoordinator

pull/5631/head
Hwee-Boon Yar 2 years ago
parent 456ceb587d
commit 673b9fa45d
  1. 73
      AlphaWallet/AppCoordinator.swift
  2. 65
      AlphaWallet/AppDelegate.swift
  3. 27
      AlphaWalletTests/Coordinators/AppCoordinatorTests.swift

@ -3,6 +3,7 @@
import Combine
import UIKit
import PromiseKit
import AlphaWalletAddress
import AlphaWalletCore
import AlphaWalletFoundation
import AlphaWalletTrackAPICalls
@ -135,7 +136,32 @@ class AppCoordinator: NSObject, Coordinator {
private lazy var sessionProvider = SessionsProvider(config: config, analytics: analytics)
private let securedStorage: SecuredPasswordStorage & SecuredStorage
init(window: UIWindow, analytics: AnalyticsServiceType, keystore: Keystore, walletAddressesStore: WalletAddressesStore, navigationController: UINavigationController = .withOverridenBarAppearence(), securedStorage: SecuredPasswordStorage & SecuredStorage) throws {
private let addressStorage: FileAddressStorage
//Unfortunate to have to have a factory method and not be able to use an initializer (because we can't override `init()` to throw)
static func create() throws -> AppCoordinator {
crashlytics.register(AlphaWallet.FirebaseCrashlyticsReporter.instance)
applyStyle()
let window = UIWindow(frame: UIScreen.main.bounds)
let analytics = AnalyticsService()
let walletAddressesStore: WalletAddressesStore = EtherKeystore.migratedWalletAddressesStore(userDefaults: .standardOrForTests)
let securedStorage: SecuredStorage & SecuredPasswordStorage = try KeychainStorage()
let keystore: Keystore = EtherKeystore(keychain: securedStorage, walletAddressesStore: walletAddressesStore, analytics: analytics)
let navigationController: UINavigationController = .withOverridenBarAppearence()
navigationController.view.backgroundColor = Colors.appWhite
let result = try AppCoordinator(window: window, analytics: analytics, keystore: keystore, walletAddressesStore: walletAddressesStore, navigationController: navigationController, securedStorage: securedStorage)
result.keystore.delegate = result
return result
}
init(window: UIWindow, analytics: AnalyticsServiceType, keystore: Keystore, walletAddressesStore: WalletAddressesStore, navigationController: UINavigationController, securedStorage: SecuredPasswordStorage & SecuredStorage) throws {
let addressStorage = FileAddressStorage()
register(addressStorage: addressStorage)
self.addressStorage = addressStorage
self.navigationController = navigationController
self.window = window
self.analytics = analytics
@ -166,7 +192,7 @@ class AppCoordinator: NSObject, Coordinator {
}.store(in: &cancelable)
}
func start() {
func start(launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) {
//Want to start as soon as possible
if AlphaWallet.Device.isSimulator {
TrackApiCalls.shared.start()
@ -197,6 +223,20 @@ class AppCoordinator: NSObject, Coordinator {
}
assetDefinitionStore.delegate = self
if let shortcutItem = launchOptions?[UIApplication.LaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem, shortcutItem.type == Constants.launchShortcutKey {
//Delay needed to work because app is launching..
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.launchUniversalScanner()
}
}
}
func applicationPerformActionFor(_ shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
if shortcutItem.type == Constants.launchShortcutKey {
launchUniversalScanner()
}
completionHandler(true)
}
func applicationWillResignActive() {
@ -216,6 +256,31 @@ class AppCoordinator: NSObject, Coordinator {
protectionCoordinator.applicationWillEnterForeground()
}
func applicationShouldAllowExtensionPointIdentifier(_ extensionPointIdentifier: UIApplication.ExtensionPointIdentifier) -> Bool {
if extensionPointIdentifier == .keyboard {
return false
}
return true
}
func applicationOpenUrl(_ url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
return handleUniversalLink(url: url, source: .customUrlScheme)
}
func applicationContinueUserActivity(_ userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
let hasHandledIntent = handleIntent(userActivity: userActivity)
if hasHandledIntent {
return true
}
var handled = false
if let url = userActivity.webpageURL {
handled = handleUniversalLink(url: url, source: .deeplink)
}
//TODO: if we handle other types of URLs, check if handled==false, then we pass the url to another handlers
return handled
}
private func setupSplashViewController(on navigationController: UINavigationController) {
navigationController.viewControllers = [
SplashViewController()
@ -347,7 +412,7 @@ class AppCoordinator: NSObject, Coordinator {
}
/// Return true if handled
@discardableResult func handleUniversalLink(url: URL, source: UrlSource) -> Bool {
@discardableResult private func handleUniversalLink(url: URL, source: UrlSource) -> Bool {
createInitialWalletIfMissing()
showActiveWalletIfNeeded()
@ -375,7 +440,7 @@ class AppCoordinator: NSObject, Coordinator {
activeWalletCoordinator?.didPressOpenWebPage(url, in: viewController)
}
func handleIntent(userActivity: NSUserActivity) -> Bool {
private func handleIntent(userActivity: NSUserActivity) -> Bool {
if let type = userActivity.userInfo?[WalletQrCodeDonation.userInfoType.key] as? String, type == WalletQrCodeDonation.userInfoType.value {
analytics.log(navigation: Analytics.Navigation.openShortcut, properties: [
Analytics.Properties.type.rawValue: Analytics.ShortcutType.walletQrCode.rawValue

@ -1,53 +1,24 @@
// Copyright SIX DAY LLC. All rights reserved.
// Copyright © 2022 Stormbird PTE. LTD.
import UIKit
import AlphaWalletAddress
import AlphaWalletFoundation
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
private var appCoordinator: AppCoordinator!
private let addressStorage = FileAddressStorage()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
crashlytics.register(AlphaWallet.FirebaseCrashlyticsReporter.instance)
applyStyle()
window = UIWindow(frame: UIScreen.main.bounds)
do {
register(addressStorage: addressStorage)
let analytics = AnalyticsService()
let walletAddressesStore: WalletAddressesStore = EtherKeystore.migratedWalletAddressesStore(userDefaults: .standardOrForTests)
let securedStorage: SecuredStorage & SecuredPasswordStorage = try KeychainStorage()
var keystore: Keystore = EtherKeystore(keychain: securedStorage, walletAddressesStore: walletAddressesStore, analytics: analytics)
let navigationController: UINavigationController = .withOverridenBarAppearence()
navigationController.view.backgroundColor = Colors.appWhite
appCoordinator = try AppCoordinator(window: window!, analytics: analytics, keystore: keystore, walletAddressesStore: walletAddressesStore, navigationController: navigationController, securedStorage: securedStorage)
keystore.delegate = appCoordinator
appCoordinator.start()
if let shortcutItem = launchOptions?[UIApplication.LaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem, shortcutItem.type == Constants.launchShortcutKey {
//Delay needed to work because app is launching..
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.appCoordinator.launchUniversalScanner()
}
}
appCoordinator = try AppCoordinator.create()
appCoordinator.start(launchOptions: launchOptions)
} catch {
//no-op
}
return true
}
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
if shortcutItem.type == Constants.launchShortcutKey {
appCoordinator.launchUniversalScanner()
}
completionHandler(true)
appCoordinator.applicationPerformActionFor(shortcutItem, completionHandler: completionHandler)
}
func applicationWillResignActive(_ application: UIApplication) {
@ -67,37 +38,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}
func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplication.ExtensionPointIdentifier) -> Bool {
if extensionPointIdentifier == .keyboard {
return false
}
return true
return appCoordinator.applicationShouldAllowExtensionPointIdentifier(extensionPointIdentifier)
}
// URI scheme links and AirDrop
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
return handleUniversalLink(url: url, source: .customUrlScheme)
return appCoordinator.applicationOpenUrl(url, options: options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
let hasHandledIntent = appCoordinator.handleIntent(userActivity: userActivity)
if hasHandledIntent {
return true
}
var handled = false
if let url = userActivity.webpageURL {
handled = handleUniversalLink(url: url, source: .deeplink)
}
//TODO: if we handle other types of URLs, check if handled==false, then we pass the url to another handlers
return handled
return appCoordinator.applicationContinueUserActivity(userActivity, restorationHandler: restorationHandler)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
//no op
}
private func handleUniversalLink(url: URL, source: UrlSource) -> Bool {
let handled = appCoordinator.handleUniversalLink(url: url, source: source)
return handled
}
}

@ -19,7 +19,10 @@ class AppCoordinatorTests: XCTestCase {
window: UIWindow(),
analytics: FakeAnalyticsService(),
keystore: FakeEtherKeystore(),
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]), securedStorage: KeychainStorage.make())
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]),
navigationController: FakeNavigationController(),
securedStorage: KeychainStorage.make()
)
XCTAssertTrue(coordinator.navigationController.viewControllers[0].isSplashScreen)
coordinator.start()
@ -39,7 +42,8 @@ class AppCoordinatorTests: XCTestCase {
recentlyUsedWallet: .make()
),
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]),
navigationController: FakeNavigationController(), securedStorage: KeychainStorage.make()
navigationController: FakeNavigationController(),
securedStorage: KeychainStorage.make()
)
coordinator.start()
@ -62,7 +66,9 @@ class AppCoordinatorTests: XCTestCase {
wallets: [.make()],
recentlyUsedWallet: .make()
),
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]), securedStorage: KeychainStorage.make()
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]),
navigationController: FakeNavigationController(),
securedStorage: KeychainStorage.make()
)
coordinator.start()
coordinator.reset()
@ -83,7 +89,8 @@ class AppCoordinatorTests: XCTestCase {
recentlyUsedWallet: .make()
),
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]),
navigationController: FakeNavigationController(), securedStorage: KeychainStorage.make()
navigationController: FakeNavigationController(),
securedStorage: KeychainStorage.make()
)
coordinator.start()
coordinator.showInitialWalletCoordinator()
@ -104,7 +111,8 @@ class AppCoordinatorTests: XCTestCase {
recentlyUsedWallet: .make()
),
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]),
navigationController: FakeNavigationController(), securedStorage: KeychainStorage.make()
navigationController: FakeNavigationController(),
securedStorage: KeychainStorage.make()
)
coordinator.start()
@ -127,7 +135,9 @@ class AppCoordinatorTests: XCTestCase {
wallets: [.make()],
recentlyUsedWallet: .make()
),
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]), securedStorage: KeychainStorage.make()
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]),
navigationController: FakeNavigationController(),
securedStorage: KeychainStorage.make()
)
coordinator.start()
@ -144,7 +154,10 @@ class AppCoordinatorTests: XCTestCase {
window: .init(),
analytics: FakeAnalyticsService(),
keystore: FakeEtherKeystore(),
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]), securedStorage: KeychainStorage.make())
walletAddressesStore: fakeWalletAddressesStore(wallets: [.make()]),
navigationController: FakeNavigationController(),
securedStorage: KeychainStorage.make()
)
coordinator.start()

Loading…
Cancel
Save