티스토리 뷰

Sopt 28기 세미나 자료가 정리가 너무 잘 돼있어서 ,,, 감사합닏 ㅏ파짱 

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

present / push시에 프로퍼티에 접근해 넘겨주는 방식

vc.text = 넘기고 싶은 데이터
와 같은 코드만 작성한다고 데이터가 전달되는 것이 아니다.
해당 vc를 push하거나 present까지 진행되어야 데이터가 전달되는 형태이다.

self.navigationController?.pushViewController(vc, animated: true)
-> 이렇게 정의한 객체를 현재 navigation의 다음 화면으로 띄우겠다 !

 

Segue prepare 메소드를 활용해서 데이터를 넘겨주는 방식

segue는 두 뷰사이의 관계를 의미한다.

출발지인 source / 도착지인 destination

segue를 통한 화면 전환이 일어나기 전, prepare(for: sender) 메소드가 호출이 된다.

// MARK: -2 세그를 이용해서 서로 data 주고받기 (스토리보드에서)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
	if segue.destination is SecondViewController { 
    	let vc = segue.destination as? SecondViewController 
        vc?.text = self.segueTextField.text ?? "" 
    }
}
 
"segue의 목적지가 SecondViewController인가요?"
	if segue.destination is SecondViewController 
라고 조건을 걸어주면 해당의 segue의 destination을 타입 캐스팅해서 vc에다가
SecondViewController의 인스턴스를 선언하고 있는 모습을 볼 수 있다.

let vc = segue.destination as? SecondViewController

 

Protocol / Delegation을 활용해서 데이터를 넘겨받는 방식

프로토콜은 특정 기능 및 역할을 수행하기 위해 필요한 것들이 적혀있는 설명서와 동일한 개념

delegate pattern은 "하나의 객체가 모든 일을 처리하는 것이 아닌" 처리해야 하는 일부를 확장해 다른 객체에게 넘기는 것 (위임)

// FirstViewController

import UIKit

// SampleProtocol 채택 
class FirstViewContoller: UIViewController, SampleProtocol {

	// 라벨 선언
    
	@IBOutlet weak var dataLabel: UILabel!
    
    override func ViewDidLoad() {
    	super.viewDidLoad()
    
    }
    
    func dataSend(data: String) {
    	dataLabel.text = data
    }
    
    // 버튼 눌렀을 때, 다음 화면 이동
    
    @IBAction func nextButtonClicked(_ sender: Any) {
    
    	guard let nextVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as?
        		SecondViewController else {return}
                
       	nextVC.delegate = self
        
        self.navigationViewController?.pushViewController(nextVC, animated: true)
        
    }
        
}
// SecondViewController

import UIKit


// SampleProtocol 생성
// 데이터를 넘기는 함수 원형만 적고, 구현부는 첫번째 뷰컨에서 
protocol SampleProtocol {
	func dataSend(data: String)
    }
    
class SecondViewController: UIViewController {
	
    // 텍스트필드 선언
    @IBOutlet weak var dataTextField: UITextField!
    
    // SampleProtocol 형의 delegate 프로퍼티를 생성
    var delegate : SampleProtocol?
    
    override func viewDidLoad() {
    	super.viewDidLoad()
        
    }
    
    // 버튼 눌렀을 때 동작
    @IBAction func dataSendButtonClicked(_ sender: Any) {
    
    // 버튼이 눌렸을 때, 위에서 선언한 delegate의 dataSend에다가 textField의 text를 담는다.
    if let text = dataTextField.text{
    	delegate?.dataSend(data: text)
    }
    
    // delegate 처리가 끝난 뒤에, navigation Pop처리
   	self.navigationController?.popViewController(animated: true)
    
    }

}

첫번째 뷰컨 -> protocol 채택, 실제 구현, delegate 위임(채택)

두번째 뷰컨 -> 타입이 protocol인 property 생성, delegate 사용, 프로토콜 만들기

 

Closure를 활용해서 데이터를 넘겨받는 방식 (코드 블럭)

클로저는 앞 게시글에서 말했듯이 일급 시민으로 변수, 상수 등으로 저장, 전달 인자로 저장이 가능한 형태이다.

 

1번 -> 두번째 뷰컨에서 클로저 타입의 프로퍼티를 선언해두고

2번 -> 아까 선언해둔 클로저에 textField의 텍스트를 넣어두면 -> completion 클로저가 call이 된다.

