호댕의 iOS 개발

[iOS] Notification Center 본문

Software Engineering/iOS

[iOS] Notification Center

호르댕댕댕 2021. 11. 7. 00:35

이 글은 아래 링크를 토대로 작성한 글입니다. 

https://learnappmaking.com/notification-center-how-to-swift/

 

How To: Using Notification Center In Swift

NotificationCenter in Swift is useful for sending data from one part of your app to another. How does it work? Find out in this tutorial!

learnappmaking.com

프로젝트에서 ViewController 간에 데이터를 전달하면서 NotificationCenter를 사용했다. 하지만 NotificationCenter에 대해 정확히 알고 있단 생각이 들지 않아 이 글을 작성하게 되었다. 

NotificationCenter는 뭘까?

노티피케이션 센터를 생성하면 앱의 특정 부분에서 다른 부분으로 데이터를 전달할 수 있다. Observer 패턴을 사용해 observer를 등록하고 알림이 오면 정보를 알려준다.

  • NotificationCenter 클래스는 종종 NSNotificationCenter로 사용된다. (NS 접두사는 Swift 3 이전에 사용되던 것이다)
  • NotificationCenter 의 매커니즘은 푸쉬 알림, 로컬 알림, Notification Center UI와 전혀 관련이 없다.

어떻게 Notification Center가 작동할까?

NotificationCenter는 3가지 구성요소를 가지고 있다.

  1. observer 라 불리는 알림을 듣는 'Listener'이 존재한다.
  2. 어떤 일이 일어났는지 전달해주는 'Sender'가 존재한다.
  3. Observer와 알림을 추적하는 notification Center 그 자체가 존재한다.

NotificationCenter가 작동하는 순서

  1. B에서 NotificationCenter에 관찰을 원한다고 요청을 한다. addObserver(_:selector:name:object:)
  2. A에서 어떤 사건이 발생한다. (ex: 데이터가 들어오거나 task가 완료됨)
  3. A에서 이에 대해 NotificationCenter에 Post를 한다.
  4. NotificationCenter는 이에 대해 B에 알려준다. (B에서 selector에 있는 것을 호출할 수 있도록 한다)
  5. Selector가 호출되면 성공적으로 B에서 함수가 실행된다.

어떻게 Notification의 옵져버를 등록할까?

NotificationCenter.default.addObserver(self, selector: #selector(), name: , object: )

<addObserver의 매개변수 구성>

  1. 첫번째 파라미터는 생략되어 있다. 여기서 notification 본인을 observer로 호출해야 하기 때문에 self를 사용한다.
  2. selector: notification이 발생했을 때 호출할 함수를 적는다.
  3. name: Notification.Name 즉 Notification의 이름을 적어주면 된다.
  4. object: 알림을 받고 싶은 객체를 선택해준다. 만약 설정을 해준다면 특정 'sender'에게만 알림을 받을 수 있다.

 

💡 Objective-C에서 selector는 Objective-C 메서드의 이름을 참조하는 type이다. Swift에선 차이가 존재하지만 단순히 함수라고 부른다. 그래서 괄호 안에 작성한 함수의 이름과 함께 #selector를 입력하여 selector를 정의할 수 있다.

 

알림이 확인될 때 호출하려는 함수는 어떤 것이든 가능하다.

 

함수는 다음과 같이 호출을 해주면 된다. 

@objc func didReceiveData(_ notification: Notification) {
    // 알림을 받고 어떤 일을 할지 작성해준다. 
}

이 함수에선 Notification의 객체에 해당하는 매개변수 하나만 가진다. 여기서 post의 userInfo를 통해 보낸 데이터를 사용할 수 있다.

 

💡 여기서 반드시 @objc를 사용해야 한다. 이걸 통해 Swift 함수에서 Objective-C 런타임을 가능하게 해준다. NotificationCenter는 Objective-C 런타임에 속하기 때문에 함수에서 이를 호출해줘야 한다.

 

모든 Notification은 Notification.Name 타입으로 이름을 가지고 있다. 따라서 다음과 같이 생성해줄 수 있다.

let name = Notification.Name("dataTransmission")

extension을 사용해서 더욱 간단하게 이름을 지어줄 수도 있다.

extension Notification.Name {
    static let dataTransmission = Notification.Name("dataTransmission")
}

이렇게 해주면 addObserver에서 이름을 간단하게 호출할 수 있다. 

NotificationCenter.default.addObserver(self, selector: #selector(), name: .dataTransmission , object: )

NotificationCenter에서 가장 중요한 것은 알림이 발생하기 전에 observer를 등록하는 것이다. 알림이 notificationCenter로 발송되었을 때, 아직 observer가 등록되어 있지 않다면 알림을 놓치게 될 것이다.

 

 

어떻게 Notification의 옵져버를 해제할까?

ViewController에서 NotificationCenter를 사용한다면 등록과 해제를 모두 해줘야 한다. 

보통은 다음과 같은 단계에서 등록과 해제가 이뤄진다. 

  • ViewDidLoad() - 등록 / deinit - 해제
  • ViewWillAppear() - 등록 / ViewWillDisappear() - 해제

옵져버 해제를 해줄 때에는 다음과 같은 메서드를 사용한다. 

removeObserver(_:name:object:)

 

어떻게 Notification을 Post할까?

NotificationCenter.default.post(name: .dataTransmission, object: nil, userInfo:)

<post의 매개변수 구성>

  1. name: Notification.Name 즉 Notification의 이름을 적어주면 된다. extension을 사용해 Notification의 이름을 지어준다면 더욱 편하게 사용할 수 있다. 
  2. object: 알림의 sender를 의미한다. addObserver에서 object와 동일한 기능을 한다. nil로 남겨놓을 수도 있다. 
  3. userInfo: 알림과 함께 추가적인 데이터를 보낼 수 있다. 이 파라미터의 경우 필요한 경우만 작성하면 된다. 
    userInfo의 기본적인 데이터 타입은 [AnyHashable: Any]로 딕셔너리이다. 

 

그럼 실제 NotificationCenter를 어떻게 사용해야할까?

먼저 NotificationCenter를 사용하지 말아야 할 순간을 생각해보자. 

NotificationCenter의 메커니즘은 간단하고 편리하다. 

ViewController 간 데이터 전달에선 NotificationCenter보다 segue나 protocol 같은 다른 방법을 사용하는 것이 좋다. 

 

그렇다면 언제 NotificationCenter를 사용하는 것이 좋을까?

  1. 앱의 두 개 이상의 요소에서 커뮤니케이션을 해야하고 형식적인 연결이 없을 경우 
  2. 커뮤니케이션이 반복적이고 지속적으로 필요한 경우 
  3. 일 대 다 / 다 대 다 커뮤니케이션이 필요할 경우 

 

 

Comments