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 {