3번 -> 첫번째 뷰컨에서는 completionHandler를 정의한다 : "text가 들어오면, 해당 text를 label에다가 표시해줘!"

--> 해당 클로저를 저렇게 정의하게 되면, 클로저에서 텍스트를 넘겨주게 되면 첫번째 뷰컨에서 라벨이 변경 ! ! !

NotificationCenter를 활용해 데이터를 넘기는 방식

Notification -> 정보를 전달하기 위한 구조체 / 하나의 정보를 전달하기 위한 "방송국" 개념 

NotificationCenter 에서 알아야 하는 두가지

1. NotificationCenter로 post하는 방법

NotificationCenter.defalut.post(name: NSNotification.Name("신호 이름"), object: "전달하고 싶은 데이터", userInfo: [Key: Value])

name: 전달하고자 하는 신호 이름
object: 전달하려고 하는 데이터 (데이텨형 상관없이 구조체 같은 것도 가능), 없으면 nil
userInfo: 노티피케이션과 관련된 값 또는 객체의 저장소를 넣는다. 없으면 nil

2. NotificationCenter에 observer를 등록하는 방법 

NotificationCenter.default.addObserver(self, selector: #selector(실행할 함수), name: Notification.Name("신호 이름"), object: nil)

self: 현재 자기자신 뷰컨에 옵저버를 달겠다 !
selector: 해당 신호를 받으면 실행하는 함수 부분
name: 신호를 구분하기 위한 이름
object: 해당 신호를 걸러주는 필터같은 역할, nil 사용시 해당 신호를 모두 받겠다는 의미

@objc func 실행할 함수(notification: NSNotification)
{
	실행할 부분...
}

observer 에서 다음과 같이 실행할 함수를 등록해놓으면,
	특정 신호 이름을 가진 신호가 온다면,
    야기에 있는 함수 부분이 실행된다.

직접 적용을 해보자 ! 

// SecondViewController 

@IBAction func dataSendButtonClicked(_ sender: Any) {

	if let text = dataTextField.text{
    
    	NotificationCenter.defalut.post(name: NSNotification.Name("sample"), object: text)
        }
        self.navigationController?.popViewController(animated: true)
        
    }
}

 

"sample" 이라는 신호에 textField의 text를 담아 보낼게 !

// FirstViewController

@IBAction func nextButtonClicked(_ sender: Any) {

	guard let nextVC = self.storyboard?.instantiateViewController(identifier: "SecondViewController") as?
        		SecondViewController else {return}
      
    // sample 이라는 신호를 받으면, dataReceived 함수를 실행하는 Observer를 달아줌  
    NotificationCenter.default.addObserver(self, selector: #selector(dataReceived),name: NSNotification.name("sample"), object: nil)
    
    self.navigationController?.pushViewController(nextVC, animated: true)
 }
 
 
 // nofification.object가 무슨 데이터형인지? (Int...? String...?)
 //	모르기 때문에 as?를 통해 다운캐스팅을 진행해서 해당 notification.object를 String형으로 가져와서 text형으로 넣어줌
 @objc func dataReceived(notification: NSNotification)
 {
 	if let text = notification.object as? String{
    	dataLabel.text = text
        }
    }
}

NotificationCenter를 활용할 때, 유의할 점은 Observer가 메모리 상에 올라와 있어야만 수신이 되는 형태

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

UserDefaults 사용하기

UserDefaluts도 plist 처럼 Key-Value 형태로  값을 저장 / 쓰기가 가능한 클래스이다. 기기에 .plist 형태로 저장이 된다.

기기에 저장되어 있는 파일이기 때문에, 앱을 종료하더라도 데이터가 보존되는 것이 특징!

* 간단한 사용자정보 (자동로그인 여부, 체크 여부등) 을 저장하는데는 적합한 클래스이지만,

내부에 데이터가 파일 형태로 저장되기 때문에 --> 보안상 취약

간단한 값을 저장하는데에 좋다 !

AppDelegate를 활용한 방법

AppDelegate는

1. 앱의 scene을 환경설정하고,

2. 앱의 가장 중요한 데이터 구조를 초기화하는 역할을 수행한다.

 

AppDelegate에 데이터를 저장해놓고, 앱이 종료되면 전부 초기화 ..! 

--> 앱이 종료되어도 데이터를 남기고 싶다면 CoreData / UserDefaults를 활용 ..! 

CoreData or Realm 활용하기 

복잡한 데이터를 저장할 때.. 나중에..

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함