오늘은 iOS 앱 개발을 한다면 꼭 알아야 할 Delegate Pattern에 대해 정리해보겠습니다.
1. Delegate란 무엇인가?
Delegate의 사전적 의미를 보면 대리자, 위임자 정도로 해석이 가능합니다
'뭘 위임한다는 거지...?' 라는 의문이 들 텐데, Swift에서는 Delegate 패턴을 통해 특정 기능을 위임하는 것이 가능합니다
한 객체에서 모든 프로세스를 처리하기엔 가독성, 코드 재사용성 측면에서 많은 손해를 보기 때문입니다
2. 사용법
이제는 델리게이트가 뭔지도 알겠고 왜 쓰는지도 알겠는데 어떻게 쓰는 걸까?
delegate를 제대로 사용하기 위해서는 아래 내용들을 이해하고 있어야 합니다
- 프로토콜 (Protocol) : 대리자가 수신자에게 전달할 내용의 약속(규칙)입니다
- 수신자 (Receiver) : 대리자가 특정 기능을 수행 후 전달받을 대상입니다
- 대리자 (Delegate) : 수신자를 대신하여 처리할 대리자입니다
흠.... 이렇게 텍스트로만 보면 뭔 소린지 저도 헷갈리네요
프로토콜에 대한 내용이 더 궁금하신 분들은 아래 글에서 더 확인하실 수 있습니다
2021.09.27 - [📕 Mobile/Swift] - [Swift] 프로토콜 지향 프로그래밍(Protocol Oriented Programming, POP)
이해를 돕기 위해 아래 샘플 코드를 준비하였습니다
3. 사용예
좌측이 AViewController, 우측이 BViewController 입니다.
Delegate 패턴을 적용하여 BViewController에서 입력한 내용을 AViewController로 넘기는 예제입니다
앞으로는 AViewController; AVC, BViewController; BVC로 표기하여 설명하겠습니다.
3-1. 프로토콜 작성
protocol CustomDelegate {
func returnValue(vc: BViewController, text: String?)
}
본 예제에서 대리자(Delegate)는 BVC, 수신자(Receiver)는 AVC가 됩니다
프로토콜은 통상 대리자(BVC)에 작성하며 BVC에서 AVC로 어떤 정보를 넘겨줄 것인가..를 생각해서 프로토콜을 작성하면 됩니다
저는 BVC에서 OK 버튼을 누르면 textField의 텍스트를 넘겨줄 수 있도록 프로토콜을 작성하였습니다
대리자는 넘겨주기만 할 뿐 수신 시 처리는 수신자(Receiver)가 할것 입니다.
3-2. 대리자 코드 작성 (BViewController)
var delegate: CustomDelegate!
프로토콜을 작성했으니 delegate를 인스턴스화 해줍니다
이 코드를 보면 초기화가 되어있지 않은데 초기화는 언제 해주냐? 라는 생각이 들텐데 AVC에서 BVC를 호출할 때 입니다
이 부분은 3-3에서 추가 설명 하도록 하겠습니다
@IBAction func click(_ sender: Any) {
self.delegate.returnValue(vc: self, text: tf.text)
}
click 함수는 OK 버튼과 연결되어있습니다
프로토콜에 작성한대로 vc에는 자신을, text에는 넘겨줄 text를 작성하면 됩니다
3-3. 수신자 코드 작성 (AViewController)
@IBAction func click(_ sender: Any) {
guard let vc = self.storyboard?.instantiateViewController(withIdentifier: "BViewController") as? BViewController else { return }
vc.delegate = self
self.present(vc, animated: true, completion: nil)
}
AVC에서 'Go BViewController' 버튼을 클릭했을 때 이벤트입니다
스토리보드에서 BVC를 가져오고 BVC의 delegate 변수를 self(AVC)로 초기화 해준 뒤 present하였습니다
delegate에 자신을 담았다는 것은 해당 delegate를 '채택'했음을 의미합니다
extension AViewController: CustomDelegate {
func returnValue(vc: BViewController, text: String?) {
vc.dismiss(animated: false, completion: {
DispatchQueue.main.async {
self.tf.text = text
}
})
}
}
AVC는 CustomDelgate를 채택하였으므로 필수적으로 CustomDelegate의 함수를 작성해주어야 합니다
그럼 3-1의 대리자가 전달한 내용을 AVC에서 받을 수 있게됩니다
vc는 BVC이므로 값을 전달받았을 때 BVC를 dismiss하고 전달받은 text를 화면에 띄우는 형식입니다
소스코드 원본은 깃에 올려두었습니다
https://github.com/YuchanSong/swift-delegate-sample.git
뭔가 쉽게 설명을 못한 느낌이네요,,,ㅠ
어렵지 않은 소스이니 글과 코드를 참고해주세요
그래도 이해가 안 되는 부분이 있다면 댓글로 남겨주세요~!