본문 바로가기
Swift

뷰 컨트롤러 간의 통신

by JDeoks 2023. 7. 6.

새로운 뷰 컨트롤러에게 데이터 전송

새로운 뷰 컨트롤러에게 데이터를 전송하는 방법은 다음과 같다.

// 전송버튼
@IBAction func onSubmit(_ sender: Any) {
    // rvc가 UIViewController이면 ResultViewController의 프로퍼티를 사용하지 못해서 형변환 필요
    guard let rvc = self.storyboard?.instantiateViewController(identifier: "RVC") as? ResultViewController else {
        return
    }

    // 만든 인스턴스에 값 전송
    rvc.paramEmail = emailInput.text!
    rvc.paramMode = mode.isOn
    rvc.paramInterval = interval.value
    
    rvc.modalPresentationStyle = .fullScreen
    self.present(rvc, animated: true)
}
//...
// 데이터 받는 뷰 컨트롤러
override func viewDidLoad() {
    super.viewDidLoad()
    print(paramEmail, paramMode, paramInterval)
    emailText.text = paramEmail
    modeText.text = paramMode ? "갱신함" : "갱신하지 않음"
    intervalText.text = "\(Int(paramInterval))분마다"
}

self.storyboard?.instantiateViewController(identifier: "RVC") 가 반환하는 타입은 UIViewController인데, 이 상태에서는

ResultViewController의 파라미터에 접근할 수 없다. 그래서 형변환을 한 후, 프로퍼티에 접근했다.

새로 만든 뷰 컨트롤러의 인스턴스의 파라미터에 값을 전달한 후 present 한다.

새로 만든 뷰 컨트롤러는 보여지기 전에 저장된 값들을 뷰에 적용해서 표시한다.

 

이전 뷰 컨트롤러에 데이터 전송

이전 뷰 컨트롤러의 경우에는 이미 메모리에 로드되어있기 때문에 화면으로 돌아올 때 viewDidLoad가 호출되지 않는다는 차이가 있다.

따라서 뷰가 화면에 나타나기 직전에 호출되는 메소드인 viewWillAppear를 사용한다.

 

// 전송하는 뷰 컨트롤러
@IBAction func savePrivacy(_ sender: Any) {
    // sendByParam()
    // sendByAppDel()
    sendByUD()
    self.navigationController?.popViewController(animated: true)
}

/// 이전화면으로 직접 전달
func sendByParam() {
    guard let preVC = self.navigationController?.viewControllers[self.navigationController!.viewControllers.count - 2] as? PrivacyVC else {
        return
    }
    preVC.paramEmail = emailInput.text!
    preVC.paramMode = mode.isOn
    preVC.paramInterval = interval.value
}

/// 앱 델리게이트 사용
func sendByAppDel() {
    let appDel = UIApplication.shared.delegate as! AppDelegate
    appDel.paramEmail = emailInput.text!
    appDel.paramMode = mode.isOn
    appDel.paramInterval = interval.value
}

/// UserDefaults 사용
func sendByUD() {
    let ud = UserDefaults.standard
    ud.set(emailInput.text!, forKey: "email")
    ud.set(mode.isOn, forKey: "mode")
    ud.set(interval.value, forKey: "interval")
}

// ...

// 수신하는 뷰 컨트롤러
override func viewWillAppear(_ animated: Bool) {
	// updateByParam()
	// updateByAppDel()
    updateByUD()
}

@IBAction func editPrivacy(_ sender: Any) {
    guard let editVC = self.storyboard?.instantiateViewController(identifier: "PrivacyEditVC") as? PrivacyEditVC else {
        return
    }
    self.navigationController?.pushViewController(editVC, animated: true)
}

/// 직접전달 사용
func updateByParam() {
    emailText.text = paramEmail
    autoUpdateText.text = paramMode ? "갱신함": "갱신하지 않음"
    intervalText.text = "\(Int(paramInterval))분 마다"
}

/// 엡 델리게이트 사용
func updateByAppDel() {
    // 앱 델리게이트 인스턴스 가져옴
    let appDel = UIApplication.shared.delegate as! AppDelegate
    emailText.text = appDel.paramEmail
    autoUpdateText.text = appDel.paramMode ? "갱신함": "갱신하지 않음"
    intervalText.text = "\(Int(appDel.paramInterval))분 마다"
}

/// 유저 디폴트 사용
func updateByUD() {
    let ud = UserDefaults.standard
    emailText.text = ud.value(forKey: "email") as? String
    autoUpdateText.text = ud.bool(forKey: "mode") ? "갱신함": "갱신하지 않음"
    intervalText.text = "\(Int(ud.double(forKey: "interval")))분 마다"
}

self.navigationController?.viewControllers는 현재 뷰 컨트롤러가 속한 네비게이션 컨트롤러의 스택에 있는 모든 뷰 컨트롤러들을 갖고 있는 배열로, 루트가 0이다. 이전 화면의 인스턴스를 가져오기 위해 배열의 전체 개수에서 -2한 인덱스에 접근했다.

 

UserDefaults:

데이터를 간단하게 저장하고 검색하기 위한 인터페이스로, 사용자의 기본 설정, 앱의 상태, 로그인 정보, 사용자 환경 설정 등을 영구적으로 저장하기 위해 사용한다.

 

예시

// 저장
let defaults = UserDefaults.standard
// String
defaults.set("John Doe", forKey: "name")
// Int
defaults.set(25, forKey: "age")
// 배열
let colors = ["red", "green", "blue"]
defaults.set(colors, forKey: "favoriteColors")
// 날짜
let currentDate = Date()
defaults.set(currentDate, forKey: "lastLoginDate")

// 검색
let defaults = UserDefaults.standard
// String
if let name = defaults.string(forKey: "name") {
    print("이름: \(name)")
}
// Int
let age = defaults.integer(forKey: "age")
print("나이: \(age)")
// 배열
if let favoriteColors = defaults.array(forKey: "favoriteColors") as? [String] {
    print("좋아하는 색상: \(favoriteColors)")
}
// 날짜
if let lastLoginDate = defaults.object(forKey: "lastLoginDate") as? Date {
    print("마지막 로그인 날짜: \(lastLoginDate)")
}

'Swift' 카테고리의 다른 글

NotificationCenter  (0) 2023.07.07
UITableViewDataSource  (0) 2023.07.06
네비게이션 바가 스토리보드상에서 보이지 않을 때  (0) 2023.07.01
Horizontally in container  (0) 2023.06.30
화면 전환  (0) 2023.06.29