>

수 기본적 Decodable  프로토콜은 변경없이 JSON 값을 객체 값으로 변환합니다. 그러나 때로는 JSON 디코딩 중에 값을 변환해야합니다 (예 : JSON에서는 {id = "id10"} 가 나타납니다)  그러나 수업 인스턴스에는 숫자 10 를 넣어야합니다.  재산 id 에  (또는 다른 이름의 부동산까지).

init(from:) 메소드를 구현할 수 있습니다  다음과 같은 값으로 원하는 것을 수행 할 수 있습니다.

public required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    latitude = try container.decode(Double.self, forKey:.latitude)
    longitude = try container.decode(Double.self, forKey: .longitude)
    // and for example there i can transform string "id10" to number 10
    // and put it into desired field
}

나에게 큰 소리로 들리지만 JSON 필드의하나만값을 변경하고 다른 20 개 필드를 모두 변경없이 남겨 두려면 어떻게해야합니까? init(from:) 의 경우  클래스의 20 개 필드마다 수동으로 값을 가져와야합니다! 수년간의 objC 코딩 후 슈퍼의 init(from:) 구현을 처음 호출하는 것은 직관적입니다.  그런 다음 일부 필드 만 변경하면 Swift 및 Decodable 를 통해 어떻게 이러한 효과를 얻을 수 있습니까?  프로토콜?

  • 답변 # 1

    lazy var 를 사용할 수 있습니다 . 단점은 여전히 ​​키 목록을 제공해야하며 모델을 상수로 선언 할 수 없다는 것입니다.

    struct MyModel: Decodable {
        lazy var id: Int = {
            return Int(_id.replacingOccurrences(of: "id", with: ""))!
        }()
        private var _id: String
        var latitude: CGFloat
        var longitude: CGFloat
        enum CodingKeys: String, CodingKey {
            case latitude, longitude
            case _id = "id"
        }
    }
    
    

    예 :

    let json = """
    {
        "id": "id10",
        "latitude": 1,
        "longitude": 1
    }
    """.data(using: .utf8)!
    // Can't use a `let` here
    var m = try JSONDecoder().decode(MyModel.self, from: json)
    print(m.id)
    
    

  • 이전 encryption - 사용자 정의 인코딩 알고리즘으로 인증서 생성
  • 다음 파이썬 27에서 오류