2017-12-13 112 views
6

Tôi gặp sự cố khi nhận được loại Codable để giải mã đúng cách. Tôi đã đọc một số hướng dẫn về cách tạo các loại enum có các loại liên quan Codable. Tôi đã tìm kiếm lỗi chính tả, tên không phù hợp, hoặc bất cứ điều gì nhưng tôi không thể phát hiện ra bất cứ điều gì sai trái với điều này. Và bất cứ khi nào tôi cố gắng giải mã trên các cấu trúc này (một Layer .. điều này định nghĩa một thuộc tính "" trên một lớp trong phần mở rộng .. nhưng tất cả các phần khác được xác định trước của Layer đang được en/de-coded đúng), tôi nhấn ngoại lệ "không tìm thấy khóa" trong phương thức decode(from decoder:).Tạo Enum (có loại liên quan) Có thể mã hóa thành công

extension Layer { 

    struct Attribute: Codable { 

     enum Value: Codable { 

      case pulse(Double) 
      case flash(Double) 
      case draw(Double) 

      private enum CodingKeys: String, CodingKey { 
       case pulse, flash, draw 
      } 

      func encode(to encoder: Encoder) throws { 

       var container = encoder.container(keyedBy: CodingKeys.self) 

       switch self { 
       case .pulse(let value): 
        try container.encode(value, forKey: .pulse) 
       case .flash(let value): 
        try container.encode(value, forKey: .flash) 
       case .draw(let value): 
        try container.encode(value, forKey: .draw) 
       } 
      } 

      init(from decoder: Decoder) throws { 

       let values = try decoder.container(keyedBy: CodingKeys.self) 

       do { 
        let value = try values.decode(Double.self, forKey: .pulse) 
        self = .pulse(value) 
       } catch (let error) { 
        print(error) 
       } 

       do { 
        let value = try values.decode(Double.self, forKey: .draw) 
        self = .draw(value) 
       } catch (let error) { 
        print(error) 
       } 

       do { 
        let value = try values.decode(Double.self, forKey: .flash) 
        self = .flash(value) 
       } catch (let error) { 
        print(error) 
       } 

       self = .draw(0.0) 
      } 


     } 

     var value: Value 

     init(value: Value) { 
      self.value = value 
     } 
    } 
} 

Trả lời

1

Tôi nghĩ trước hết bạn nên kiểm tra xem khóa có tồn tại trong vùng chứa bộ giải mã hay không, trước khi giải mã. Hiện tại, bạn đang thực hiện việc này:

do { 
    let value = try values.decode(Double.self, forKey: .pulse) 
    self = .pulse(value) 
} catch (let error) { 
    print(error) 
} 

do { 
    let value = try values.decode(Double.self, forKey: .draw) 
    self = .draw(value) 
} catch (let error) { 
    print(error) 
} 

do { 
    let value = try values.decode(Double.self, forKey: .flash) 
    self = .flash(value) 
} catch (let error) { 
    print(error) 
} 

Không có cách nào mà bộ giải mã sẽ có cả ba khóa trong đó, phải không?

Vì vậy, kiểm tra trước khi giải mã:

if values.contains(.pulse) { 
    do { 
     let value = try values.decode(Double.self, forKey: .pulse) 
     self = .pulse(value) 
     return // remember to return here, so you don't set self back to .draw(0.0) again! 
    } catch (let error) { 
     print(error) 
    } 
} else if values.contains(.draw) { 
    do { 
     let value = try values.decode(Double.self, forKey: .draw) 
     self = .draw(value) 
     return 
    } catch (let error) { 
     print(error) 
    } 
} else if values.contains(.flash) { 
    do { 
     let value = try values.decode(Double.self, forKey: .flash) 
     self = .flash(value) 
     return 
    } catch (let error) { 
     print(error) 
    } 
} 
+0

vâng điều chủ yếu là tôi đã không trở về sau 'tự = ... 'i giả Swift ngầm trả về sau khi khởi nhưng tôi đã sai. mà không có trả về mã ban đầu của tôi hoạt động mặc dù tôi đồng ý với các cải tiến của bạn. Tôi cũng không biết rằng 'values.decode' trả về một bộ sưu tập bình thường mà bạn có thể thực hiện các thao tác đơn giản như' .contains' –

Các vấn đề liên quan