@@ -15,6 +15,7 @@ final class SearchViewModel: Store {
1515 var searchQuery : String = " "
1616 var selectedWebPage : WebPageItem ?
1717 var webPages : OrderedSet < WebPageItem > = [ ]
18+ var recentQueries : OrderedSet < String > = [ ]
1819 var filteredWebPages : [ WebPageItem ] {
1920 webPages. filter {
2021 $0. title. localizedCaseInsensitiveContains ( searchQuery) ||
@@ -30,6 +31,9 @@ final class SearchViewModel: Store {
3031 case onAppear
3132 case fetchWebPage( [ WebPageItem ] ? = nil )
3233 case selectWebPage( WebPageItem )
34+ case addRecentQuery( String )
35+ case removeRecentQuery( String )
36+ case clearRecentQueries
3337 case setAlert( Bool )
3438 case setLoading( Bool )
3539 case setSearching( Bool )
@@ -42,9 +46,21 @@ final class SearchViewModel: Store {
4246
4347 @Published private( set) var state : State = . init( )
4448 private let fetchWebPagesUseCase : FetchWebPagesUseCase
49+ private let userDefaults : UserDefaults
4550
46- init ( fetchWebPagesUseCase: FetchWebPagesUseCase ) {
51+ private enum DefaultsKey {
52+ static let recentQueries = " Search.recentQueries "
53+ }
54+
55+ private let maxRecentQueries = 20
56+
57+ init (
58+ fetchWebPagesUseCase: FetchWebPagesUseCase ,
59+ userDefaults: UserDefaults = . standard
60+ ) {
4761 self . fetchWebPagesUseCase = fetchWebPagesUseCase
62+ self . userDefaults = userDefaults
63+ self . state. recentQueries = Self . loadRecentQueries ( userDefaults: userDefaults)
4864 }
4965
5066 func reduce( with action: Action ) -> [ SideEffect ] {
@@ -63,6 +79,21 @@ final class SearchViewModel: Store {
6379 state. webPages = OrderedSet ( items)
6480 case . selectWebPage( let item) :
6581 state. selectedWebPage = item
82+ case . addRecentQuery( let query) :
83+ let trimmed = query. trimmingCharacters ( in: . whitespacesAndNewlines)
84+ guard !trimmed. isEmpty else { break }
85+ state. recentQueries. remove ( trimmed)
86+ state. recentQueries. insert ( trimmed, at: 0 )
87+ if maxRecentQueries < state. recentQueries. count {
88+ state. recentQueries = OrderedSet ( state. recentQueries. prefix ( maxRecentQueries) )
89+ }
90+ saveRecentQueries ( Array ( state. recentQueries) )
91+ case . removeRecentQuery( let query) :
92+ state. recentQueries. remove ( query)
93+ saveRecentQueries ( Array ( state. recentQueries) )
94+ case . clearRecentQueries:
95+ state. recentQueries = [ ]
96+ saveRecentQueries ( [ ] )
6697 case . setAlert( let isPresented) :
6798 setAlert ( & state, isPresented: isPresented)
6899 case . setLoading( let isLoading) :
@@ -103,4 +134,12 @@ private extension SearchViewModel {
103134 state. alertMessage = " 문제가 발생했습니다. 잠시 후 다시 시도해주세요. "
104135 state. showAlert = isPresented
105136 }
137+
138+ static func loadRecentQueries( userDefaults: UserDefaults ) -> OrderedSet < String > {
139+ OrderedSet ( userDefaults. stringArray ( forKey: DefaultsKey . recentQueries) ?? [ ] )
140+ }
141+
142+ func saveRecentQueries( _ queries: [ String ] ) {
143+ userDefaults. set ( queries, forKey: DefaultsKey . recentQueries)
144+ }
106145}
0 commit comments