@@ -15,10 +15,6 @@ final class CountrySelectorViewModel: FilterListSelectorViewModelable, Observabl
1515 }
1616 }
1717
18- /// Define if the view should show placeholders instead of the real elements.
19- ///
20- @Published private( set) var showPlaceholders : Bool = false
21-
2218 /// Command that powers the `ListSelector` view.
2319 ///
2420 let command = CountrySelectorCommand ( countries: [ ] )
@@ -31,93 +27,12 @@ final class CountrySelectorViewModel: FilterListSelectorViewModelable, Observabl
3127 ///
3228 let filterPlaceholder = Localization . placeholder
3329
34- /// ResultsController for stored countries.
35- ///
36- private lazy var countriesResultsController : ResultsController < StorageCountry > = {
37- let countriesDescriptor = NSSortDescriptor ( key: " name " , ascending: true )
38- return ResultsController < StorageCountry > ( storageManager: storageManager, sortedBy: [ countriesDescriptor] )
39- } ( )
40-
41- /// Trigger to sync countries.
42- ///
43- private let syncCountriesTrigger = PassthroughSubject < Void , Never > ( )
44-
45- /// Storage to fetch countries
46- ///
47- private let storageManager : StorageManagerType
48-
49- /// Stores to sync countries
50- ///
51- private let stores : StoresManager
52-
5330 /// Current `SiteID`, needed to sync countries from a remote source.
5431 ///
5532 private let siteID : Int64
5633
57- init ( siteID: Int64 , storageManager : StorageManagerType = ServiceLocator . storageManager , stores : StoresManager = ServiceLocator . stores ) {
34+ init ( siteID: Int64 ) {
5835 self . siteID = siteID
59- self . storageManager = storageManager
60- self . stores = stores
61- bindSyncTrigger ( )
62- bindStoredCountries ( )
63- }
64- }
65-
66- // MARK: Helpers
67- private extension CountrySelectorViewModel {
68- /// Fetches & Binds countries from storage, If there are no stored countries, trigger a sync request.
69- ///
70- func bindStoredCountries( ) {
71-
72- // Bind stored countries & command
73- countriesResultsController. onDidChangeContent = { [ weak self] in
74- guard let self = self else { return }
75- self . command. resetCountries ( self . countriesResultsController. fetchedObjects)
76- }
77-
78- // Initial fetch
79- try ? countriesResultsController. performFetch ( )
80-
81- // Trigger a sync request if there are no countries.
82- guard !countriesResultsController. isEmpty else {
83- return syncCountriesTrigger. send ( )
84- }
85-
86- // Reset countries with fetched
87- command. resetCountries ( countriesResultsController. fetchedObjects)
88- }
89-
90- /// Sync countries when requested. Defines the `showPlaceholderState` value depending if countries are being synced or not.
91- ///
92- func bindSyncTrigger( ) {
93- syncCountriesTrigger
94- . handleEvents ( receiveOutput: { // Set `showPlaceholders` to `true` before initiating sync.
95- self . showPlaceholders = true // I could not find a way to assign this using combine operators. :-(
96- } )
97- . map { // Sync countries
98- self . makeSyncCountriesFuture ( )
99- . replaceError ( with: ( ) ) // TODO: Handle errors
100- }
101- . switchToLatest ( )
102- . map { _ in // Set `showPlaceholders` to `false` after sync is done.
103- false
104- }
105- . assign ( to: & $showPlaceholders)
106- }
107-
108- /// Creates a publisher that syncs countries into our storage layer.
109- ///
110- func makeSyncCountriesFuture( ) -> AnyPublisher < Void , Error > {
111- Future < Void , Error > { [ weak self] promise in
112- guard let self = self else { return }
113-
114- let action = DataAction . synchronizeCountries ( siteID: self . siteID) { result in
115- let newResult = result. map { _ in } // Hides the result success type because we don't need it.
116- promise ( newResult)
117- }
118- self . stores. dispatch ( action)
119- }
120- . eraseToAnyPublisher ( )
12136 }
12237}
12338
0 commit comments