@@ -3,14 +3,15 @@ import SSFModels
33import RobinHood
44
55protocol PricesServiceProtocol {
6- func startPricesObserving ( for chainAssets : [ ChainAsset ] , currencies : [ Currency ] )
6+ func setup ( )
77 func updatePrices( )
88}
99
1010final class PricesService : PricesServiceProtocol {
1111 static let shared : PricesServiceProtocol = PricesService . create ( )
1212 private let priceLocalSubscriber = PriceLocalStorageSubscriberImpl . shared
1313 private let chainRepository : AnyDataProviderRepository < ChainModel >
14+ private let walletRepository : AnyDataProviderRepository < MetaAccountModel >
1415 private let operationQueue : OperationQueue
1516 private let logger : Logger
1617 private var pricesProvider : AnySingleValueProvider < [ PriceData ] > ?
@@ -21,39 +22,34 @@ final class PricesService: PricesServiceProtocol {
2122
2223 private init (
2324 chainRepository: AnyDataProviderRepository < ChainModel > ,
25+ walletRepository: AnyDataProviderRepository < MetaAccountModel > ,
2426 operationQueue: OperationQueue ,
2527 logger: Logger ,
2628 eventCenter: EventCenter
2729 ) {
2830 self . chainRepository = chainRepository
31+ self . walletRepository = walletRepository
2932 self . operationQueue = operationQueue
3033 self . logger = logger
3134 self . eventCenter = eventCenter
3235 }
3336
34- func startPricesObserving( for chainAssets: [ SSFModels . ChainAsset ] , currencies: [ SSFModels . Currency ] ) {
35- let oldAssets = self . chainAssets
36- let uniqueAssets = chainAssets. filter { newAsset in
37- !oldAssets. contains ( newAsset)
38- }
39- let oldCurrencies = self . currencies
40- let uniqueCurencies = currencies. filter { newCurrency in
41- !oldCurrencies. contains ( newCurrency)
42- }
43- let timeFromLastRequst = Date ( ) . timeIntervalSince ( lastRequestDate ?? Date . distantPast)
44- if uniqueAssets. isNotEmpty || uniqueCurencies. isNotEmpty || timeFromLastRequst > 30 {
45- let updatedAssets = oldAssets + uniqueAssets
46- let updatedCurrencies = currencies + uniqueCurencies
37+ func setup( ) {
38+ eventCenter. add ( observer: self )
39+ let walletsOperation = walletRepository. fetchAllOperation ( with: RepositoryFetchOptions ( ) )
40+ let chainsOperation = chainRepository. fetchAllOperation ( with: RepositoryFetchOptions ( ) )
41+ let subscribeOperation = ClosureOperation { [ weak self] in
42+ let wallets = try walletsOperation. extractNoCancellableResultData ( )
43+ let currencies = wallets. compactMap { $0. selectedCurrency } . uniq ( predicate: { $0. id } )
4744
48- pricesProvider = priceLocalSubscriber. subscribeToPrices (
49- for: updatedAssets,
50- currencies: updatedCurrencies,
51- listener: self
52- )
53- self . chainAssets = updatedAssets
54- self . currencies = currencies
55- lastRequestDate = Date ( )
45+ let chains = try chainsOperation. extractNoCancellableResultData ( )
46+ let chainAssets = chains. map ( \. chainAssets) . reduce ( [ ] , + ) . uniq ( predicate: { $0. chainAssetId } )
47+
48+ self ? . observePrices ( for: chainAssets, currencies: currencies)
5649 }
50+ subscribeOperation. addDependency ( walletsOperation)
51+ subscribeOperation. addDependency ( chainsOperation)
52+ operationQueue. addOperations ( [ subscribeOperation, walletsOperation, chainsOperation] , waitUntilFinished: false )
5753 }
5854
5955 func updatePrices( ) {
@@ -77,7 +73,62 @@ extension PricesService: PriceLocalSubscriptionHandler {
7773 }
7874}
7975
76+ extension PricesService : EventVisitorProtocol {
77+ func processChainSyncDidComplete( event: ChainSyncDidComplete ) {
78+ let updatedChainAssets = event. newOrUpdatedChains. map ( \. chainAssets) . reduce ( [ ] , + ) . uniq ( predicate: { $0. chainAssetId } )
79+ observePrices ( for: updatedChainAssets, currencies: currencies)
80+ }
81+
82+ func processChainsUpdated( event: ChainsUpdatedEvent ) {
83+ let updatedChainAssets = event. updatedChains. map ( \. chainAssets) . reduce ( [ ] , + ) . uniq ( predicate: { $0. chainAssetId } )
84+ observePrices ( for: updatedChainAssets, currencies: currencies)
85+ }
86+
87+ func processMetaAccountChanged( event: MetaAccountModelChangedEvent ) {
88+ let currency = event. account. selectedCurrency
89+ observePrices ( for: chainAssets, currencies: [ currency] )
90+ }
91+ }
92+
8093private extension PricesService {
94+ static func create( ) -> PricesServiceProtocol {
95+ let chainRepository = ChainRepositoryFactory ( ) . createRepository ( )
96+ let accountRepositoryFactory = AccountRepositoryFactory ( storageFacade: UserDataStorageFacade . shared)
97+ let walletRepository = accountRepositoryFactory. createMetaAccountRepository ( for: nil , sortDescriptors: [ ] )
98+ return PricesService (
99+ chainRepository: AnyDataProviderRepository ( chainRepository) ,
100+ walletRepository: AnyDataProviderRepository ( walletRepository) ,
101+ operationQueue: OperationQueue ( ) ,
102+ logger: Logger . shared,
103+ eventCenter: EventCenter . shared
104+ )
105+ }
106+
107+ func observePrices( for chainAssets: [ SSFModels . ChainAsset ] , currencies: [ SSFModels . Currency ] ) {
108+ let oldAssets = self . chainAssets
109+ let uniqueAssets = chainAssets. filter { newAsset in
110+ !oldAssets. contains ( newAsset)
111+ }
112+ let oldCurrencies = self . currencies
113+ let uniqueCurencies = currencies. filter { newCurrency in
114+ !oldCurrencies. contains ( newCurrency)
115+ }
116+ let timeFromLastRequst = Date ( ) . timeIntervalSince ( lastRequestDate ?? Date . distantPast)
117+ if uniqueAssets. isNotEmpty || uniqueCurencies. isNotEmpty || timeFromLastRequst > 30 {
118+ let updatedAssets = oldAssets + uniqueAssets
119+ let updatedCurrencies = currencies + uniqueCurencies
120+
121+ pricesProvider = priceLocalSubscriber. subscribeToPrices (
122+ for: updatedAssets,
123+ currencies: updatedCurrencies,
124+ listener: self
125+ )
126+ self . chainAssets = updatedAssets
127+ self . currencies = currencies
128+ lastRequestDate = Date ( )
129+ }
130+ }
131+
81132 func handle( prices: [ PriceData ] , for chainAssets: [ ChainAsset ] ) {
82133 var updatedChains : [ ChainModel ] = [ ]
83134 let uniqChains : [ ChainModel ] = chainAssets. compactMap { $0. chain } . uniq { $0. chainId }
@@ -106,15 +157,3 @@ private extension PricesService {
106157 logger. error ( " Prices service failed to get prices: \( error. localizedDescription) " )
107158 }
108159}
109-
110- private extension PricesService {
111- static func create( ) -> PricesServiceProtocol {
112- let repository = ChainRepositoryFactory ( ) . createRepository ( )
113- return PricesService (
114- chainRepository: AnyDataProviderRepository ( repository) ,
115- operationQueue: OperationQueue ( ) ,
116- logger: Logger . shared,
117- eventCenter: EventCenter . shared
118- )
119- }
120- }
0 commit comments