카테고리 없음

User Defaults와 실습

bluewiper 2024. 7. 10. 18:35

User Defaults란

  • UserDefaults 또한 디스크에 데이터를 저장할 수 있게 돕는 도구.
  • CoreData 보다 사용성이 간단.
  • key 와 value 를 이용해서 값을 저장.
  • 대량의 데이터를 담는데에는 CoreData 가, 비교적 단순한 데이터를 담는 데에는 UserDefaults 가 적절.

User Defaults의 CRUD

  • UserDefaults.standard.set() 메서드를 통해서 Create, Update
  • UserDefaults.standard.string(forKey: "") 메서드를 통해서 Read (각 타입에 맞는 메서드사용)
    • bool 타입 Read: UserDefaults.standard.bool(forKey: "")
    • Int 타입 Read: UserDefaults.standard.integer(forKey: "")
  • UserDefaults.standard.removeObject(forKey: "") 메서드를 통해서 Delete

 

1. Create and Read

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Create
        UserDefaults.standard.set("010-1111-2222", forKey: "phoneNumber")
        
        //Read
        let phoneNumber = UserDefaults.standard.string(forKey: "phoneNumber")
        
        print("저장된 전화번호: \(phoneNumber)")
    }
    
}

 

옵셔널로 표시된다. 저 노란색 오류도 옵셔널에 관한 것이다. 

String이면서 옵셔널이다.

guard let으로 바꿔서 

//Read
        guard let phoneNumber = UserDefaults.standard.string(forKey: "phoneNumber") else {
            print("저장된 번호가 없습니다.")
            return }

 

실험해보자

 

2. Update

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Create
        UserDefaults.standard.set("010-1111-2222", forKey: "phoneNumber")
        
        
        //Update
        UserDefaults.standard.set("010-2222-4444", forKey: "phoneNumber")
        
        let phoneNumber = UserDefaults.standard.string(forKey: "phoneNumber")
        
        print("새로 저장된 전화번호: \(phoneNumber)")
    }
    
}

 

 

마찬가지로 옵셔널이어서 오류가 뜨긴하지만 print는 잘 돌아간다. 

 

3. Delete

 

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Create
        UserDefaults.standard.set("010-1111-2222", forKey: "phoneNumber")
        
        
        //Update
        UserDefaults.standard.set("010-2222-4444", forKey: "phoneNumber")
        
        
        //Delete
        UserDefaults.standard.removeObject(forKey: "phoneNumber")
        let phoneNumber = UserDefaults.standard.string(forKey: "phoneNumber")
        print("전화번호가 남아있는지 확인 \(phoneNumber)")
    }
    
}

 

삭제되어서 nil로 표시된다. 

 

앱이 종료되고 나서도 데이터가 저장되어 있는지 확인

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Create
        UserDefaults.standard.set("010-1111-2222", forKey: "phoneNumber")
//        
//        
//        //Update
//        UserDefaults.standard.set("010-2222-4444", forKey: "phoneNumber")
//        
//        
//        //Delete
//        UserDefaults.standard.removeObject(forKey: "phoneNumber")
//        let phoneNumber = UserDefaults.standard.string(forKey: "phoneNumber")
//        print("전화번호가 남아있는지 확인 \(phoneNumber)")
    }
    
}

 

이 상태로 한번 돌리고

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
//        //Create
//        UserDefaults.standard.set("010-1111-2222", forKey: "phoneNumber")
//        
//        
//        //Update
//        UserDefaults.standard.set("010-2222-4444", forKey: "phoneNumber")
//        
//        
//        //Delete
//        UserDefaults.standard.removeObject(forKey: "phoneNumber")
        let phoneNumber = UserDefaults.standard.string(forKey: "phoneNumber")
        print("전화번호가 남아있는지 확인 \(phoneNumber)")
    }
    
}

Read만 남겨서 돌려본다.

 

