I want to observe changes on UISearchController's text, here is my setup (and I'm pretty new to Combine
):
private var searchQuery: String? {
didSet {
print(searchQuery)
}
}
private var disposable: AnyCancellable?
func bindSearchQuery() {
disposable = searchController.searchBar.publisher(for: \.text)
.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
.sink { value in
if let _value = value {
self.searchQuery = _value
}
}
}
And I see this once only in the console, on load:
Optional("")
I had to create an AnyPublisher
object then received its changes on an AnyCancellable
object:
final class SearchResult {
var resultText: String? {
didSet {
print(resultText)
}
}
}
///
@Published var searchQuery: String = ""
private var validateQuery: AnyPublisher<String?, Never> {
return $searchQuery
.debounce(for: 0.3, scheduler: RunLoop.main)
.removeDuplicates()
.flatMap { query in
return Future { promise in
self.search(query: query) { result in
switch result {
case .success(let _output):
print(_output)
promise(.success(_output))
case .failure:
print("Failed search")
promise(.success(nil))
}
}
}
}
.eraseToAnyPublisher()
}
private var cancelable: AnyCancellable?
private var result = SearchResult()
///
func bindSearchQuery() {
cancelable = validateQuery
.receive(on: RunLoop.main)
.assign(to: \.resultText, on: result)
}
And everytime user types in the search box I update searchQuery
:
func updateSearchResults(for searchController: UISearchController) {
self.searchQuery = searchController.searchBar.text ?? ""
}