[SwiftUI] CryptoApp: Filtering & Search Bar

Junyoung Park·2022년 11월 3일
0

SwiftUI

목록 보기
80/136
post-thumbnail
post-custom-banner

Filtering data based on search bar text using Combine | SwiftUI Crypto App #11

CryptoApp: Filtering & Search Bar

구현 목표

  • 서치 바의 텍스트에 따른 자동 필터링 및 UI 인터렉션 구현

구현 태스크

  • 서치 바의 텍스트를 통한 기존의 데이터 모델 필터링
  • 디바운스를 통한 텍스트 필드 입력 시간이 끝난 뒤 데이터 퍼블리셔 발행

핵심 코드

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 퍼블리셔 값이 변경될 때마다 감지 가능
  • 텍스트 필드 입력 시간이 0.5 초 이내라면 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 사용 가능

구현 화면

profile
JUST DO IT
post-custom-banner

0개의 댓글