-
[Combine] Publishers 를 합쳐서 한번에 처리해주자 - combineLatestSwift 2023. 1. 13. 23:56
이런 화면을 구현하고 싶습니다 👇👇
입력받은 텍스트로 결괏값을 필터해서 맞는 결과를 보여주는 것입니다
✅ 구현1 - didSet
예전에 저 같았으면 아마도 아래와 같은 로직으로 코드를 짰을 것 같습니다 👇👇
(검증된 코드가 아닙니다 그냥 대충 이런식으로 했을것 같다~ 입니다)searchText 가 입력될때 마다 didSet 이 실행되고 거기서 필터하고..
하지만 경험상 이렇게 되면 굉장히 지저분해지니다.
왜냐? Property 에 저렇게 didSet 이 달리고 달리고 하면서 이게 intent 도 많아지고 한눈에 봤을때 안읽히는 문제가 있습니다
그럼 어떻게 해야할까요?
final class HomeViewModel: ObservableObject { private let dataService = CoinDataService() @Published var coins: [CoinModel] = [] @Published var portfolioCoins: [CoinModel] = [] @Published var searchText = "" { didSet { self.coins = filterCoins(text: searchText, coins: dataService.coins) } } private func filterCoins(text: String, coins: [CoinModel]) -> [CoinModel] { guard !text.isEmpty else { return coins } let lowercased = text.lowercased() let filtered = coins.filter { $0.name.lowercased().contains(lowercased) || $0.id.lowercased().contains(lowercased) || $0.symbol.lowercased().contains(lowercased) } return filtered } }
✅ 구현2 - combineLatest
이런식으로 쓰면 굉장히 편해집니다~!
일단 한눈에 봤을때 어떤가요? 굉장히 편해지지 않았나요?
좀더 함수형에 가까워진 기분도 들고 뭐 좋은것 같습니다
그럼 코드를 하나씩 까보면서 어떻게 구현된건지 읽어보겠습니다.
searchText에 변화가 있으면 계속 호출이 될꺼에요.
근데 서버에서 값이 받아져왔을 때도 값에 대한 변화를 주고 싶어요!
그러면 이렇게 하시면 됩니다. 바로 두 값에 변화가 있을때 마다 하나로 묶어서 한번에 처리를 해주는 거에요.
.combineLatest 는 이럴때 사용하는 메써드입니다. 다수의 Publisher에 변화가 있을때 한번에 처리를 해주는 거에요.
자 이렇게 코드를 작성하게 된다면 tuple 로 String 과 [CoinModel] 이 들어옵니다.
그리고 그걸 filterCoins 에 넘겨주고 있어요. 한번에 처리하니까 너무 깔끔하죠?
didSet 의 겹겹이 쌓인 들여쓰기도 없고 너무 깔끔한것 같아요
아래는 공식문서인데 Publishers 가 최소한 한개의 요소를 던져줘야만 호출이 된다 뭐 이런 말을 하고 있네요.
'Swift' 카테고리의 다른 글
[Swift] CodingKeys 작성, 이제 제발 그만하자 - JSONDecoder, keyDecodingStrategy (0) 2023.01.15 [Combine] 시간차를 두고 값을 내보내주자 - debounce (0) 2023.01.14 [Combine] tryMap 말고 compactMap 으로 조져보자 (0) 2023.01.13 [Swift] GCD DispatchQueue 에 대해서 (0) 2023.01.09 [Swift] 안전하게 Array Index 하기 - subscript 직접 구현하기 (0) 2023.01.08