[ios] userDefaults를 이용한structure 타입 Data 저장하기

감자·2020년 9월 28일
2

ios

목록 보기
4/9

why?

->
프로젝트를 진행하던중 기본적인 user의 데이터를 저장해야해서 userDefault를 활용했다.(굳이 coreData를 이용할 일이 없어서 사용할 지 않았다.)

what?

->
1. userDefaults??, coreData??
기본적으로 개발을 할 때 데이터를 영구적으로 보관하기 위해서는 서버를 이용하는 방법, coreData를 이용하는 방법, userDefaults를 이용하는 방법이 있다.(userDefaults는 앱 삭제시 데이터가 삭제되기 때문에 완전 영구적이라고 말할 수 는 없다!! ) 이 세가지 방법 중 오늘은 userDefaults에 대해서 다루겠다. (coreData는 이후에 다룰 일이 있으면 글을 작성할 예정이다.)

  1. userDefaults가 뭐야?

    애플 문서에서 설명하는 것과 같이 앱을 런칭한 후 key-value 쌍의 데이터를 저장할 수 있는 인터페이스를 의미한다.
    이런 userDefaults는 float, double, integer 및 boolean과 같은 타입의 데이터를 저장하는 메소드를 제공할 뿐만아니라, NSData, NSString, NSNumber, NSDate, NSArray 또는 NSDictionary 타입도 저장할 수 있다.
    그러나 사용자 정의 객체를 저장하거나 불러오고싶을 때는 NSKeyedArchiver(NSKeyedUnarchiver), codable을 활용해야한다

    오늘은 기본적인 userDefault의 활용이 아닌 NSKeyedArchiver(NSKeyedUnarchiver), codable을 활용하는 방법의 차이점에 대해서 정리하고, codable을 이용하여 사용자 정의 객체를 저장하고 불러오는 방법에 대해서 초점을 맞추어 글을 작성할 예정이다.

  2. NSCoding(아카이빙?, 언아카이빙?), NSKeyedArchiver(NSKeyedUnarchiver)

  • 아카이빙?

    ios환경에서 아카이빙이란 객체를 파일에 저장할 수 있는 형태로 인코딩하는 행위를 말한다. 그리고 실제 이런 아카이빙이 가능하게 도와주는 것이 NSkeyedArchiver클래스이다.
    NSkeyedArchiver클래스를 이용하면 객체를 파일에 저장할 수 있는 바이너리 프로퍼티 리스트 형태로 인코딩하게 된다.

  • 언아카이빙?

    아카이빙하여 파일에 저장한 데이터를 다시 객체 형태로 디코딩하는 행위를 언아카이빙이라고 한다. 그리고 이를 위해서는 NSKeyedUnarchiver라는 클래스를 이용하여 파일에 저장된 바이너리 프로퍼티 리스트 형태의 데이터를 다시 객체로 디코딩하는 과정을 거치게된다.

  • 실제 사용법
    오늘은 NSKeyedArchiver(NSKeyedUnarchiver)이용한 방법을 다룰 예정이 아니기 때문에 아래 참고 블로그의 글을 인용하겠다 :)
    https://lemon-dev.tistory.com/entry/NSUserDefaults

  1. codable
    위에 참고 블로그를 보면 class를 이용하여 사용자 객체를 만들고 그것을 아카이빙, 언아카이빙 하기위해서는 NSCoding프로토콜을 채택하고, NSObject를 상속하여야한다. 그리고 모든 프로퍼티들에 대해 인코딩, 디코딩 설정을 해줘야하는 번거로운이 존재한다.
    그러나 codable프로토콜을 이용하면 조금 더 쉽게 프로퍼티 리스트에 값을 저장할 수 있다.

    Decodable은 Ecodable과 Decodable로 이뤄져있는데 econdale은 말 그래도 데이터를 인코드하는 용도로 사용하고 decodable은 디코딩하는데 사용한다 swift에서는 int, float등과 같은 타입 이외에도 array, dictionary들 또한 codable프로토콜을 기본적으로 채택하고 있다. 그러나 struct, class와 같은 사용자 정의 객체는 별도로 codable프로토콜을 채택해야한다. 사실 codable프로토콜은 사용자 객체를 프로퍼티 리스트에 저장하기위해서 userDefaults와 혼합하여 사용하는 것보다 JsonData를 다룰 때 더 많이 사용한다.

how?

->

  1. 사용자 객체 정의 및 userDefatults를 이용해서 프로퍼티 리스트 타입으로 저장하기
enum userDefaultsKeys : String {
    case profileImage
    case userInfo
}

struct userInfo: Codable{
    var email : String!
    var name :  String!
    var gender : String!
    var classes : String!
    var location: String!
    var Anonymity : Bool!
}

extension AppDelegate{
    func setUserInfo(){
        DispatchQueue.global().async {
            var user = userInfo(email: "ynwa3690@gmail.com", name: "김재석", gender: "남자", classes: "일반학생", location: "서울 특별시", Anonymity: true)
            var propertyListEncoder = try? PropertyListEncoder().encode(user)
            var userCoreData = UserDefaults.standard
            userCoreData.set(propertyListEncoder, forKey: userDefaultsKeys.userInfo.rawValue)
            userCoreData.synchronize()
        }
    }
}

위와 같이 userDefaults를 이용하여 프로퍼티리스트 형태로 저장할 사용자 객체를 정의하고 PropertyListEncoder().encode()를 이용해서 바이너리 프로퍼티 리스트 형태로 인코딩하여 저장한다.

  1. 저장된 프로퍼티 리스트 형태의 데이터를 다시 객체로 디코딩하고 사용하기
extension ProfileBasicViewController{
    func setUerInfo(){
        // userDefault에 저장된 데이터 뽑아오는 로직 작성
        if UserDefaults.standard.object(forKey: userDefaultsKeys.userInfo.rawValue) != nil{
            if let data = UserDefaults.standard.value(forKey: userDefaultsKeys.userInfo.rawValue) as? Data{
                let decoderUserInfo = try? PropertyListDecoder().decode(userInfo.self, from: data)
                self.user = decoderUserInfo
                print(decoderUserInfo)
            }
        }
//        self.user = UserDefaults.standard.object(forKey: "userInfo") as? userInfo
//        DispatchQueue.main.async {
//            self.tableViewToUserInfo.reloadData()
//            print(self.user)
//        }
    }
    
}

위와 같이 작성하고 userDefaults에 저장된 값을 확인하기 위해서 출력된결과를 보면 아래 그림와 같이 정상적으로 잘 출력된다.

finish

->

  • 어렴풋하게 알던 아카이빙과 언아카이빙의 개념을 확실히 알게되어서 좋았다.
  • 다음에 coreData를 활용할 일이 있으면 coreData에 대해서도 정리해봐야할 필용성을 느꼈다.

0개의 댓글