다시 생성한 번호가 디스크에 표시된다. 

 

위 코드를 보면 우리는 String값의 타입을 받았지만, 

Int, String 과 같은 원시타입이 아닌 StructClass 타입을 저장하기 위해서는 json 인코딩 과정이 필요(이건 모르겠다. 아직) 

 

 

 

 

 

UserDefaults 를 활용해서 간단한 포스트잇 앱 만들기

  • UserDefaults 는 디스크에 데이터를 저장하기 때문에, 포스트잇에 적은 텍스트를 UserDefaults 에 저장 해둔다면, 앱을 종료해도 데이터가 소멸되지 않습니다.
  • 메모를 작성하고, 앱을 종료했다가 다시 실행해도 메모가 남는 포스트잇 앱을 만들어봅니다

 

아래 사진처럼 포스트잇을 만들어보자

 

import UIKit
import SnapKit

class ViewController: UIViewController {
    
    //라벨 생성
    private let label: UILabel = {
        let label = UILabel()
        label.text = "포스트잇"
        label.font = .boldSystemFont(ofSize: 30)
        label.textColor = .black
        return label
    }()
    
    //텍스트뷰 생성
    private let textView: UITextView = {
        let textView = UITextView()
        textView.text = ""
        textView.layer.cornerRadius = 10
        textView.backgroundColor = #colorLiteral(red: 0.5843137503, green: 0.8235294223, blue: 0.4196078479, alpha: 1)
        textView.font = .boldSystemFont(ofSize: 30 )
        return textView
    }()
    
    //적용하는 버튼 생성
    private lazy var button: UIButton = {
        let button = UIButton()
        button.setTitle("적용", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .red
        button.titleLabel?.font = .boldSystemFont(ofSize: 30)
        button.layer.cornerRadius = 10
        //button에 add Target
        button.addTarget(self, action: #selector(buttonTapped), for: .touchDown)
        return button
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        configureUI()
    }
    
    private func configureUI() {
        
        //뷰 생성
        [label, textView, button]
            .forEach { view.addSubview($0) }
        
        //배경화면 색상
        view.backgroundColor = .white
        
        //라벨 오토레이아웃 제약 설정
        label.snp.makeConstraints {
            $0.top.equalToSuperview().offset(100)
            $0.centerX.equalToSuperview()
        }
        //텍스트뷰 오토레이아웃 제약 설정
        textView.snp.makeConstraints {
            $0.top.equalTo(label.snp.bottom).offset(100)
            $0.centerX.equalToSuperview()
            $0.width.height.equalTo(200)
        }
        //텍스트뷰 오토레이아웃 제약 설정
        button.snp.makeConstraints {
            $0.top.equalTo(textView.snp.bottom).offset(50)
            $0.width.equalTo(60)
            $0.height.equalTo(40)
            $0.centerX.equalToSuperview()
        }
    }
    
    //버튼 클릭했을 때 로직
    @objc
    private  func buttonTapped() {
        UserDefaults.standard.set(textView.text, forKey: "memo") //textView.text => 텍스트뷰안에 있는 현재 텍스트
        print("저장 완료")
    }
    
}

 

이렇게 하고 시뮬레이터에서 '안녕'이라는 메시지를 입력하고, 적용을 누르면 

"저장 완료"가 뜬다. 

 

그런데 시뮬레이터를 끄지 않고, 홈화면으로 갔다가 돌아왔는데 '안녕'이라는 메시지가 안 보인다. 

 

기존에 textView 생성할 때

        textView.text = "" 빈칸으로 두었기 때문이다. 그래서 User Defaults를 써서 추적해줘야 한다. 

        textView.text = UserDefaults.standard.string(forKey: "memo")

 

 

이전에 저장해놓은 메모가 뜬다. 

새로운 메시지를 입력하고 적용을 누른 다음에 이전처럼 앱에 들어가도 잘 뜬다. 

 

 

끝.