Architecture + Design Pattern

Delegate & Protocol

iosswift 2022. 3. 28. 21:04

Swift 에서 controllers 간 communication 수단 중 하나인 Delegate & Protocol 은 주로 1:1 communication 에 쓰인다. 

(다른 수단으로는

Notification & Observer 도 있다. 1:n Communication 에 쓰임,

completionHandler(Closure) 를 이용하는 방법도 있음 )

 

먼저 간단히 설명하자면, Boss 와 employee 간의 관계로 이해하면 쉽다.

(Boss 가 명령을 내릴 수 있는 list 는 protocol 에 정의된다. )

 

Boss 는 SettingsViewController, 

employee 는 ProfileViewController  로 보면 된다. 

 

 

첫번째 화면은 첫번째 Screen 이자 Profile ViewController

 

두번째 화면은 

SettingsViewController.

 

 

두번째 화면에서 Name, Info, Image, color 를 고른 후 체크마크를 누르면 입력한 값을 ProfileViewController 에 적용한다. 

 

 

 

 

 

 

 

 

 

 

 

입력한 값을 적용하는 과정.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이제 코드를 살펴보자

 

// Employee

class ProfileViewController: UIViewController {
    
    lazy var settingsBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "gear"), 
    style: .done, target: self, action: #selector(settingsBarButtonItemTapped))
    
    @objc fileprivate func settingsBarButtonItemTapped() {
        let controller = SettingsViewController()
        controller.delegate = self
        
        navigationController?.pushViewController(controller, animated: true)
    }
    
    func apply(_ profile: Profile) {
        iconImageView.image = UIImage(named: profile.icon)?.withRenderingMode(.alwaysTemplate)
        iconImageView.tintColor = profile.accentColor
        nameLabel.text = profile.name
        infoLabel.text = profile.info
    }
}

extension ProfileViewController: SettingsViewControllerDelegate {
    func didChange(_ profile: Profile) {
        apply(profile)
    }
}

각 Layout 에 대한 상세 코드는 생략하고 중요한 코드만 가져왔다. 

ProfileViewController 에서 settingBarButtonItem 을 누르면 settingBarButtonItemTapped func 이 실행된다.

해당 함수를 누르면 SettingsViewController 로 이동하는데, 이 controller 의 delegate 는 자신이다. (controller.delegate = self), (Boss 의 employee 가 본인이라고 말하는 과정) 

 

 

// Boss

import UIKit

protocol SettingsViewControllerDelegate{
    func didChange(_ profile: Profile)
}

class SettingsViewController: UIViewController {
    
    var delegate: SettingsViewControllerDelegate?
    
    lazy var saveBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "checkmark"), 
    style: .done, target: self, action: #selector(saveBarButtonItemTapped))
    
    @objc fileprivate func saveBarButtonItemTapped() {
        let profile = Profile(icon: "icon\(UserDefaults.standard.integer(forKey: kIconButton))", accentColor: colors[UserDefaults.standard.integer(forKey: kColorButton)], name: nameTextField.text ?? "", info: infoTextField.text ?? "")
        print(profile)
        // call the delegate
        delegate?.didChange(profile)
        navigationController?.popViewController(animated: true)
    }
}

여기에서도 마찬가지로 중요한 코드만 가져왔다. 

protocol SettingsViewControllerDelegate 내에는 employee 가 boss 를 위해 수행할 함수를 선언한다. 

 

위 예시에서는 saveBarButtonItem 을 누르면 saveBarButtonItemTapped 가 실행되며, 여기에서 delegate?.didChange(_:) 가 호출된 후 profileVC 로 돌아가게 된다. 

 

 

전체 source Code 는 아래에서 확인할 수 있다.

https://github.com/hanmok/protocolDelegatePrac

 

 

 

 

출처 https://www.youtube.com/watch?v=UQnSdXFDAQQ