[iOS] 사용자 지정 클래스를 Data 형식으로 변환(UserDefaults에 사용자 지정 클래스의 배열 저장)

(코멘트에서 @ObuchiYuki씨의 지적에도 있습니다만,)
이 기사의 내용은 오래되었으며 현재라면 Codable를 사용하기가 쉽습니다.

다음은 예입니다.

저장할 맞춤 클래스
struct Item: Codable {
    let id: Int
    let name: String
}

저장 처리
func saveItems(items: [Item]) {
    let data = items.map { try! JSONEncoder().encode($0) }
    userDefaults.set(data as [Any], forKey: "キー名")
}


읽기 처리

func readItems() -> [Item]? {
    guard let items = userDefaults.array(forKey: "キー名") as? [Data] else { return [Item]() }

    let decodedItems = items.map { try! JSONDecoder().decode(Item.self, from: $0) }
    return decodedItems
}

커스텀 클래스를 Data 타입으로 변환할 필요성



예를 들어 UserDefaults를 사용하는 경우 사용자 지정 개체를 NSData로 변환해야합니다 :)

왜냐하면, UserDefaults로 보존할 수 있는 형태는 NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary 가 되어 있기 때문입니다.

이것 이외의 형태를 보관 유지하고 싶은 경우는 일단 NSData형으로 변환하고 나서 보관 유지해, 읽어들일 때는 NSData형으로서 읽어들인 후에 형 변환을 실시할 필요가 있습니다.

이하에서는 「UserDefaults에서 커스텀 클래스의 배열을 보존, 로드한다」라고 하는 구체적인 경우로, Swift4로 커스텀 클래스를 Data형으로 변환하는 처리를 살펴볼 것입니다😄

흐름



iOS에서는 시리얼라이즈를 아카이브, 디시리얼라이즈를 아카이브라고 합니다.
아카이브를 위한 클래스로서 NSKeyedArchiver 클래스
언아카이브를 위한 클래스로서 NSKeyedUnarchiver 클래스가 있습니다.



UserDefaults에 커스텀 클래스의 배열을 저장, 로드



먼저, 사용자가 직접 만들 사용자 정의 클래스를 정의합니다.

<포인트>
NSObject, NSCoding 상속
인코딩, 디코딩 처리 기술
class SomeObj: NSObject, NSCoding {

    var word: String!
    var date: String!

    init(word: String, date: String) {
        self.word = word
        self.date = date
    }

    required init?(coder aDecoder: NSCoder) {
        self.word = aDecoder.decodeObject(forKey: "word") as! String
        self.date = aDecoder.decodeObject(forKey: "date") as! String
    }

    func encode(with aCoder: NSCoder) {
        if let word = word { aCoder.encode(word, forKey: "word") }
        if let date = date { aCoder.encode(date, forKey: "date") }
    }
}


저장 처리에는 NSKeyedArchiver.archivedData

var someObjArray = [SomeObj]()
let someObj = SomeObj(word: "hoge", date: "2000/01/01")

someObjArray.insert(someObj, at: 0) 

UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: someObjArray), forKey: "someObjs")


로드 프로세스는 데이터 형식으로 한 번 읽은 것을 NSKeyedUnarchiver.unarchiveObjec

func loadSomeObjs() -> [someObj]?{
        if let loadedData = UserDefaults().data(forKey: "someObjs") {
            let someObjs = NSKeyedUnarchiver.unarchiveObject(with: loadedData) as! [SomeObj]
            return someObjs
        }else {
            return nil
        }
}


이제 UserDefaults에 사용자 정의 클래스의 배열을 저장하고 로드할 수 있습니다!

좋은 웹페이지 즐겨찾기