iOS

[ iOS ] UserDefaults - ์ปค์Šคํ…€ ํƒ€์ž… ์ €์žฅํ•˜๊ธฐ (Attempt to insert non-property list object ์˜ค๋ฅ˜)

Forest Yun 2023. 1. 21. 23:20
728x90

 

 

UserDefaults์™€ non-property list ์˜ค๋ฅ˜

UserDefaults๋Š” Float, Double, Int, URL ๋“ฑ ๊ธฐ๋ณธ ํƒ€์ž…์— ๋Œ€ํ•œ ํŽธ๋ฆฌํ•œ ๋ฉ”์„œ๋“œ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary ํƒ€์ž…์ด๋ผ๋ฉด UserDefaults์— ์ž์œ ๋กญ๊ฒŒ ์ €์žฅ ๋ฐ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ์—๋Š” ๋ณดํ†ต ์•„๋ž˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด ์ปค์Šคํ…€ํ•œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•œ๋‹ค. 

struct User {
   let name: String
   let age: String
}

 

์ด ์ปค์Šคํ…€ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด UserDefaults์— ์ €์žฅํ•ด๋ณด์ž.

let user = User(name: "์‚ฌ์šฉ์ž", age: "12")

Userdeafaults.standard.setValue(user, forKey: "userSave")

 

 

์•„์‰ฝ๊ฒŒ๋„ UserDefaults๋Š” NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary ๋“ฑ standard ํƒ€์ž…์ด ์•„๋‹ˆ๋ฉด ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์—†์œผ๋ฉฐ, ์•„๋ž˜์˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

"Attempt to insert non-property list object ํŒŒ์ผ๋ช….User(~~) for key userSave "

์—ฌ๊ธฐ์„œ Property list๋Š” ๊ฐ์ฒด ์ง๋ ฌํ™”๋ฅผ ์œ„ํ•œ ํŒŒ์ผ์ด๋‹ค. plist๋ผ๋Š” ํ™•์žฅ์ž๋ฅผ ๊ฐ€์ง€๋ฉฐ ์šฐ๋ฆฌ๊ฐ€ ์•„๋Š” info.plist๊ฐ€ ๋ฐ”๋กœ property list์ด๋‹ค.

์ฆ‰ ์œ„์˜ ์ € ์˜ค๋ฅ˜๋Š” ๊ฐ์ฒด ์ง๋ ฌํ™” ํŒŒ์ผ์ด ์•„๋‹Œ User ๊ฐ์ฒด๋ฅผ UserDefaults์— ์ €์žฅํ•˜๋ ค ํ•ด์„œ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜์ด๋‹ค.

 

 

UserDefaults์˜ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด, UserDefaults๋Š”  property list ์—ฌ์•ผ ํ•œ๋‹ค๊ณ  ๋‚˜์™€์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Apple์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ปค์Šคํ…€ํ•œ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ UserDefaults์— ํ• ๋‹นํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ๊ฐ์ฒด๋ฅผ NSData ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ NSData๋Š” property list ํƒ€์ž… ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์šฐ๋ฆฌ๋Š” Object-C ๊ด€๋ จํ•œ ์ฝ”๋“œ๊ฐ€ ์—†์œผ๋ฏ€๋กœ Data ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด๋ณด์ž.

default ๊ฐ์ฒด๋Š” NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary์˜ ์ธ์Šคํ„ด์Šค์™€ ๊ฐ™์€  property list๊ฐ€ ๋˜์–ด์•ผํ•œ๋‹ค. (๋˜๋Š” ์ปฌ๋ ‰์…˜ ํƒ€์ž…์ธ ๊ฒฝ์šฐ ์ธ์Šคํ„ด์Šค์˜ ์กฐํ•ฉ์ด์–ด์•ผ ํ•œ๋‹ค.)
 ๋งŒ์•ฝ ๋‹ค๋ฅธ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด, ๊ฐ์ฒด๋ฅผ NSData ์ธ์Šคํ„ด์Šค๋กœ ๋งŒ๋“ค์–ด ๋ณด๊ด€ํ•ด์•ผ ํ•œ๋‹ค.

 

 

 

๋“ค์–ด๊ฐ€๊ธฐ ์ „ Serializarion ๊ณต๋ถ€ํ•˜๊ธฐ

 

[ Swift ] Serialization์ด๋ž€?

๊ฒ€์ƒ‰์„ ํ†ตํ•ด ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ถ€์ •ํ™•ํ•  ์ˆ˜๋„ ์žˆ๊ณ  ์ถ”ํ›„ ์ถ”๊ฐ€ ๊ณต๋ถ€๋ฅผ ํ†ตํ•ด ๋‚ด์šฉ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Serialization์ด๋ž€? Serializtion์„ ๋ฒˆ์—ญํ•˜๋ฉด '์ง๋ ฌํ™”'์ด๋‹ค. ์ง๋ ฌํ™”๋ž€ ๊ฐ„

88yhtserof.tistory.com

 

 

 

 

 

์ปค์Šคํ…€ ๊ฐ์ฒด๋ฅผ Serializarionํ•˜๊ธฐ

