UserDefaults

2023년 1월 6일 수정

UserDefaults

UserDefaults 혹은 NSUserDefaultsiOSmacOS 용 앱에서 간단한 정보나 설정을 저장하고 읽어 들이기 위해 사용하는 클래스다. 데이터를 키-값(Key-Value) 스타일로 읽거나 쓸 수 있게 구성되어 있다. 해당 데이터는 각 앱의 전용 공간에 plist 형태로 저장된다.

Swift에서는 UserDefaults 라는 이름으로 사용되고 있지만 원래 이름은 NSUserDefaults 이고 Objective-C에서는 아직도 이 이름이 사용되고 있다.

굉장히 다양한 기능을 제공하고 있지만, 보통은 .standard 라는 싱글톤 객체를 이용해 저장하거나 읽어 들이는 단순한 메서드를 주로 사용한다.

데이터는 단순한 기본 타입의 값 위주로 사용한다고 생각하자. 복잡하거나 큰 데이터는 이 저장소에 어울리지 않으니 별도의 DB나 Core Data를 활용하자.

설정 저장하기

아래 예제는 age 라는 키의 값을 27로 저장하는 예제다.

UserDefaults.standard.set(27, forKey: "age")

데이터 타입에 따라 다양한 오버로드가 있기 때문에 Swift의 기본 타입 데이터는 대부분 그대로 저장할 수 있다.

저장된 데이터는 앱이 종료되어도 계속 파일 시스템에 기록되어서 남는다.

설정 읽어오기

읽을 때는 타입에 신경을 쓰는 편이 좋다.

let age = UserDefaults.standard.integer(forKey: "age")

각 타입을 읽어 들이는 전용 메서드들이 구현되어 있으니 적당한 것으로 찾아 쓰는 편이 편하다.

물론 아래 처럼 캐스팅을 통해서 사용하는 것도 가능하긴 하다.

let age = UserDefatuls.standard.object(forKey: "age") as? Int

개인적으로는 캐스팅 방식은 코드가 복잡해 보이는 경향이 있어서 전용 메서드를 사용하는 것을 추천한다.

기본값

register(defaults:) 메서드를 활용해서 기본값들을 작성해 줄 수 있다.

UserDefaults.standard.register(
  defaults: [
    "key1": true,
    "key2": 10,
    "key3": "value"
  ])

이 기본값은 별도로 저장된 키의 값이 존재하면 저장된 값을 사용한다. 그리고 이 기본값들은 메모리상에만 저장되기 때문에 별도로 set 하지 않는 한 앱이 종료되면 사라진다. 따라서 register(defaults:) 코드는 앱 시작 시 항상 실행되게 작성해 놓아야 원하는 용도로 사용할 수 있다.

JSON으로 복잡한 데이터 저장하고 읽기

유행과도 같은 JSON 형태를 이용해 복잡한 데이터를 저장하거나 읽는 것도 가능은 하다.

예를 들어 쓸 때는 아래와 같이 JSONEncoder 를 활용한다. 인코딩 방법은 Swift에서 JSON 인코딩/디코딩하기 글을 참고하자.

do {
  let json = try JSONEncoder().encode(object)
  UserDefaults.standard.set(json, forKey: "my-json-data")
} catch {
  // JSON 인코딩에 실패할 경우 예외처리
}

synchronize()?

결론부터 말하자면 이 메서드는 이제 잊어도 된다.

과거에는 값을 저장한 뒤에는 이 메서드를 호출하는 편이 안전했다. 파일 시스템과 메모리의 내용을 동기화 하는 커맨드이기 때문이다.

UserDefaults.standard.synchronize()

이 메서드가 호출되면 값이 바로 파일 시스템이 기록되었다. 반대로 쓰지 않았을 경우 간혹 데이터를 잃어 버리는 경우도 있었다.

하지만 요즘은 쓸 필요가 없이 모두 자동으로 필요할 때 값이 저장된다. 오히려 애플🌏공식 문서에서는 사용하지 않는 것을 추천하고 있다.