본문 바로가기
iOS/RxSwift

[RxSwift] NotificationCenter, Notification

by 0inn 2022. 11. 21.

프로젝트 진행 중에 키보드에 의해 뷰가 가려지는 상황을 해결해야 했습니다 . .

이 때, NotificationCenter로 사용해 구현할 수 있었는데요 (+ RxSwift 로 ~)

 

그래서 !! NotificationCenter에 대해서 정리하고 가려합니다 . .

의식의 흐름대로 공부해서 다른 내용도 있을 수 있습니다 . . 양해 부탁드려요 . .

NotificationCenter

 

NotificationCenter란 등록된 observers에게 정보를 broadcast가 가능하게 하는 notification dispatch 매커니즘이라고 합니다.

흠. . 무슨소릴까 싶지만 일단 observers 들에게 어떠한 방식으로 정보를 전달하는 아이 . . ?

 

아래 설명을 계속 살펴볼게요.

notification center를 등록한 객체들은 notifications를 받게 됩니다.

addObserver() 메서드를 통해서 말이죠.

객체가 자기 자신을 observer로 등록하면, 어떤 notification을 받을 건지 지정합니다.

그러므로 객체는 여러 알림에 대한 observer로 자신을 등록하기 위해 여러 번 호출할 수 있게 됩니다.

 

각각의 앱들은 default notification center를 가지고 우리는 새로운 notification center를 만들어서 사용할 수 있습니다.

 

notification center는 단일 프로그램 내에서만 주고받을 수 있으며 만약 다른 프로세스로 notification을 전달하거나 받고 싶다면 DistributedNotificationCenter를 대신 써야합니다.

 

음 ~ notification center는 notification을 observer들에게 전달해주는 아이구나 !

 

그렇다면 여기서 notification은 뭐죠 . . ?

Notification

 

Notification이란 notification center를 통해 등록된 모든 observers들에게 broadcast되는 정보를 위한 컨테이너입니다.

 

이놈의 broadcast가 뭐지 ?

네트워크에서 broadcast란 네트워크에 있는 모든 호스트로 데이터를 전송하는 방식입니다.

여기서는 등록된 모든 observers들에게 정보를 전송한다는 의미가 되겠죠 !

 

그럼 이제 사용해봐야겠죠 ?

그러려면 observer들을 등록해줘야 합니다. addObserver()로 !!

addObserver()

func addObserver(
    forName name: NSNotification.Name?,
    object obj: Any?,
    queue: OperationQueue?,
    using block: @escaping @Sendable (Notification) -> Void
) -> NSObjectProtocol
  • name : 등록할 notification의 이름
  • obj : notification을 보내는 객체
  • queue : block이 실행되는 operation queue
  • block : notification을 받으면 실행

이제 실제 키보드 구현한 코드를 살펴보겠습니다 !

NotificationCenter + Rx

public func notification(_ name: Notification.Name?, object: AnyObject? = nil) -> Observable<Notification> {
    return Observable.create { [weak object] observer in
        let nsObserver = self.base.addObserver(forName: name, object: object, queue: nil) { notification in
            observer.on(.next(notification))
        }
        
        return Disposables.create {
            self.base.removeObserver(nsObserver)
        }
    }
}

요로코롬 Rx에서 아주 편하게 구현되어 있기 때문에 ! 이걸 그대로 사용하면 됩니다 ~

 

여기서 든 의문. 왜 removeObserver 해주지 ?

RemoveObserver()

func removeObserver(
    _ observer: Any,
    name aName: NSNotification.Name?,
    object anObject: Any?
)
  • observer : 지울 observer
  • name : 지울 notification
  • object : 지울 notification을 보내는 객체

말 그대로 notification observer를 제거하는 메서드입니다.

removeObserver를 해준 이유는 사용하지 않는 observer를 제거하기 위함이겠죠 !

 

여기서 다시 의문. Disposable.create 저건 왜 return 한거지 ?

이 의문은 따로 작성할게요 . . 지금 코드를 뜯어보니 정리할 게 많을 것 같아요 . .

Notification 구현

func setKeyboardNotification() {
    NotificationCenter.default.rx
        .notification(UIResponder.keyboardWillShowNotification)
        .withUnretained(self)
        .bind { (this, notification) in
        	// 키보드 올라갈 때 처리
        }
        .disposed(by: disposeBag)
    
    NotificationCenter.default.rx
        .notification(UIResponder.keyboardWillHideNotification)
        .withUnretained(self)
        .bind { (this, notification) in
        	// 키보드 내려갈 때 처리
        }
        .disposed(by: disposeBag)
}

UIResponder에 정의된 키보드가 올라갈 때와 내려갈 때의 notification name을 넣어주면 등록 완료 !

bind해서 해당 키보드 관련 처리 코드 작성하면 끝 ~ ! !

 

UIResponder 안에 아이들이 궁금해지지 않나요 . .

UIResponder + Ext

extension UIResponder {
    
    public class let keyboardWillShowNotification: NSNotification.Name

    public class let keyboardWillHideNotification: NSNotification.Name

    @available(iOS 3.2, *)
    public class let keyboardFrameEndUserInfoKey: String // NSValue of CGRect

    @available(iOS 3.0, *)
    public class let keyboardAnimationDurationUserInfoKey: String // NSNumber of double

    @available(iOS 3.0, *)
    public class let keyboardAnimationCurveUserInfoKey: String // NSNumber of NSUInteger (UIViewAnimationCurve)
}

코드 몇 줄은 생략하고 . . 제가 키보드 구현할 때 사용했던 class만 가져와봤습니다 .

키보드 올라올 때 노티 이름, 키보드 내려갈 때 노티 이름, 키보드 높이 구할 수 있는 UserInfoKey, 애니메이션 넣을 수 있는 key들이 있습니다.

 

이렇게 NotificationCenter, Notification과 사용법에 대해 간단하게 정리해보았습니다.

공부만 해놓고 많이 사용하지 않아서 개념을 다시 착실히 알아가는 . . 좋은 기회였습니다 . .(코드도 뜯어보고 !)

키보드 관련 코드는 나중에 정리해서 올리겠습니다 . . ♡


참고

https://developer.apple.com/documentation/foundation/notification

https://developer.apple.com/documentation/foundation/notificationcenter