Codable协议 继承自 Decodable & Encodable
//
// Test1.swift
// TestDemo
//
// Created by admin on 2024/7/9.
//
import Foundation
struct Player{
var name:String
var highScore:Int = 0
var history:[Int] = []
var address:Address?
var birthday:Date?
init(name: String) {
self.name = name
}
}
extension Player{
mutating func updateScore(_ newScore:Int){
history.append(newScore)
if(highScore < newScore){
highScore = newScore
}
}
}
//Codable 继承自 Decodable & Encodable
/*
Codable 是 Swift 中用于简化对象序列化和反序列化的协议组合。它由 Encodable 和 Decodable 组成,分别用于将对象编码为外部表示(如 JSON)和从外部表示解码对象。通过实现 Codable,我们可以轻松地将自定义类型与 JSON 等格式进行转换。
*/
extension Player:Codable{
/*
如果 JSON 中的键与结构体中的属性名称不一致,可以使用 CodingKeys 枚举来定义自定义的键映射
*/
enum CodingKeys:String,CodingKey{
case name
case highScore
case address
case birthday
case history = "history1"
}
}
/*
Codable 同样适用于嵌套类型
*/
struct Address:Codable{
var street:String
var citty:String
var zipCode:String
}
func test111(){
var player = Player(name: "John")
player.address = Address(street: "宝田一路", citty: "深圳", zipCode: "2212")
player.birthday = Date(timeIntervalSince1970: 25 * 365 * 24 * 60 * 60)
player.updateScore(121)
player.updateScore(134)
/*
默认情况下,JSONEncoder 和 JSONDecoder 对日期的处理方式可能不符合需求,可以自定义日期格式
*/
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .formatted(formatter)
let jsonData = try? encoder.encode(player)
guard let jsonData = jsonData else{
print("json data is nil")
return
}
let jsonStr = String(data: jsonData, encoding: .utf8)
guard let jsonStr = jsonStr else{
print("json 数据编码失败")
return
}
print("player 转json 字符串 : " + jsonStr)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
guard let jsonDataDe = jsonStr.data(using: .utf8) else {
print("json DataDe is null")
return
}
//解码异常处理和打印
var user :Player?
do {
user = try decoder.decode(Player.self, from: jsonDataDe)
} catch let DecodingError.dataCorrupted(context) {
print(context)
} catch let DecodingError.keyNotFound(key, context) {
print("Key '\(key)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch let DecodingError.valueNotFound(value, context) {
print("Value '\(value)' not found:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch let DecodingError.typeMismatch(type, context) {
print("Type '\(type)' mismatch:", context.debugDescription)
print("codingPath:", context.codingPath)
} catch {
print("Error: ", error)
}
guard let user = user else{
print("user is null")
return
}
print("name:" + user.name + ",score:" + "\(user.highScore)")
}