From fe0d586a4051cda495256b83e7a7faca7aded60b Mon Sep 17 00:00:00 2001 From: Pavel Anokhov Date: Mon, 19 Nov 2018 15:57:55 +0300 Subject: [PATCH] Improved EthWalletService initialisation. Fixed dependency cycle. --- Adamant/Services/AdamantAccountService.swift | 51 ++++++++++++++++++- Adamant/SwinjectDependencies.swift | 14 ++--- .../Wallets/Ethereum/EthWalletService.swift | 26 ++++++---- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/Adamant/Services/AdamantAccountService.swift b/Adamant/Services/AdamantAccountService.swift index c6704d711..ca8b1581e 100644 --- a/Adamant/Services/AdamantAccountService.swift +++ b/Adamant/Services/AdamantAccountService.swift @@ -14,7 +14,8 @@ class AdamantAccountService: AccountService { var apiService: ApiService! var adamantCore: AdamantCore! - var notificationsService: NotificationsService! + weak var notificationsService: NotificationsService! + var dialogService: DialogService! var securedStore: SecuredStore! { didSet { securedStoreSemaphore.wait() @@ -86,9 +87,55 @@ class AdamantAccountService: AccountService { // MARK: Wallets var wallets: [WalletService] = [ AdmWalletService(), - try! EthWalletService(apiUrl: AdamantResources.ethServers.first!), // TODO: Move to background thread + EthWalletService(), // TODO: Move to background thread // LskWalletService() ] + + init() { + guard let ethWallet = wallets[1] as? EthWalletService else { + fatalError("Failed to get EthWalletService") + } + + ethWallet.initiateNetwork(apiUrl: AdamantResources.ethServers.first!) { result in + switch result { + case .success: + break + + case .failure(let error): + switch error { + case .networkError: + NotificationCenter.default.addObserver(forName: Notification.Name.AdamantReachabilityMonitor.reachabilityChanged, object: nil, queue: nil) { notification in + guard let connection = notification.userInfo?[AdamantUserInfoKey.ReachabilityMonitor.connection] as? AdamantConnection else { + return + } + + switch connection { + case .none: + break + + case .wifi, .cellular: + ethWallet.initiateNetwork(apiUrl: AdamantResources.ethServers.first!) { result in + switch result { + case .success: + NotificationCenter.default.removeObserver(self, name: Notification.Name.AdamantReachabilityMonitor.reachabilityChanged, object: nil) + + case .failure(let error): + self.dialogService.showRichError(error: error) + } + } + } + } + + case .notLogged, .transactionNotFound, .notEnoughtMoney, .accountNotFound, .walletNotInitiated, .invalidAmount: + break + + case .remoteServiceError, .apiError, .internalError: + self.dialogService.showRichError(error: error) + self.wallets.remove(at: 1) + } + } + } + } } // MARK: - Saved data diff --git a/Adamant/SwinjectDependencies.swift b/Adamant/SwinjectDependencies.swift index 516b5c073..04672a625 100644 --- a/Adamant/SwinjectDependencies.swift +++ b/Adamant/SwinjectDependencies.swift @@ -14,10 +14,7 @@ extension Container { func registerAdamantServices() { // MARK: - Standalone services // MARK: AdamantCore - self.register(AdamantCore.self) { _ in - let core = NativeAdamantCore() - return core - }.inObjectScope(.container) + self.register(AdamantCore.self) { _ in NativeAdamantCore() }.inObjectScope(.container) // MARK: Router self.register(Router.self) { _ in @@ -81,9 +78,12 @@ extension Container { service.apiService = r.resolve(ApiService.self)! service.adamantCore = r.resolve(AdamantCore.self)! service.securedStore = r.resolve(SecuredStore.self)! - service.notificationsService = r.resolve(NotificationsService.self)! - return service - }.inObjectScope(.container).initCompleted { (r, service) in + service.dialogService = r.resolve(DialogService.self)! + return service + }.inObjectScope(.container).initCompleted { (r, c) in + let service = c as! AdamantAccountService + service.notificationsService = r.resolve(NotificationsService.self)! + for case let wallet as SwinjectDependentService in service.wallets { wallet.injectDependencies(from: self) } diff --git a/Adamant/Wallets/Ethereum/EthWalletService.swift b/Adamant/Wallets/Ethereum/EthWalletService.swift index 1fb2f7d6c..af3c18d6f 100644 --- a/Adamant/Wallets/Ethereum/EthWalletService.swift +++ b/Adamant/Wallets/Ethereum/EthWalletService.swift @@ -78,8 +78,8 @@ class EthWalletService: WalletService { private static let transactionsListApiSubpath = "ethtxs" - let web3: web3 - private let baseUrl: String + private(set) var web3: web3! + private var baseUrl: String! let defaultDispatchQueue = DispatchQueue(label: "im.adamant.ethWalletService", qos: .utility, attributes: [.concurrent]) private (set) var enabled = true @@ -121,15 +121,7 @@ class EthWalletService: WalletService { private var balanceObserver: NSObjectProtocol? = nil // MARK: - Logic - init(apiUrl: String) throws { - // Init network - guard let url = URL(string: apiUrl), let web3 = Web3.new(url) else { - throw WalletServiceError.networkError - } - - self.web3 = web3 - self.baseUrl = EthWalletService.buildBaseUrl(for: web3.provider.network) - + init() { // Notifications NotificationCenter.default.addObserver(forName: Notification.Name.AdamantAccountService.userLoggedIn, object: nil, queue: nil) { [weak self] _ in self?.update() @@ -148,6 +140,18 @@ class EthWalletService: WalletService { } } } + + func initiateNetwork(apiUrl: String, completion: @escaping (WalletServiceSimpleResult) -> Void) { + DispatchQueue.global(qos: .userInitiated).async { + guard let url = URL(string: apiUrl), let web3 = Web3.new(url) else { + completion(.failure(error: WalletServiceError.networkError)) + return + } + + self.web3 = web3 + self.baseUrl = EthWalletService.buildBaseUrl(for: web3.provider.network) + } + } func update() { guard let wallet = ethWallet else {