UserDefaults
안녕하세요. 제가 이전에 작성한 글을 보면 공부해야 할 것이라고 CoreData
를 언급했습니다. 어플리케이션의 사용자가 어플리케이션을 사용하면서 저장해놨던 설정이나 값들을 서버가 아닌 디바이스에 저장하기 위해 저는 CoreData
를 공부하려 했습니다.
하지만 현업 개발자분과 여러 블로그들의 글을 보면 CoreData
는 데이터베이스의 테이블의 수가 적거나 테이블 간의 관계가 복잡하지 않다면 사용하지 않는 것이 좋다고 언급하셨습니다. 그리고 그러한 상황에서도 CoreData
보다는 SQLite
를 더 많이 사용하는 것 같았습니다.
저는 지금 복잡한 관계의 데이터들을 디바이스에 저장하기 위한 것이 아닌 사용자가 설정한 어플리케이션 세팅 값과 기록한 값(ToDo List의 목록, 친구 연락처의 친구 목록 등등)과 같이 간단한 데이터들을 저장하려 하기 때문에 위와 같은 옵션들은 적절하지 않았습니다.
그래서 구글링을 한 결과 UserDefaults
를 사용하여 데이터를 저장하는 것이 현재 저에게 가장 좋은 방법이라고 생각했습니다. 그럼 오늘은 UserDefaults
에 관해 간단히 알아보는 시간을 갖도록 하겠습니다.
1. UserDefaults
UserDefaults
의 사용법은 매우 간단했습니다. 먼저 UserDefaults
가 무엇인지 알아보도록 하겠습니다. 애플의 문서에는 다음과 같이 쓰여져 있습니다.
An interface to the user’s defaults database, where you store key-value pairs persistently across launches of your app.
간단하게 설명하자면 key-value
쌍으로 디바이스에 데이터를 저장하는 것을 도와주는 인터페이스입니다. 애플 문서의 설명을 추가적으로 인용하자면 UserDefaults
는 Default System에 접근할 수 있는 인터페이스를 제공하는 클래스입니다.
그럼 이제 UserDefaults
의 사용법을 알아보도록 하겠습니다.
2. 데이터 저장과 불러오기
데이터를 저장하는 것과 불러오는 것은 각각 코드 한 줄로 구현이 가능합니다.
UserDefaults.standard.set(value, forKey: "CustomKey") // Save
UserDefaults.standard.value(forKey: "CustomKey") // Load
이 두 줄로 데이터를 저장하고 불러올 수 있습니다. 매우 간단하죠!?
데이터를 불러올 때는 약간의 코드를 추가해야 합니다. 위의 데이터를 불러오는 코드의 반환 타입을 살펴보시면 Any?
인 것을 확인하실 수 있습니다. 올바르지 않은 forKey
값에 대한 접근을 했을 때는 nil
값이 반환되기 때문에 옵셔널 타입인 것을 확인할 수 있습니다. 또한 데이터를 불러올 때는 저장한 값의 타입으로 캐스팅을 해야 정상적으로 값에 접근할 수 있습니다.
var data = "String data"
UserDefaults.standard.set(data, forKey:"stringData")
var loadedData = UserDefaults.standard.value(forKey: "stringData") as! String
그럼 이를 바탕으로 간단한 예제 어플리케이션을 만들어보도록 하겠습니다.
3. Example
먼저 화면 구성은 다음과 같습니다. 흔히 어플리케이션에서 볼 수 있는 설정화면입니다. 설정 해놓은 값이 어플리케이션이 실행할 때마다 초기화 된다면 당연히 안되겠죠?! 이렇게 설정 값을 저장하기 위해 UserDefaults
를 사용해보도록 하겠습니다.
먼저 세팅 화면의 기본적인 ViewController
는 다음과 같습니다. 코드를 추가해가면서 완성시켜보도록 하겠습니다.
// MARK: - SettingViewController.swift
class SettingViewController{
@IBOutlet weak var vibrateSwitch: UISwitch!
@IBOutlet weak var soundSwitch: UISwitch!
@IBOutlet weak var brightSlider: UISlider!
override func viewDidLoad(){
super.viewDidLoad()
// ToDo
}
}
먼저 Save
버튼을 눌렀을 때 설정 값을 저장하고 메인 화면으로 돌아가게끔 코드를 작성하겠습니다.
// MARK: - SettingViewController.swift
extension SettingViewController {
@IBAction func saveBtnTapped(_ sender: Any){
UserDefaultss.standard.set(vibrateSwitch.isOn, forKey: "vibrate")
UserDefaultss.standard.set(soundSwitch.isOn, forKey: "sound")
UserDefaultss.standard.set(brightSlider.value, forKey: "bright")
navigationController?.popViewController(animated: true)
}
}
그리고 세팅 화면으로 들어왔을 때 이전의 설정한 값들로 설정되어 있어야 하고, 이전에 설정해놓은 값이 없다면 기본 값을 설정해주기 위한 코드를 작성해보도록 하겠습니다.
// MARK: - SettingViewController.swift
class SettingViewController{
@IBOutlet weak var vibrateSwitch: UISwitch!
@IBOutlet weak var soundSwitch: UISwitch!
@IBOutlet weak var brightSlider: UISlider!
override func viewDidLoad(){
super.viewDidLoad()
setState()
}
}
extension SettingViewController {
func setState(){
let userDefualts = UserDefaults.standard
if let vibrate = userDefaults.value(forKey: "vibrate"),
let sound = userDefaults.value(forKey: "sound"),
let bright = userDefaults.value(forKey: "bright"){
// Load Data
vibrateSwitch.isOn = vibrate as! Bool
soundSwitch.isOn = sound as! Bool
brightSlider.value = bright as! Float
}else{
// Default Setting
vibrateSwitch.isOn = true
soundSwitch.isOn = true
brightSlider.value = 0.5
}
}
}
값을 가져올 때는 반드시 저장한 값의 타입으로 캐스팅을 해주시는 것을 잊지마세요!
이렇게 Key-Value
을 통한 값의 접근에 Key
값은 상당히 중요합니다. 이러한 Key
값에 직접적인 문자열을 사용한다면 실수를 유발할 수 있습니다. 그래서 저는 다음과 하나의 타입으로 Key
값을 구현하여 사용하도록 하겠습니다.
// MARK: - SettingViewController.swift
struct Setting{
enum State:String{
case Vibrate
case Sound
case Bright
}
}
이렇게 작성된 최종 코드는 다음과 같습니다.
struct Setting{
enum State:String{
case Vibrate
case Sound
case Bright
}
}
class SettingViewController{
@IBOutlet weak var vibrateSwitch: UISwitch!
@IBOutlet weak var soundSwitch: UISwitch!
@IBOutlet weak var brightSlider: UISlider!
override func viewDidLoad(){
super.viewDidLoad()
setState()
}
}
extension SettingViewController {
func setState(){
let userDefualts = UserDefaults.standard
if let vibrate = userDefaults.value(forKey: Setting.State.Vibrate.rawValue),
let sound = userDefaults.value(forKey: Setting.State.Sound.rawValue),
let bright = userDefaults.value(forKey: Setting.State.Bright.rawValue){
// Load Data
vibrateSwitch.isOn = vibrate as! Bool
soundSwitch.isOn = sound as! Bool
brightSlider.value = bright as! Float
}else{
// Default Setting
vibrateSwitch.isOn = true
soundSwitch.isOn = true
brightSlider.value = 0.5
}
}
}
extension SettingViewController {
@IBAction func saveBtnTapped(_ sender: Any){
UserDefaultss.standard.set(vibrateSwitch.isOn, forKey: Setting.State.Vibrate.rawValue)
UserDefaultss.standard.set(soundSwitch.isOn, forKey: Setting.State.Sound.rawValue)
UserDefaultss.standard.set(brightSlider.value, forKey: Setting.State.Bright.rawValue)
navigationController?.popViewController(animated: true)
}
}
마무리
이제 프로젝트를 실행하시고 세팅 값을 설정하신 후 어플리케이션 종료 후 세팅 화면으로 들어가시면 저장한 값들로 설정된 화면을 홗인하실 수 있습니다. 이렇게 간단한 타입뿐만 아니라 [String]
과 같이 배열의 형태나 [String: Int]
와 같은 딕셔너리 형태로도 저장이 가능하니 한번 직접 만들어시길 바랍니다.
오늘은 이렇게 간단한 데이터를 저장하는 방법 중 하나인 UserDefaults
와 이에 대한 사용법을 알아보았습니다. 감사합니다.
Soure: github
참고자료