UserDefaults를 사용하는 이유가 뭔가요?
여러 이유가 있겠지만 core Data를 사용하는 것보다 간단하고, 앱의 어느 곳에서나 데이터를 쉽게 읽고 저장할 수 있음
단점 : 대량의 데이터를 저장할 떄는 core Data 사용하는 것이 좋음 ex) 개인정보, 데이터 저장 등등
UserDefauls에 대해 간단히 말하지만 데이터 저장소 이다.
공식문서를 보면
정의를 보면 앱을 실행하는 동안 키 - 값 쌍을 저장하는 한다고 나온다. 즉, UserDefaults는 [ 데이터 , 키(key) ] ( 딕셔너리 ) 값으로 저장된다.
UserDefaults를 설정하고 저장하는 법
저장된 UserDefaults를 실행하는 법
그럼 적용을 해보면
우리가 텍스트 필드를 통해 입력하는 곳에 UserDefaults를 실행하면 저장이 되기 때문에
value를 Any?로 해줌으로써 해당 데이터를 넣고 실행 할때 타입 캐스팅을 해주기로 하자 ( 왜 Any?를 선택했냐면, 우리가 저장하려는 데이터가 String 타입으로 타입 캐스팅 해줄것이기 때문이다)
코드를 보면
@IBAction func addButtonTapped(_ sender: UIBarButtonItem) {
let alert = UIAlertController(title: "새로운 메모 추가하기 ", message: "새로운 메모를 추가 하시겠습니까?", preferredStyle: .alert)
let success = UIAlertAction(title: "확인", style: .default) { textField in
let textField = alert.textFields?[0].text
print(textField!)
self.memoArray.append(textField!)
UserDefaults.standard.set(self.memoArray, forKey: "saveMemo")
self.tableView.reloadData()
}
UserDefaults를 저장을 했으니 실행을 해야되는데... 어디서 하냐??
앱이 실행되기 전에 UserDefaults가 실행하거나 앱이 실행 될 때 UserDefaults가 실행하면 되기 때문에
viewWillAppear() or viewDidLoad() 에 해주면 된다.
viewDidLoad()에 실행 코드를 작성해보자
이미지를 보면 옵셔널 바인딩과 타입 캐스팅을 해준것을 볼수 있다.
왜 옵셔널 바인딩과 타입 캐스팅을 해주었나요??
set을 보면 value의 타입이 Any이고 Any뒤에 옵셔널(?)이 붙어 있기 때문에 옵셔널 바인딩과 타입 캐스팅을 해야한다.
자 이렇게 바인딩 된 data 를 어떻게 활용 하면 좋을까?? 바로 우리가 만들어 줬던 배열 ( memoArray)에 할당 해주면 UserDefaults가 실행된다.
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
guard let data = UserDefaults.standard.object(forKey: "saveMemo") as? [String] else { return }
memoArray = data
}
자 실행을 해보자
전체 코드는 이렇다.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
// 테이블을 만들 배열 만들기
var memoArray: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
guard let data = UserDefaults.standard.object(forKey: "saveMemo") as? [String] else { return }
memoArray = data
}
@IBAction func addButtonTapped(_ sender: UIBarButtonItem) {
let alert = UIAlertController(title: "새로운 메모 추가하기 ", message: "새로운 메모를 추가 하시겠습니까?", preferredStyle: .alert)
let success = UIAlertAction(title: "확인", style: .default) { textField in
let textField = alert.textFields?[0].text
print(textField!)
self.memoArray.append(textField!)
UserDefaults.standard.set(self.memoArray, forKey: "saveMemo")
self.tableView.reloadData()
}
let cancel = UIAlertAction(title: "취소", style: .cancel) { action in
print("취소버튼이 눌렸습니다.")
}
alert.addAction(success)
alert.addAction(cancel)
alert.addTextField { textfield in
textfield.placeholder = "메모를 입력해주세요"
}
// 실제 띄우기
self.present(alert, animated: true, completion: nil)
}
}
// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return memoArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "toCell", for: indexPath) as! MyTableViewCell
cell.mainLabel.text = memoArray[indexPath.row]
cell.selectionStyle = .none
return cell
}
}
// MARK: - UITableViewDelegate
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action1 = UIContextualAction(style: .normal, title: "1") { action, view, completion in
print("오른쪽으로 스와이핑 됐음 1")
completion(true)
// 배열의 index row를 삭제한다.
self.memoArray.remove(at: indexPath.row)
// 배열의 row에 fade 방식으로
tableView.deleteRows(at: [indexPath], with: .fade)
// 화면에 다시 그리기
tableView.reloadData()
}
let action2 = UIContextualAction(style: .normal, title: "2") { action, view, completion in
print("오른쪽으로 스와이핑 됐음 2")
completion(true)
}
action1.backgroundColor = .red
action1.image = UIImage(systemName: "trash")
action2.backgroundColor = .blue
action2.image = UIImage(systemName: "square.and.arrow.up")
return UISwipeActionsConfiguration(actions: [action1, action2])
}
}