Merge pull request #4067 from oa-s/#4066

Delay subscribing for tokens updates for events creating #4066
pull/4073/head
Crypto Pank 3 years ago committed by GitHub
commit 5bb184d164
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      AlphaWallet/InCoordinator.swift
  2. 30
      AlphaWallet/TokenScriptClient/Coordinators/EventSourceCoordinator.swift
  3. 19
      AlphaWallet/TokenScriptClient/Coordinators/EventSourceCoordinatorForActivities.swift
  4. 8
      AlphaWallet/Tokens/Coordinators/TokensCoordinator.swift

@ -32,7 +32,10 @@ class InCoordinator: NSObject, Coordinator {
private let queue: DispatchQueue = DispatchQueue(label: "com.Background.updateQueue", qos: .userInitiated)
lazy private var eventsDataStore: NonActivityEventsDataStore = NonActivityMultiChainEventsDataStore(realm: realm)
lazy private var eventsActivityDataStore: EventsActivityDataStoreProtocol = EventsActivityDataStore(realm: realm)
private var eventSourceCoordinatorForActivities: EventSourceCoordinatorForActivities?
private lazy var eventSourceCoordinatorForActivities: EventSourceCoordinatorForActivities? = {
guard Features.isActivityEnabled else { return nil }
return EventSourceCoordinatorForActivities(wallet: wallet, config: config, tokensDataStore: tokensDataStore, assetDefinitionStore: assetDefinitionStore, eventsDataStore: eventsActivityDataStore)
}()
private let coinTickersFetcher: CoinTickersFetcherType
lazy var tokensDataStore: TokensDataStore = {
@ -150,7 +153,6 @@ class InCoordinator: NSObject, Coordinator {
//Disabled for now. Refer to function's comment
//self.assetDefinitionStore.enableFetchXMLForContractInPasteboard()
super.init()
}
deinit {
@ -214,9 +216,7 @@ class InCoordinator: NSObject, Coordinator {
guard let token = tokensDataStore.token(forContract: contract, server: server) else { return }
eventsDataStore.deleteEvents(forTokenContract: contract)
let _ = eventSourceCoordinator.fetchEventsByTokenId(forToken: token)
if Features.isActivityEnabled {
let _ = eventSourceCoordinatorForActivities?.fetchEvents(forToken: token)
}
let _ = eventSourceCoordinatorForActivities?.fetchEvents(forToken: token)
}
private func oneTimeCreationOfOneDatabaseToHoldAllChains() {
@ -263,23 +263,6 @@ class InCoordinator: NSObject, Coordinator {
setUpEventSourceCoordinatorForActivities()
}
private func fetchEthereumEvents() {
eventSourceCoordinator.fetchEthereumEvents()
if Features.isActivityEnabled {
eventSourceCoordinatorForActivities?.fetchEthereumEvents()
}
}
private func pollEthereumEvents(tokensDataStore: TokensDataStore) {
tokensDataStore
.enabledTokenObjectsChangesetPublisher(forServers: config.enabledServers)
.subscribe(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.fetchEthereumEvents()
}.store(in: &cancellable)
}
//Internal for test purposes
/*private*/ func showTabBar(for account: Wallet, animated: Bool) {
keystore.recentlyUsedWallet = account
@ -349,7 +332,6 @@ class InCoordinator: NSObject, Coordinator {
private func createTokensCoordinator(promptBackupCoordinator: PromptBackupCoordinator, activitiesService: ActivitiesServiceType) -> TokensCoordinator {
promptBackupCoordinator.listenToNativeCryptoCurrencyBalance(withWalletSessions: sessionsSubject.value)
pollEthereumEvents(tokensDataStore: tokensDataStore)
let coordinator = TokensCoordinator(
sessions: sessionsSubject.value,
@ -369,6 +351,7 @@ class InCoordinator: NSObject, Coordinator {
coordinator.rootViewController.tabBarItem = UITabBarController.Tabs.tokens.tabBarItem
coordinator.delegate = self
coordinator.start()
addCoordinator(coordinator)
return coordinator
}
@ -999,6 +982,11 @@ extension InCoordinator: WhereAreMyTokensCoordinatorDelegate {
extension InCoordinator: TokensCoordinatorDelegate {
func viewWillAppearOnce(in coordinator: TokensCoordinator) {
eventSourceCoordinator.start()
eventSourceCoordinatorForActivities?.start()
}
func whereAreMyTokensSelected(in coordinator: TokensCoordinator) {
let coordinator = WhereAreMyTokensCoordinator(navigationController: navigationController)
coordinator.delegate = self

@ -4,6 +4,7 @@ import Foundation
import BigInt
import PromiseKit
import web3swift
import Combine
extension PromiseKit.Result {
var optionalValue: T? {
@ -17,12 +18,13 @@ extension PromiseKit.Result {
}
protocol EventSourceCoordinatorType: class {
func fetchEthereumEvents()
func start()
@discardableResult func fetchEventsByTokenId(forToken token: TokenObject) -> [Promise<Void>]
}
//TODO: Create XMLHandler store and pass it everwhere we use it
//TODO: Rename this generic name to reflect that it's for event instances, not for event activity
class EventSourceCoordinator: EventSourceCoordinatorType {
class EventSourceCoordinator: NSObject, EventSourceCoordinatorType {
private var wallet: Wallet
private let tokensDataStore: TokensDataStore
private let assetDefinitionStore: AssetDefinitionStore
@ -31,6 +33,7 @@ class EventSourceCoordinator: EventSourceCoordinatorType {
private var rateLimitedUpdater: RateLimiter?
private let queue = DispatchQueue(label: "com.eventSourceCoordinator.updateQueue")
private let enabledServers: [RPCServer]
private var cancellable = Set<AnyCancellable>()
init(wallet: Wallet, tokensDataStore: TokensDataStore, assetDefinitionStore: AssetDefinitionStore, eventsDataStore: NonActivityEventsDataStore, config: Config) {
self.wallet = wallet
@ -38,6 +41,18 @@ class EventSourceCoordinator: EventSourceCoordinatorType {
self.assetDefinitionStore = assetDefinitionStore
self.eventsDataStore = eventsDataStore
self.enabledServers = config.enabledServers
super.init()
}
func start() {
tokensDataStore
.enabledTokenObjectsChangesetPublisher(forServers: enabledServers)
.subscribe(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.fetchEthereumEvents()
}.store(in: &cancellable)
}
func fetchEventsByTokenId(forToken token: TokenObject) -> [Promise<Void>] {
@ -84,15 +99,10 @@ class EventSourceCoordinator: EventSourceCoordinatorType {
seal.fulfill(values)
}
}
//NOTE: calling .fetchEventsByTokenId shoul be performed on .main queue
}
}.then(on: .main, { tokens -> Promise<Void> in
return Promise { seal in
let promises = tokens.map { self.fetchEventsByTokenId(forToken: $0) }.flatMap { $0 }
when(resolved: promises).done { _ in
seal.fulfill(())
}
}
let promises = tokens.map { self.fetchEventsByTokenId(forToken: $0) }.flatMap { $0 }
return when(resolved: promises).asVoid()
}).done(on: queue, { _ in
self.isFetching = false
}).cauterize()

@ -4,11 +4,11 @@ import Foundation
import BigInt
import PromiseKit
import web3swift
import Combine
protocol EventSourceCoordinatorForActivitiesType: AnyObject {
func fetchEvents(forToken token: TokenObject) -> [Promise<Void>]
func fetchEvents(contract: AlphaWallet.Address, tokenType: TokenType, rpcServer: RPCServer) -> [Promise<Void>]
func fetchEthereumEvents()
func fetchEvents(forToken token: TokenObject) -> [Promise<Void>]
func start()
}
class EventSourceCoordinatorForActivities: EventSourceCoordinatorForActivitiesType {
@ -21,6 +21,7 @@ class EventSourceCoordinatorForActivities: EventSourceCoordinatorForActivitiesTy
private var rateLimitedUpdater: RateLimiter?
private let queue = DispatchQueue(label: "com.EventSourceCoordinatorForActivities.updateQueue")
private let enabledServers: [RPCServer]
private var cancellable = Set<AnyCancellable>()
init(wallet: Wallet, config: Config, tokensDataStore: TokensDataStore, assetDefinitionStore: AssetDefinitionStore, eventsDataStore: EventsActivityDataStoreProtocol) {
self.wallet = wallet
@ -31,6 +32,16 @@ class EventSourceCoordinatorForActivities: EventSourceCoordinatorForActivitiesTy
self.enabledServers = Config().enabledServers
}
func start() {
tokensDataStore
.enabledTokenObjectsChangesetPublisher(forServers: config.enabledServers)
.subscribe(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let strongSelf = self else { return }
strongSelf.fetchEthereumEvents()
}.store(in: &cancellable)
}
func fetchEvents(forToken token: TokenObject) -> [Promise<Void>] {
let xmlHandler = XMLHandler(contract: token.contractAddress, tokenType: token.type, assetDefinitionStore: assetDefinitionStore)
guard xmlHandler.hasAssetDefinition else { return [] }
@ -39,7 +50,7 @@ class EventSourceCoordinatorForActivities: EventSourceCoordinatorForActivitiesTy
}
}
func fetchEvents(contract: AlphaWallet.Address, tokenType: TokenType, rpcServer: RPCServer) -> [Promise<Void>] {
private func fetchEvents(contract: AlphaWallet.Address, tokenType: TokenType, rpcServer: RPCServer) -> [Promise<Void>] {
let xmlHandler = XMLHandler(contract: contract, tokenType: tokenType, assetDefinitionStore: assetDefinitionStore)
guard xmlHandler.hasAssetDefinition else { return [] }
return xmlHandler.activityCards.compactMap {

@ -18,6 +18,7 @@ protocol TokensCoordinatorDelegate: CanOpenURL, SendTransactionDelegate {
func whereAreMyTokensSelected(in coordinator: TokensCoordinator)
func didSelectAccount(account: Wallet, in coordinator: TokensCoordinator)
func viewWillAppearOnce(in coordinator: TokensCoordinator)
}
private struct NoContractDetailsDetected: Error {
@ -101,7 +102,7 @@ class TokensCoordinator: Coordinator {
private let tokensDataStore: TokensDataStore
private let tokensAutoDetectionQueue: DispatchQueue = DispatchQueue(label: "com.TokensAutoDetection.updateQueue")
private var viewWillAppearHandled = false
init(
navigationController: UINavigationController = .withOverridenBarAppearence(),
sessions: ServerDictionary<WalletSession>,
@ -264,6 +265,11 @@ extension TokensCoordinator: TokensViewControllerDelegate {
func viewWillAppear(in viewController: UIViewController) {
getWalletName()
getWalletBlockie()
guard !viewWillAppearHandled else { return }
viewWillAppearHandled = true
delegate?.viewWillAppearOnce(in: self)
}
private func makeMoreAlertSheet(sender: UIBarButtonItem) -> UIAlertController {

Loading…
Cancel
Save