Filtering data based on search bar text using Combine | SwiftUI Crypto App #11
private func addSubscriber() {
$searchText
.combineLatest(dataService.$allCoins)
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.map(filterCoins)
.sink { [weak self] coinModels in
self?.allCoins = coinModels
}
.store(in: &cancellables)
}
searchText
퍼블리셔 값이 변경될 때마다 감지 가능debounce
를 통해 내려가지 않도록 조정combineLatest
를 통해 텍스트 필드의 텍스트 퍼블리셔와 데이터 서비스가 리턴하는 allCoins
값을 함께 핸들링import Foundation
import Combine
class HomeViewModel: ObservableObject {
@Published var allCoins: [CoinModel] = []
@Published var portfolioCoins: [CoinModel] = []
@Published var searchText: String = ""
private let dataService = CoinDataService()
private var cancellables = Set<AnyCancellable>()
init() {
addSubscriber()
}
private func addSubscriber() {
$searchText
.combineLatest(dataService.$allCoins)
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.map(filterCoins)
.sink { [weak self] coinModels in
self?.allCoins = coinModels
}
.store(in: &cancellables)
}
private func filterCoins(text: String, coins: [CoinModel]) -> [CoinModel] {
guard !text.isEmpty else { return coins }
let lowerCasedText = text.lowercased()
let filteredCoins = coins.filter({$0.name.lowercased().contains(lowerCasedText) || $0.symbol.lowercased().contains(lowerCasedText) || $0.id.lowercased().contains(lowerCasedText)})
return filteredCoins
}
}
filterCoins
함수를 통해 퍼블리셔를 핸들링하는 부분의 map
함수로 적용filter
사용 가능