한국어로 번역하면 알림기지국
.
앱 내의 각각에서 발생하는 여러 이벤트들이 있다.
화면의 캡쳐가 일어난다던가, 특정 값이 변한다던가, 어떤 뷰가 불러와진다던가 등등 수도 없이 많은 활동이
앱 내에서는 늘 일어나고 있다.
이 이벤트들의 상호작용이 원활하게 일어나도록 선을 이어줄 수 있는데, 이 연관성을 NotificationCenter
로 확보할 수 있다.
사실 특정 상황에서는 Delegate 패턴을 쓰는 것이 더 낫지만 NotificationCenter
를 써야 하는 이유는 아래와 같다.
해당 내용은 해외 블로거의 글에서 발췌했다.
기본으로 제공되는 default
싱글톤 객체가 있으며, 2가지 형태의 addObserver()
메소드를 활용하거나, post()
로 게시 활동을 받아올 수 있다.
이 싱글톤 객체를 쓰고 싶지 않다면 커스텀도 가능하다.
removeObserver()
를 제공하지만, 꼭 필수적으로 개발자가 구현할 필요는 없다고 한다.
이 객체 활동으로 리턴되는 비동기 시퀀스와 Combine 퍼블리셔를 받아올 수도 있다.
각각 NotificationCenter
의 notifications
, publisher
메소드를 호출하여 활용한다.
그러나 NotificationCenter
는 하나의 프로그램 내에서만 작동하기 때문에 다른 프로세스와 노티피케이션을 주고받고 싶다면 DistributedNOtificationCenter
를 써야 한다.
기본 형태 활용을 잘 익혀보도록 하자.
우선 싱글톤 객체를 만들어보자.
텍스트가 텍스트필드 위에 없을 때는 placeholder
를 노출시키고 그 외의 경우엔 숨겨줄 것이다.
UIView
내의 UITextView
에서 텍스트 변화가 일어나는 상황이다.
특정 텍스트가 변화할 때마다 셀렉터 함수가 호출될 것이고,
UITextView
의 특정 텍스트가 변화할 때를 받아와야 하니까 name
파라미터에는 UItextView.textDidChangeNotification
을 전달한다.
// MARK: UIView
func setNotification() {
NotificationCenter.default.addObserver(self,
selector: #selector(textInputDidChange),
name: UITextView.textDidChangeNotification,
object: nil)
}
// MARK: Selectors
@objc func textInputDidChange() {
placeholderLabel.isHidden = !self.messageInputTextView.text.isEmpty
}
이런 식으로 앱 내의 정보 변화, 이벤트 등등을 감지해서 쉽게 뷰를 새로 그릴 수 있다.
이를 활용하면 동적 UI도 그릴 수 있다.
UIResponder
객체는 앱 내의 이벤트가 서로 상호작용할 수 있도록 기본 구조를 갖추고 있는데, 키보드의 움직임음 받아오거나, 텍스트의 변화를 감지할 수도 있다.
모든 UIView
객체를 포함하여 UIViewController
까지 Responder
가 될 수 있다.
UIResponder
는 이번 게시글의 주인공이 아니라 이만 줄이고, 추가 내용이 필요하다면 공식 문서를 보자.
정말 정리가 잘 되어 있다!
다시 원점으로 돌아오자.
이번엔 NotificationCenter
를 활용해서 키보드가 화면에 등장하면 뷰의 상단을 끌어 올리고, 키보드가 사라지면 다시 원 상태로 돌려보자.
// MARK: UIView
func setNotification() {
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillShow),
name: UIResponder.keyboardWillShowNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillHide),
name: UIResponder.keyboardWillHideNotification,
object: nil)
}
// MARK: Selectors
@objc func keyboardWillShow() {
if view.frame.origin.y == 0 {
self.view.frame.origin.y -= 60
}
}
@objc func keyboardWillHide() {
if view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}
그런데 이렇게만 쓰면 NotificationCenter
의 절반만 활용하는 것이라 할 수 있다.
기본 이벤트만 Receiver
의 observer
로 쓰고 있고, broadcaster
를 직접 쓰고 있지 않기 때문이다.
post
를 써서 Name
에 해당하는 옵저버들을 활성화하는 것이 NotificationCenter
의 핵심이다.
여러 객체 간의 이벤트와 호출해야 하는 메소드 통신이 가능해지고, 심지어 데이터도 전달할 수 있다! 무려 여러 객체로!
// MARK: Broadcaster
func userLogin() {
// code
let loginInfo = ["name": "길동이", "age": "15"]
NotificationCenter.default.post(name: .loginSuccess, object: loginInfo)
}
// MARK: Receiver
func setupNotification() {
NotificationCenter.default.addObserver(self,
selector: #selector(loggedIn(_:)),
name: .loginSuccess,
object: nil)
}
// MARK: Selector
// NotificationCenter로 전달되는 데이터는 Notification 구조체 형태로 전달된다.
@objc func loggedIn(_ notification: Notification) {
print(notification.object as? [String: Any] ?? ["데이터가": "없는디?"])
}
간단하게
NotificationCenter
의 목적과 쓰임, 활용을 요약.
NotificationCenter
는 델리게이트 패턴의 1:1 대응을 앱 전체로 확장하고 데이터를 전달하기 위해 활용할 수 있다.addObserver
메소드를 활용하여 이벤트가 감지될 때마다 특정 메소드를 호출할 수 있다.post
메소드를 활용하여 내가 원하는 곳에서 노티피케이션의 트리거를 정의하고 데이터를 전달할 수 있다.애플공식문서 - NotificationCenter
NotificationCenter in Swift <- 일독 강력 추천
Is necessary removeObserver in NSNotificationCenter for iOS 9.0 and later or macOS 10.11 and later ?
220819