I'm trying to learn how to use Combine in an AppKit app I'm working on. I found an Apple Developer article that explains pretty much exactly what I'm trying to achieve, delaying input from an NSTextField with the .debounce operator. (https://developer.apple.com/documentation/combine/receiving-and-handling-events-with-combine)
Unfortunately it doesn't seem to be working for me. I have created a function in a NSTableCellView subclass that gets called as part of the cell's configuration which looks like:
When I run the app and type in that field, nothing gets printed to the Console.
As a test, I also tried adding a NotificationCenter observer that calls a method to print out the notification's object.
That works as expected.
So what's going on with my attempted use of Combine?
Unfortunately it doesn't seem to be working for me. I have created a function in a NSTableCellView subclass that gets called as part of the cell's configuration which looks like:
Code Block private func watchForSearchTextEntries() { print("Setting up search text observer") let sub = NotificationCenter.default .publisher(for: NSControl.textDidChangeNotification, object: searchTermText) .map( { ($0.object as! NSTextField).stringValue } ) .sink(receiveCompletion: { print ($0) }, receiveValue: { print ($0) }) }
When I run the app and type in that field, nothing gets printed to the Console.
As a test, I also tried adding a NotificationCenter observer that calls a method to print out the notification's object.
Code Block NotificationCenter.default.addObserver(self, selector: #selector(receivedTextChangeNotification(_:)), name: NSControl.textDidChangeNotification, object: searchTermText)
That works as expected.
So what's going on with my attempted use of Combine?
I finally realized that I simply needed to keep a strong reference to sub. The finished code now looks something like:
Code Block private var searchTextObserver: AnyCancellable! private var item: ModelItem! private func setupTextObserver() { let sub = NotificationCenter.default .publisher(for: NSControl.textDidChangeNotification, object: searchTermText) .map( { ($0.object as! NSTextField).stringValue } ) .debounce(for: .milliseconds(500), scheduler: RunLoop.main) .sink(receiveValue: { [weak self] in self?.item.value = $0 }) searchTextObserver = sub }