[Swift] UIViewController 간 데이터 전달 방법(Delegate Pattern, Closure, NotificationCenter 등)

Oni·2023년 11월 1일
0

기술면접

목록 보기
12/13
post-thumbnail

iOS 앱에서 UIViewController 간에 데이터를 전달하는 다양한 방법이 있다. 다음은 주요한 방법들에 대한 간단한 설명이다.

1. Delegate Pattern (델리게이트 패턴)

Delegate 패턴은 객체 간의 통신을 위해 사용한다. 프로토콜을 정의하여 원하는 동작을 정의하고, 해당 프로토콜을 채택한 객체를 델리게이트(delegate)로 설정한다. 이 방법은 일반적으로 하위 UIViewController에서 상위 UIViewController로 데이터를 전달할 때 사용된다.

protocol DataDelegate: AnyObject {
    func sendData(data: String)
}

class SenderViewController: UIViewController {
    weak var delegate: DataDelegate?

    func sendDataToReceiver() {
        delegate?.sendData(data: "Hello from Sender")
    }
}

class ReceiverViewController: UIViewController, DataDelegate {
    func sendData(data: String) {
        print("Received data: \(data)")
    }
    
    func configureDelegate() {
        let senderVC = SenderViewController()
        senderVC.delegate = self
    }
}

2. Closure (클로저)

클로저를 사용하여 데이터 전달 및 콜백을 수행할 수 있다. 클로저를 변수에 저장하고, 필요한 시점에 호출하여 데이터를 전달한다.

class SenderViewController: UIViewController {
    var dataHandler: ((String) -> Void)?

    func sendDataToReceiver() {
        dataHandler?("Hello from Sender")
    }
}

class ReceiverViewController: UIViewController {
    func configureClosure() {
        let senderVC = SenderViewController()
        senderVC.dataHandler = { data in
            print("Received data: \(data)")
        }
    }
}

3. NotificationCenter

NotificationCenter를 사용하여 이벤트를 등록하고 발송하면, 여러 객체들 간에 데이터를 전달할 수 있다.

class SenderViewController: UIViewController {
    func sendDataToReceiver() {
        NotificationCenter.default.post(name: NSNotification.Name("DataNotification"), object: nil, userInfo: ["data": "Hello from Sender"])
    }
}

class ReceiverViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(handleData(_:)), name: NSNotification.Name("DataNotification"), object: nil)
    }
    
    @objc func handleData(_ notification: Notification) {
        if let data = notification.userInfo?["data"] as? String {
            print("Received data: \(data)")
        }
    }
}

4. Segues (세그웨이)

스토리보드에서 UIViewController 간의 화면 전환을 정의할 때 세그웨이를 사용할 수 있다. 세그웨이를 사용하여 데이터를 전달할 때는 prepare(for:sender:) 메서드를 오버라이드하여 목적지 뷰 컨트롤러에 데이터를 전달할 수 있다.

class SenderViewController: UIViewController {
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destinationVC = segue.destination as? ReceiverViewController {
            destinationVC.receivedData = "Hello from Sender"
        }
    }
}

class ReceiverViewController: UIViewController {
    var receivedData: String?
}

5. URL Scheme (URL 스키마)

URL 스키마를 사용하여 다른 앱의 뷰 컨트롤러로 데이터를 전달할 수 있다. 해당 앱은 특정 URL 스키마를 처리하는 기능을 구현해야 한다.

// Sender App
if let url = URL(string: "receiverapp://data?message=Hello%20from%20Sender") {
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}

// Receiver App (AppDelegate에서 처리)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    if url.scheme == "receiverapp" {
        if let message = url.queryParameters?["message"] {
            // 데이터 처리
        }
    }
    return true
}

이 방법들 중 하나를 선택하여 UIViewController 간에 데이터를 전달할 수 있다. 선택한 방법은 앱의 구조와 요구사항에 따라 달라질 수 있다.

profile
하지만 나는 끝까지 살아남을 거야!

0개의 댓글