Day 48 - UserDefaults

sun02·2021년 11월 2일
0

100 days of Swift 

목록 보기
32/40

1. UserDefaults

UserDefaults를 사용하여 앱이 설치된 동안 모든 기본 데이터 유형을 저장할 수 있다.
Bool, Float, Double, Int, String, URL뿐만 아니라 array, Dictionary, date 도 저장할 수 있다.

UserDefaults에 데이터를 작성하면, 앱이 실행될 때 자동으로 로드되어 다시 읽을 수 있다.
그러나 만약 100KB이상의 데이터를 저장한다면, 앱 로드가 느려질 수 있으므로 UserDefaults에 저장하는 것은 잘못된 것이다.

  • UserDefaults를 사용하기 전, 다음과 같은 새로운 인스턴스를 만들어야한다

let defaults = UserDefaults.standard

이후, 다양한 값을 쉽게 설정할 수 있다.
나중에 참조할 수 있도록 각각에 고유한 키를 부여하기만 하면 된다.


defaults.set(25, forKey: "Age")
defaults.set(true, forKey: "UseTouchID")
defaults.set(CGFloat.pi, forKey: "Pi")

추가로 문자열, array, Dictionary, date를 저장할 수도 있다.
Swift에서 문자열, 배열, 딕셔너리 는 모두 객체가 아니라 구조체이다.
그러나 UserDefaults는 NSString과 그 친구들을 위해 작성되었기 때문에 이 코드는 작동할 수 있는 것이다.


defaults.set("Paul Hudson", forKey: "Name")
defaults.set(Date(), forKey: "LastRun")


let array = ["Hello", "World"]
defaults.set(array, forKey: "SavedArray")

let dict = ["Name": "Paul", "Country": "UK"]
defaults.set(dict, forKey: "SavedDict")

UserDefaulst에서 값을 읽어올 때 Return타입을 주의깊게 확인하여 무엇을 얻고 있는지 확인해야한다.

  • integer(forKey:) : key값이 존재하면 정수값를 반환하고, 그렇지 않으면 0 반환
  • bool(forKey:) : key값이 존재하면 boolean를 반환하고, 그렇지 않으면 false 반환
  • float(forKey:) : key값이 존재하면 float을 반환하고, 그렇지 않으면 0.0 반환
  • double(forKey:) : key값이 존재하면 double을 반환하고, 그렇지 않으면 0.0 반환
  • object(forKey:) : 어의 데이터 타입에 맞게 조건부로 typecast할 수 있도록 Any?를 반환

반환값을 아는 것은 매우 중요하다,
bool(forKey:)를 사용한 뒤 "false"를 반환받는다면, key가 존재하지 않는다는 의미인가 값이 false라는 의미인가?

가장 귀찮은 것은 object(forKey:)이다.
우리에겐 두 가지 옵션이 있다.

  • As! 를 사용하여 object를 강제 typecast한다.
  • as? 를 사용하여 object를 선택적으로 typecast한다.

만약 as!를 사용하여 object(forKey:)가 nil을 반환하다면, 충돌이 일어나기 때문에 너가 완전 확신하는 것이 아니라면 추천하지 않는다.
as?를 사용하는 것도 옵셔널을 언래핑하고 default값을 부여해야하기 깨문에 귀찮긴 하다.

여기 해결책이 있다. '??' 이렇게 생겼으며, 이름은 nil병합 연산자이다.
이것은 두 가지 일을 한번에 한다.
왼쪽의 object가 옵셔널이고 값이 존재한다면, 옵셔널이 아닌 값으로 언래핑하고,
값이 존재하지 않는다면 오른쪽의 값을 대신 사용한다.

예를 들어, SavedArray라는 키로 저장한 배열을 읽어와보자.


let array = defaults.object(forKey: "SavedArray") as? [String] ?? [string]()

만약 SavedArray 가 존재하고 문자열 배열이라면, array에 들어갈 것이고, 그렇지 않다면 array는 새로운 문자열 배열로 설정될 것이다.

딕셔너리에도 이 방법을 사용할 수 있다.


let dic = defaults.objec(forKey: "SavedDic") as? [String: String] ?? [String: String]()

0개의 댓글