2017-12-13 99 views
6

मुझे अपने कोडेबल प्रकार को ठीक से डीकोड करने में परेशानी हो रही है। मैंने संबंधित प्रकारों के साथ Codable enums बनाने पर कुछ ट्यूटोरियल पढ़े हैं। मैंने टाइपो, नाम विसंगतियां, या जो कुछ भी खोजा है, लेकिन मैं इसके साथ कुछ भी गलत नहीं खोज सकता। और फिर भी जब भी मैं इन structs (एक परत .. पर डीकोड करने की कोशिश करता हूं .. यह एक एक्सटेंशन में एक परत पर "विशेषता" परिभाषित करता है .. लेकिन परत के सभी अन्य पूर्वनिर्धारित हिस्सों को ठीक से एन/डी-कोड किया जा रहा है), मैंने हिट किया decode(from decoder:) विधि में एक "कुंजी नहीं मिली" अपवाद।एनम (संबंधित प्रकार के साथ) कोडेबल बनाएं, सफलतापूर्वक

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 
     } 
    } 
} 

उत्तर

1

मैं आपको पहले की जाँच करनी चाहिए एक महत्वपूर्ण नहीं विकोडक के कंटेनर में मौजूद है या इसे डीकोड से पहले, चाहे लगता है।

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) 
} 

कोई रास्ता नहीं है कि डिकोडर कंटेनर वहाँ में सभी तीन कुंजी जा रहा है नहीं है, ऐसा नहीं है: वर्तमान में आप यह कर रहे हैं?

तो, डिकोडिंग से पहले की जाँच करें:

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

हाँ मुख्य बात यह है कि मैं 'स्वयं के बाद वापस नहीं कर रहा था = ...' मैं स्विफ्ट परोक्ष आरंभीकरण के बाद रिटर्न मान लिया, लेकिन मैं गलत था। रिटर्न के बिना मेरा मूल कोड काम करता है हालांकि मैं आपके सुधारों से सहमत हूं। मुझे यह भी नहीं पता था कि 'values.decode' ने एक सामान्य संग्रह लौटाया जिस पर आप' .contains 'जैसे सरल संचालन कर सकते थे –

संबंधित मुद्दे