protocol Saveable: Codable {
func save(key: String)
static func load(key: String) -> Self?
}
extension Saveable {
func save(key: String) {
do {
let data = try JSONEncoder().encode(self)
UserDefaults.standard.set(data, forKey: key)
} catch let error {
print(error)
}
}
static func load(key: String) -> Self? {
guard let data = UserDefaults.standard.data(forKey: key) else {
return nil
}
do {
return try JSONDecoder().decode(Self.self, from: data)
} catch let error {
print(error)
return nil
}
}
}
// Usage
struct User: Saveable {
let id: Int
let name: String
let address: String
}
let key = "user"
let user = User(id: 0, name: "name", address: "address")
user.save(key: key)
let user_ = User.load(key: key)
protocol Dictionaryable: Codable {
func encode() -> [String: Any]?
static func decode(dictionary:[String: Any]) -> Self?
}
extension Dictionaryable {
func encode() -> [String: Any]? {
do {
let data = try JSONEncoder().encode(self)
return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
} catch let error {
print(error)
return nil
}
}
static func decode(dictionary:[String: Any]) -> Self? {
do {
let data = try JSONSerialization.data(withJSONObject: dictionary, options: [])
return try JSONDecoder().decode(Self.self, from: data)
} catch let error {
print(error)
return nil
}
}
}
// Usage
struct User: Dictionaryable {
let id: Int
let name: String
let address: String
}
let dictionary: [String: Any] = ["id": 0, "name": "name", "address": "address"]
let user = User.decode(dictionary: dictionary)
let user_ = User(id: 0, name: "name", address: "address")
let dictionary_ = user_.encode()
struct User: Codable {
let id: Int
let name: String
let address: String
}
let data = """
{
"id":0,
"name": "name",
"address": "address"
}
""".data(using: .utf8)!
// Decode
do {
let user = try JSONDecoder().decode(User.self, from: data)
} catch { }
// encode
do {
let user = try JSONDecoder().decode(User.self, from: data)
let data = try JSONEncoder().encode(user)
let json = String(data: data, encoding: .utf8)!
} catch { }
// property type and type of value are different
struct User: Codable {
let id: Int
}
let data = "{"id":"id"}".data(using: .utf8)!
do {
let user = try JSONDecoder().decode(User.self, from: data)
} catch let error {
print(error) // typeMismatch
}
// Key not found property name
struct User: Codable {
let id: Int
}
let data = "{"user_id":0}".data(using: .utf8)!
do {
let user = try JSONDecoder().decode(User.self, from: data)
} catch let error {
print(error) // keyNotFound
}
// Success
// property type change to Optional type
struct User: Codable {
let id: Int?
}
let data = "{"user_id":0}".data(using: .utf8)!
do {
let user = try JSONDecoder().decode(User.self, from: data)
} catch let error {
print(error)
}
// When property name and key are different
let data = """
{
"user_id":0,
"user_name": "name",
"mail-address": "address"
}
""".data(using: .utf8)!
struct User: Codable {
let id: Int
let name: String
let address: String
enum CodingKeys: String, CodingKey {
case id = "user_id"
case name = "user_name"
case address = "mail-address"
}
}