[iOS] Combine 활용하기(3)

Han's·2023년 10월 9일
0
post-thumbnail

debounce란?

일련의 값을 버퍼링하고, 버퍼링 된 값들 중에서 가장 최근 값만을 내보내는 연산자(Operator) 중 하나입니다.
(주로 사용자 입력 또는 다른 이벤트를 처리할 때 유용하게 사용)

예를 들어 사용자가 텍스트 입력을 할 때 텍스트 필드에서 발생하는 변경 이벤트를 debounce를 사용하면 사용자의 입력이 일정 시간 동안 안정화될 때까지 이벤트를 처리하지 않고, 안정화된 입력 이벤트만을 처리할 수 있습니다.

delay와 debounce의 차이점

delay는 모든 이벤트에 동일한 지연을 적용하고, debounce는 안정화된 입력만을 내보낸다는 차이가 있습니다.

코드

import UIKit
import Combine

class DebounceViewController: UIViewController {
    
    @IBOutlet weak var myLabel: UILabel!
    
    static let identifier: String = "DebounceViewController"
    var subscriptions = Set<AnyCancellable>()
    
    private lazy var searchController: UISearchController = {
        let searchController = UISearchController()
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.tintColor = .label
        searchController.searchBar.searchTextField.accessibilityIdentifier = "mySearchBarTextField"
        return searchController
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        configure()
        bind()
    }
}

private extension DebounceViewController {
    func configure() {
        navigationItem.title = "디바운스"
        
        setupSearchController()
    }
    
    func setupSearchController() {
        navigationItem.searchController = searchController
        searchController.isActive = true
    }
    
    func bind() {
        searchController.searchBar.searchTextField
            .myDebounceSearchPublisher
            .receive(on: DispatchQueue.main)
            .sink { [weak self] receivedValue in
                guard let self = self else { return }
                print("receivedValue: \(receivedValue)")
                myLabel.text = receivedValue
            }
            .store(in: &subscriptions)
    }
}

extension UISearchTextField {
    var myDebounceSearchPublisher: AnyPublisher<String, Never> {
        NotificationCenter.default.publisher(for: UISearchTextField.textDidChangeNotification, object: self)
            .compactMap { $0.object as? UISearchTextField }
            .map { $0.text ?? "" }
        
        // delay는 값을 방출하는 시점을 지연시키는 역할, 주로 작업을 일정 시간 동안 지연시키고 타이밍을 조정할 때 사용
//            .delay(for: 2, scheduler: RunLoop.main)
        
        // debounce는 일정 시간 동안 발생하는 중간 값을 제거하여 마지막 값을 방출, 주로 사용자 입력과 같은 빠른 연속적인 이벤트에서 유용하게 사용
            .debounce(for: 1, scheduler: RunLoop.main)
        
        // 글자가 있을때만 이벤트 전달
            .filter { $0.count > 0 }
            .eraseToAnyPublisher()
    }
}
profile
🍎 iOS Developer

0개의 댓글