Notification Center - Publisher
Notification Center - 옵저버 등록과 제거
var observer: NSObjectProtocol? observer = NotificationCenter.default.addObserver(forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: nil) { notification in print("user tak..
forstudy.tistory.com
Notification Center - publisher
Notification Center 에 addObserver 를 통해 notification 을 수신했을 때 실행할 클로저를 정의할 수도 있지만, Notification 을 발행하는 Combine publisher 형태로 제공받아 Combine 프레임워크의 강력한 operation 을 적용할 수도 있다.
func publisher(for name: Notification.Name, object: AnyObject? = nil)
-> NotificationCenter.Publisher
name
publish 할 Notification 의 이름
object
위 name 을 가지는 Notification 을 post 할 object, 만약 nil 이면, 해당 이름을 가지는 모든 노티피케이션을 sender 에 상관없이 publish 한다.
Return Value
Notification 을 publish 하는 Publisher 를 리턴한다.
Notification Publisher 예시
UITextField 는 기본적으로 text 프로퍼티가 바뀔 때마다, UITextField.textDidChangeNotification 을 post 한다. 즉 Notification Center 를 통해 해당 텍스트 변경 이벤트를 구독하는 옵저버를 만들거나, 텍스트 변경 이벤트를 publish 하는 publisher 를 사용할 수 있다.
위와 같은 화면이 있을 때, textField 의 값이 바뀔 때마다 Label 의 text 가 똑같이 변경되는 코드를 작성해보자.
Step 1. text 변경 이벤트를 발행하는 publisher 생성하기
extension UITextField {
func textPublisher() -> AnyPublisher<String, Never> {
NotificationCenter.default.publisher(for: UITextField.textDidChangeNotification, object: self)
.compactMap {
$0.object as? UITextField
}
.compactMap(\.text)
.eraseToAnyPublisher()
}
}
- UITextField extension 을 통해, 각 UITextField 의 text 가 변경될 때 해당 변경 이벤트를 publish 하는 publisher 를 반환하는 함수를 정의하였다
- compactMap -> 하위 stream 에 nil 이 아닌 요소만 publish 하고, nil 인 요소는 제공하는 combine operator
- Notification sender 를 UITextField 로 타입 캐스팅하고, 해당 UITextField 의 text 프로퍼티를 publish 한다.
Step 2. Notification Publisher 를 통해 받는 값을 Label 에 적용하기
class ViewController: UIViewController {
private var cancelBag: Set<AnyCancellable> = []
@IBOutlet weak var label: UILabel!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
addTextFieldChangeObserver()
}
private func addTextFieldChangeObserver() {
// 텍스트 필드 변경 이벤트를 Label 의 text 프로퍼티에 할당
textField.textPublisher()
.receive(on: DispatchQueue.main)
.assign(to: \.text!, on: label)
.store(in: &cancelBag)
}
}
- textField 가 변경될 때마다, 해당 변경된 값을 UILabel 의 text 프로퍼티로 할당함
위와 같이 Notification Center 와 Combine 을 같이 사용하면 아래와 같은 결과를 얻을 수 있다.