[iOS] App Development

[iOS] 다른 뷰컨의 함수 호출하기 : Call Another Viewcontroller's Function(NotificationCenter)

ddgoori 2021. 12. 16. 17:24

프로젝트 진행중 아기이름을 수정하는 기능 개발 중 다른 뷰컨의 함수를 호출하는 기능이 필요했다.

 

셋팅화면에서 babyName을 수정했을 때 발생하는 이벤트는 다음과 같다.

1) textField에 입력한 데이터 firestore에 update
2) 메인뷰컨의 아기이름 레이블에 firestore데이터 한번 더 조회 get 해서 업데이트해주기(변경된 아기이름 반영)

iOS 이벤트 전달은 아래의 3가지로 구현할 수 있는데.

- 컴플리션 블럭 클로저

- 프로토콜 델리게이트

- 노티피케이션센터

 

2)번 진행시 notificationCenter를 아래와 같이 활용하였다.

 

메인뷰컨

 

// import 아래에 상수로 이름 구현
let notificationName = "updateMainViewNotification"

 

viewDidLoad에 노티피케이션이라는 방송 수신기 장착

observer: 자기자신

selector: 특정한 주파수의 방송이 들어왔을 때 행하는 액션, 여기 메소드가 발동이 되는 것임 

name: 특정주파수가 위에 notificationName인 것임 

object: 이벤트 전달에 대한 데이터도 넘길 수 있음!

 override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(updateBabyView), name: NSNotification.Name(rawValue: notificationName), object: nil)
  }
  
 @objc func updateBabyView() {
        if Auth.auth().currentUser != nil {
            getBabyName { name in
                self.babyNickNameLabel.text = name
            }
        } else {
            self.babyNickNameLabel.text = "데이터 오류!ㅠ"
        }
    }

 

 

 

 

셋팅아기이름뷰컨

 

 

방송을 뿌리는 것은 메인의 함수를 호출할 뷰컨에서 진행

 

NotificationCenter에 접근해서 post! 이벤트를 알린다. object는 데이터를 넘길 수 있음

어떤 노티피케이션 이름을 보낼건지 name에 입력 object는 데이터

 

노티피케이션 이름을 첨에 선언할 때 밖에 상수로 정해놨기 때문에 사용할 수 있음

 
    @objc func didTapSave() {
        let babyNameRef = db.collection("Users").document(userUid!)

        // Set the "capital" field of the city 'DC'
        babyNameRef.updateData([
            "babyNickName": babyNameField.text
        ]) { err in
            if let err = err {
                print("Error updating document: \(err)")
            } else {
                print("Document successfully updated")
            }
        }

        print(babyNameField.text)
        
        // 노티피케이션센터 방송국 호출 부분
        NotificationCenter.default.post(name: Notification.Name(rawValue: notificationName), object: nil)
        
        self.navigationController?.popViewController(animated: true)
        self.dismiss(animated: true, completion: nil)

 

 

결과적으로 변경된 아기이름이 다시 메인뷰컨에서 로드되어 아기이름 레이블이 잘 바뀐 것을 확인할 수 있었다!

 

 

중요! 노티피케이션은 등록을 했으면 등록해제를 해줘야한다.

메인뷰컨에서 한다.

뷰컨이 메모리에서 해제될 때 해주면 된다. deinit에서 하면된단 말.

 

화면이 여러개고 중첩적으로 생기고, 옵저버 해제하지 않으면 메모리를 잡아 먹게됨

deinit {
        NotificationCenter.default.removeObserver(self)
}

 

 

추가할 부분,,

노티피케이션을 여러개 등록하게 된다면?

 

 

 

 

 

 

 

 

출처: 개발하는정대리