티스토리 뷰
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 활용하기
복잡한 데이터를 저장할 때.. 나중에..
'Sopt 28th 세미나 - iOS' 카테고리의 다른 글
[Swift] Activity Indicator & Lottie (0) | 2021.08.16 |
---|---|
[Swift] TableView 개념 (0) | 2021.08.14 |
[Swift] 시작하는 스토리보드 바꾸는 방법 (0) | 2021.08.14 |
[Swift] ViewController 화면 전환 (0) | 2021.07.23 |
[Swift] ViewController 생명주기 (0) | 2021.07.22 |