[IOS/Swift] NotificationCenter 사용하기

2022. 12. 8. 23:17IOS

NotificationCenter

NotificationCenter는 앱 내에서 메세지를 던지고 필요한 곳에서 이 메세지를 받아 사용할 수 있는 기능을 수행한다. 좀 구체적으로 설명을 하자면 이벤트 발생시 Notification post하는 파트 Notification을 받아 할 일을 수행하는 observer로 구성되며 이 옵저버는 특정 이벤트만을 기다리며 이벤트가 발생할 때만 불린다. 등록된 observer들에게 동시에 notification 전달할 수 있으며, NotificationCenter Notification 발송되면 옵저버가 이를 처리할 때까지 동기적으로 진행된다. NotificationCenter를 이용한 데이터 넘기기는 비교적 적은 코드로  내의 어느 곳에 있는 객체든지 상호작용을   있다는 장점을 가지고 있다. 보통 백그라운드 작업의 결과, 비동기 작업의 결과  현재 작업의 흐름과 다른 흐름의 작업으로부터 이벤트를 받을  사용된다.

 

 


 

Notification 

NotificationCenter를 통해 정보를 저장하기 위한 구조체이며 다음과 같이 구성되어 있다.

var name: Notification.Name 
var object: Any? 
userInfo: [AnyHashable : Any]?

 

- var name: Notification.Name  

 전달하고자 하는 notification의 이름으로 식별자 역할을 한다.

 

- var object: Any? 

 발송자가 옵저버에게 전달하고자 하는 객체로 전달하고자 하는 객체를 의미한다.

 

- userInfo: [AnyHashable : Any]? 

 notification과 관련된 값 또는 객체의 저장소 등 추가적인 정보를 보내는 데 사용된다.

 

 


 

NotificationCenter : Post, addObserver

 

원하는 이벤트에 맞춰서 post 매서드를 이용해 코드를 작성하면 NotificationCenter에 해당 name을 식별자로 한 Notification이 발송된다.

NotificationCenter.default.post(
                name: Notification.Name("key"),
                object: data,
                userInfo: ["extra_data" : extra_data]
            )

 

옵저버는 addObserver 매서드로 만들 수 있으며 다음과 같이 구성되어 있다.

func addObserver(
	Any, // 옵저버 역할을 수행할 객체
	selector: Selector, // 옵저버가 실행할 함수
	name: NSNotification.Name?,  // Notification의 name(식별자)
	object: Any? // 넘겨진 데이터
)

 

 

따라서 위에서 작성한 post를 받기 위해서는 다음과 같이 작성하면 된다.

NotificationCenter.default.addObserver(
    self,
    selector: #selector(editDiarysetNotification(_:)),
    name: Notification.Name("editDiary"),
    object: nil
)


@objc func doSomething(_ notification : Notification) {
    guard let data = notification.object as? String else {return}
    print(data)
}

 

 


 

 

extension NotificationCenter.Name

위에 작성된 것처럼 코드를 작성하여도 되지만, 식별자인 name의 값을 까먹거나 맞춤법 실수로 버그가 발생할 때가 종종있다. 이러한 사고를 줄이고 더 쉽게 코드를 작성하기 위한 팁으로 extension NotificationCenter.Name 을 사용할 수 있다.

extension Notification.Name {
    static let NotificationName = Notification.Name(rawValue: "namekey")
}

 

이를 이용하면 이전의 소개했던 post와 addObserver 코드를 다음과 같이 바꿀 수 있다.

NotificationCenter.default.post(
                name: .NotificationName,
                object: data,
                userInfo: ["extra_data" : extra_data]
)

NotificationCenter.default.addObserver(
    self,
    selector: #selector(editDiarysetNotification(_:)),
    name: .NotificationName,
    object: nil
)

 

 

 

 


 

removeObserver

만일 특정 post에 대해 여러 옵저버를 만든다면 버그가 발생할 가능성이 많다. 따라서 필요가 없어진 observer는 지워야 할 필요가 있다! 따라서 앱의 생명주기를 사용해 필요한 때에 등록시키고 없애는 과정이 필요하다. 많은 분들이 willdisappear 함수를 사용하여 제거한다.필자는 deinit을 이용해 제거해 보았다. 

deinit {
        NotificationCenter.default.removeObserver(self)
    }