์ด์™€ ๊ด€๋ จํ•œ Apple์˜ ๊ณต์‹๋ฌธ์„œ Archives and Serialization ๋ฅผ ๋ณด๋ฉด, serializarion์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Encoder์™€ Decoder API๋“ค์„ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ๋‚˜์™€์žˆ๋‹ค.

์•ฑ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด ํƒ€์ž…์„ ์ž…์ถœ๋ ฅ๊ณผ ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•œ ์ง๋ ฌํ™”(Serialization) ๋˜๋Š” ์žฅ๊ธฐ๊ฐ„์˜ ์ €์žฅ์— ์ ํ•ฉํ•œ ํ‘œํ˜„์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ์ด API๋“ค์„ ์‚ฌ์šฉํ•˜๋ผ.
 
Swift์—์„œ, standard ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” Encodable, Decodable๊ณผ Codable ํƒ€์ž…๋“ค(Int, String ๋“ฑ)์„ ์ •์˜ํ•˜๊ณ , ๋ง๋ถ™์—ฌ 'Encoding, Decoding, and Serialization'์—์„œ ์„ค๋ช…๋˜์–ด์žˆ๋“ฏ์ด encoding๊ณผ decoding์„ ์ˆ˜ํ–‰ํ•˜๋Š” Encoder์™€ Decoder APIs๋ฅผ ์ •์˜ํ•œ๋‹ค. 

 

 

๊ทธ๋Ÿผ ์ปค์Šคํ…€ ๊ฐ์ฒด์— Encoder, Decoder๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ”๋กœ Serialization์„ ํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์•„์‰ฝ์ง€๋งŒ ์ปค์Šคํ…€ ํƒ€์ž…๋Š” standard ํƒ€์ž…๋“ค๊ณผ ๋‹ค๋ฅด๊ฒŒ Codableํ•˜์ง€ ์•Š๋‹ค. ๋”ฐ๋ผ์„œ ์„ ์–ธ๋ถ€์˜ ์ƒ์† ๋ชฉ๋ก์— Codable์„ ์ฑ„ํƒํ•ด์คŒ์œผ๋กœ์จ Codableํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ์ž. ๋งŒ์•ฝ decoding์ด ํ•„์š”์—†๋Š” ์ปค์Šคํ…€ ํƒ€์ž…๋ผ๋ฉด Encodable์„, encoding์ด ํ•„์š”์—†๋Š” ์ปค์Šคํ…€ ํƒ€์ž…์ด๋ผ๋ฉด Decodable์„ ๋ช…์‹œํ•˜์ž. Apple์˜ ๊ณต์‹๋ฌธ์„œ์ธ Encoding and Decoding Custom Types ๋ฅผ ๋ณด๋ฉด ์˜ˆ์‹œ๊ฐ€ ์ž˜ ๋‚˜์™€์žˆ๋‹ค.

struct Coordinate: Codable {    
    var latitude: Double    
    var longitude: Double
}

struct Landmark: Codable {    
    // Double, String, and Int all conform to Codable.    
    var name: String    
    var foundingYear: Int
    
    // Adding a property of a custom Codable type maintains overall Codable conformance.    
    var location: Coordinate
}

 

 

์ปค์Šคํ…€ ํƒ€์ž…์ด ์ด์ œ Codableํ•˜๋‹ˆ Endcoder๋ฅผ ํ†ตํ•ด ์ปค์Šคํ…€ ๊ฐ์ฒด๋ฅผ Data ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ฐจ๋ก€์ด๋‹ค. Encoder ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” class ์ค‘ PropertyListEncoder๊ฐ€ ์žˆ๋‹ค. ์•„๋ž˜์˜ encode ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Data ํƒ€์ž…์„ ๋ฐ˜ํ™˜๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ JSON ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ํ•  ๊ณ„ํš์ด๋ผ๋ฉด JSONEncoder๋ฅผ ํ†ตํ•ด Serializarion ํ•ด์ค„ ์ˆ˜๋„ ์žˆ๋‹ค.

func encode<Value>(_ value: Value) throws -> Data where Value : Encodable

 

 

์ปค์Šคํ…€ ๊ฐ์ฒด๋ฅผ Serializionํ•ด UserDefaults์— ์ €์žฅํ•˜๊ณ  ๊บผ๋‚ด์˜ค๊ธฐ ์˜ˆ์‹œ

struct MessageModel: Codable {
    let text: String
}

let message = MessageModel(text: "์ €์žฅํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์Šต๋‹ˆ๋‹ค.")
let userDefault = UserDefaults.standard

//UserDefaults์— ์ €์žฅํ•˜๊ธฐ
let pEncoder = PropertyListEncoder()
let encodedData = try? pEncoder.encode(message)
userDefault.set(encodedData, forKey: "BlogTestEx_PropertyListEncoder")

//UserDefaults์—์„œ ๊บผ๋‚ด์˜ค๊ธฐ
let userData = userDefault.object(forKey: "BlogTestEx_PropertyListEncoder")
guard let object = userData as? Data else { return }
        
let pDecoder = PropertyListDecoder()
let decodedData = try? pDecoder.decode(MessageModel.self, from: object)
if let message = decodedData {
    self.textLabel.text = message.text
}

 

 

 

 

 

728x90