관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 4. 뷰 컨트롤러 간 데이터 전달 본문

iOS 기본 (swift)

[iOS - swift] 4. 뷰 컨트롤러 간 데이터 전달

jake-kim 2020. 4. 2. 19:31

*소스코드 출처 : 꼼꼼한 재은씨의 스위프트 기본편

1. 직접 전달 방식 (동기 방식)

 - 자료형은 NSMutableDictionary을 쓰는게 가장 전달받기 쉬움

 1) 프레젠테이션 방식 & 네비게이션 컨트롤러 방식 (인스턴스화 할 때 다운캐스팅 해줘야 하는 것 주의)

1
2
3
4
5
6
7
8
9
10
11
12
// VC1
class ViewController: UIViewController {
    var text = "이것이 넘겨질 데이터 내용"
    
    @IBAction func onClick(_ sender: Any) {
        guard let rvc = self.storyboard?.instantiateViewController(identifier: "RVC"as? ResultViewController else {
            return
        }
        
        rvc.paramLabel = text
self.navigatrionController?.pushViewController(rvc, animated: true)
    }
}
 
 
1
2
3
4
5
6
7
8
9
10
// VC2
class ResultViewController: UIViewController {
    
    @IBOutlet var label: UILabel!
    var paramLabel: String!
    
    override func viewDidLoad() {
        self.label.text = paramLabel
    }
}
 
 

VC2에서 viewDidLoad에서 pramLabel을 할당 받는 다는 의미 : VC1에서 접근하는 객체와 VC2의 viewDidLoad()접근 객체가 동일. (=뷰 컨트롤러의 인스턴스는 싱글톤)

 

2) 세그웨이를 이용하여 값을 전달

 - prepare메소드에 segue.destination을 통해 인스턴스를 가지고 데이터 넘겨줌

1
2
3
4
5
6
7
// VC1
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let dest = segue.destination
        guard let rvc = dest as? ResultViewController else {
            return
        }
        rvc.paramLabel = self.email.text!
    }
 
 

 

3) 데이터 반대로 보내기 (VC2에서 VC1으로 전달)

1
2
3
4
5
6
7
    @IBAction func back(_ sender: Any) {
        guard let vc = self.presentingViewController as? ViewController else {return}
        
        vc.param.text = "from VC2"
        
        self.navigationController?.popViewController(animated: true)
    }
 
 

※ 주의 사항 

  - present방식 : viewWillAppear 부르지 않음

  - navigation 방식 : viewWillAppear 부름

  - segue 방식 : viewWllAppear 부르지 않음

 -> navigation방식이 데이터 주고받기에 좋음

 

2. 간접 전달 방식 (비동기 방식)

 

1) AppDelegate.swift파일에 저장 (싱글톤 객체이므로 가능)

1
2
3
4
5
6
7
8
9
10
11
import UIKit
 
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
 
 
  /* 값을 저장할 변수를 정의 */
  var paramEmail : String// 이메일 값을 전달받을 변수
...
 
 

 - Delegate객체 얻어와서 저장

1
2
3
// VC2
let ad = UIApplication.shared.delegate as? AppDelegate
ad?.paramEmail = self.eail.text
 

(받아오는 VC1에서도 역시 이 객체로 값 가져오면 됨)

 

2) UserDefaults객체를 사용하여 값을 주고받기

 - 코코아 터치 프레임워크에서 제공하는 UserDefaults객체 사용(따로 객체 생성하지 않음)

 - 앱을 삭제하기 까지 반영구적 유지

 - 딕셔너리 형태로 저장

1
2
3
4
5
6
7
// VC2
// UserDefaults 객체의 인스턴스를 가져온다
    let ud = UserDefaults.standard
    
    // 값을 저장한다.
    ud.set(self.email.text, forKey: "email")
    ud.set(self.isUpdate.isOn, forKey: "isUpdate")
    ud.set(self.interval.value, forKey: "interval")

    self.navigationContorller?.popViewController(animated: true)

 
1
2
3
4
5
6
7
8
9
10
11
12
13
// VC1
    //UserDefaults 객체의 인스턴스를 가져온다
    let ud = UserDefaults.standard
    
    if let email = ud.string(forKey: "email") {
      resultEmail.text = email
    }
    
    let update = ud.bool(forKey: "isUpdate")
    resultUpdate.text = (update == true ? "자동갱신":"자동갱신안함")
    
    let interval = ud.double(forKey: "interval")
    resultInterval.text = "\(Int(interval))분마다"
 

- 또는 Any로 나오게 하고 캐스팅 방법 (둘 다 모두 Any타입 반환)

  ud.value(forKey: "email") as? String

  ud.object(forKey: "email") as? String

 

- 저장된 모든 데이터 삭제

1
2
3
for key in UserDefaults.standard.dictionaryRepresentation().keys {
    UserDefaults.standard.removeObject(forKey: key.description)
}
 

 

※ UserDefaults는 간단한 자료형을 저장하는 용도 -> 테이블에 대한 레코드 저장은 sqlite사용할 것

 float, double, integer 및 boolean과 같은 기본 자료형과

 NSData, NSString, NSNumber, NSDate, NSArray 또는 NSDictionary 유형의 객체를 저장가능

 

* 일반적으로 다양한 객체를 저장하고 효율적인 데이터베이스 다루는 "Realm"사용

https://ios-development.tistory.com/31

 

[iOS - swift] 1. 데이터베이스 (Realm)

1. Realm을 사용하는 이유 - UserDefaults는 기본적인 데이터 형식(String, int)와 같은 것마 가능하지만 Realm은 빠르고 유연함 2. Realm 프레임워크 준비 1) podfile에 프레임워크 추가 및 인스톨 1 2 pod 'R..

ios-development.tistory.com

 

Comments