Search code examples
swiftfrpcombine

Simple Swift Combine subscribing to textDidChangeNotification


I'm having trouble getting the most simple implementation of the Combine pattern to work, subscribing to a UITextField textDidChangeNotification.

import UIKit
import Combine

class ViewController: UIViewController {

    let textField = UITextField()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(textField)
        textField.frame = CGRect(x: 100, y: 0, width: view.frame.width, height: 100)
        textField.placeholder = "Search"

        let sub = NotificationCenter.default.publisher(for: UITextField.textDidChangeNotification, object: textField)
            .sink { (notification) in
                print("123")
        }
    }

}

I must be missing something super simple, but this basic pattern is exactly copied from the Documentation and other tutorials.

Thanks for the help.


Solution

  • The sink call returns an AnyCancellable, a ARC managed object which models the lifetime of your subscription.

    You assigned this cancellable token to the local variable sub, whose lifetime ends at last usage of the sub variable (no later than the end of the viewDidLoad() function's scope). This is causing your subscription to be cancelled early, before anything could have happened.

    If you want your subscription to last longer, you need to extend the lifetime of sub, perhaps by storing it as a property of your ViewController object.