아리의 iOS 탐구생활

[iOS/Swift] Notification, NotificationCenter 본문

Swift/iOS

[iOS/Swift] Notification, NotificationCenter

Ari Lee 2021. 10. 20. 20:58
반응형

 

싱글턴 객체중 하나이므로 이벤트들의 발생 여부를 옵저버를 등록한 객체들에게 Notification을 post하는 방식으로 사용한다.

Notification Name이라는 Key 값을 통해 보내고 받을 수 있다.

장점

  • 많은 줄의 코드가 필요없이 쉽게 구현이 가능하다.
  • 다수의 객체들에게 동시에 이벤트의 발생을 알려줄 수 있다.
  • Notification과 관련된 정보를 Any? 타입의 object, [AnyHashable : Any]? 타입의 userInfo로 전달할 수 있다.

단점

  • key 값으로 Notification의 이름과 userInfo를 서로 맞추기 때문에 컴파일시 구독이 잘 되고 있는지, 올바르게 userInfo의 value를 받아오는지 체크가 불가능 하다
  • 추적이 쉽지 않을 수도 있다
  • Notification post 이후 정보를 받을 수 없다.

✔️ Notification

NotificationCenter를 통해 정보를 저장하기 위한 구조체다. 옵저버들에게 전달되는 구조체로 정보가 담겨있고, 해당 알림을 등록한 옵저버에게만 전달된다. 구조체는 아래와 같이 구성되어 있다.

var name: Notification.Name
var object: Any?
userInfo: [AnyHashable : Any]?
  • name
    전달하고자 하는 notification의 이름 (이걸 통해 알림을 식별한다)
  • object
    발송자가 옵저버에게 보내려고 하는 객체. 주로 발송자 객체를 전달하는 데 쓰임
  • userInfo
    notification과 관련된 값 또는 객체의 저장소. Extra data를 보내는데 사용 가능

 

✔️ Notification Center (NSNotificationCenter)

notification이 오면 observer pattern을 통해서 등록된 옵저버들에게 notification을 전달하기 위해 사용하는 클래스. notification을 발송하면 NotificationCenter에서 메세지를 전달한 observer를 처리할 때까지 대기한다.
즉, 흐름이 동기적으로 흘러간다.

  • otification Center를 통해서 앱의 한 파트에서 다른 파트로 데이터를 전달할 수 있다.
  • Notification이 오면 등록된 observer list를 스캔한다.
  • Notification Center는 어플리케이션 어느 곳에서 어느 객체와도 상호작용을 할 수 있다.

 

상호 작용을 하기 전에 extension으로 Notification.Name을 추가해주면 편리하다.

// Notification Name 설정
extension Notification.Name {
    static let secret = Notification.Name("Shh")
}

 

✔️ NotificationCenter로 Post하기 (발송하기)

  • Post가 핵심이다. Name의 해당자들에게 일을 수행하라고 시킨다.
// 노티피케이션 발송
NotificationCenter.default.post(name: Notification.Name.secret, object: nil, userInfo: [NotificationKey.password: "암호는 !@#$"])
  • name
    전달하고자 하는 notification의 이름 (이걸 통해 알림을 식별)
  • object
    addObserver의 object 부분과 목적이 동일한데, 특정 sender의 notification만 받고 싶은 경우 작성 해주면 된다. filter 기능과 같다고 생각하면 될 것 같다. 없으면 nil
  • userInfo
    notification과 관련된 값이다. extra data를 보내는데 사용한다.

 

Notification Center에 Observer 등록하기

  • notification을 observe 해주기 전에 Notification Center에 addObserver 과정을 무조건 먼저 거쳐줘야 원하는 신호를 관찰 가능하니까 주의하도록 하자.
  • addObserver가 있으면 removeObserver(_:name:object:)도 있는데 방식은 같다.
// Notification Name 설정
NotificationCenter.default.addObserver(self, selector: #selector(answerToMaster(notification:)), name: Notification.Name.secret, object: nil)

@objc func answerToMaster(notification: Notification) {
    // notification.userInfo 값을 받아온다.
    guard let key = notification.userInfo?[NotificationKey.password] as? String else {
        return
    }
    print("\(name): \(key)")
}

 

NotificationCenter는 언제 사용해야할까?

  • 앱 내에서 공식적인 연결이 없는 두 개 이상의 컴포넌트들이 상호작용이 필요할 때
  • 상호작용이 반복적으로 그리고 지속적으로 이루어져야 할 때
  • 일대다 또는 다대다 통신을 사용하는 경우

예제 코드 풀버전

// Notification Name 설정
extension Notification.Name {
    static let secret = Notification.Name("Shh")
}

// Notification과 관련된 인스턴스
enum NotificationKey {
    case password
}

class Master {
    func callPassword() {
        print("마스터: 벽면에 쓰여있는 암호를 읊어봐.")
        // NotificationCenter로 Post하기 (발송하기)
        NotificationCenter.default.post(name: Notification.Name.secret, object: nil, userInfo: [NotificationKey.password: "!@#$"])
    }
}

class Friend {
    let name: String
    
    init(name: String) {
        self.name = name
        // NotificationCenter에 Observer 등록하기
        NotificationCenter.default.addObserver(self, selector: #selector(answerToMaster(notification:)), name: Notification.Name.secret, object: nil)
    }
    @objc func answerToMaster(notification: Notification) {
        // notification.userInfo 값을 받아온다.
        guard let object = notification.userInfo?[NotificationKey.password] as? String else {
            return
        }
        print("\(name): 암호는 \(object)")
    }
}

let master = Master()

// 관찰자들 (observer)
let ariOwn = Friend(name: "아리랑")
let ariTwo = Friend(name: "쓰리랑")
let ariThree = Friend(name: "아라리오")

// observer들에게 일을 수행하라고 시킨다
master.callPassword()
/*
마스터: 벽면에 쓰여있는 암호를 읊어봐.
아리랑: 암호는 !@#$
쓰리랑: 암호는 !@#$
아라리오: 암호는 !@#$
/*

 

Reference

 

Apple Developer Documentation

 

developer.apple.com

 

Apple Developer Documentation

 

developer.apple.com

 

Delegation, Notification, 그리고 KVO

언제, 어디서 써야할까?

medium.com

 

[iOS] NotificationCenter?

🔹 Notification? observer들에게 전달되는 구조체로 정보가 담겨있고, 해당 알림을 등록한 observer에게만 전달됩니다. 구조체는 아래와 같이 구성되어 있습니다. 1️⃣ name : 전달하고자 하는 notificati

roniruny.tistory.com

 

 

반응형
Comments