기술나눔

Swift는 Codable 프로토콜을 기반으로 사용됩니다.

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Codable 프로토콜은 Decodable 및 Encodable을 상속합니다.

//
// Test1.swift
// 테스트데모
//
// 2024/7/9에 admin이 생성했습니다.
//

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
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

//Codable은 Decodable과 Encodable을 상속받습니다.
/*

Codable은 객체 직렬화 및 역직렬화를 단순화하기 위한 Swift의 프로토콜 조합입니다. 이는 각각 객체를 외부 표현(예: JSON)으로 인코딩하고 객체를 디코딩하는 데 사용되는 Encodable 및 Decodeable로 구성됩니다. Codable을 구현하면 사용자 정의 유형을 JSON과 같은 형식으로 쉽게 변환할 수 있습니다.

*/

extension Player:Codable{
    /*
     如果 JSON 中的键与结构体中的属性名称不一致,可以使用 CodingKeys 枚举来定义自定义的键映射
     */
    enum CodingKeys:String,CodingKey{
        case name
        case highScore
        case address
        case birthday
        case history = "history1"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

/*
Codable은 중첩 유형에서도 작동합니다.
*/

struct Address:Codable{
    var street:String
    var citty:String
    var zipCode:String
}
  • 1
  • 2
  • 3
  • 4
  • 5
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)")
    
    
    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59



  • 1
  • 2
  • 3