【问题标题】:Swift 5: How can i get data from JSONDecoder().decode?Swift 5:如何从 JSONDecoder().decode 获取数据?
【发布时间】:2020-11-26 11:05:08
【问题描述】:

我从 Google 翻译 API 获得 JSON:

{
    data =     {
        translations =         (
                        {
                detectedSourceLanguage = en;
                translatedText = "\U0434\U0430\U043d\U043d\U044b\U0435";
            }
        );
    };
}

然后我这样做:

     if data != nil && error == nil {
        
        let decoder = JSONDecoder()
        
        do {
        
            let translated = try! decoder.decode(Data.self, from: data!)
            dump(translated)
        } catch {
            print(error)
        }
    }

我拿了这个:

MyVocabulary.JSONTranslator.Data
  ▿ data: MyVocabulary.JSONTranslator.Data.Translations
    ▿ translations: 1 element
      ▿ MyVocabulary.JSONTranslator.Data.Translations.TranslatedText
        - detectedSourceLanguage: "en"
        - translatedText: "Работа"

我的结构:

 struct Data: Codable {
        
        struct Translations: Codable {
            
            struct  TranslatedText: Codable {
                var detectedSourceLanguage: String
                var translatedText: String
                
                enum CodingKeys: String, CodingKey{
                    case detectedSourceLanguage
                    case translatedText
                }
                
                init(from decoder: Decoder) throws {
                    let container = try decoder.container(keyedBy: CodingKeys.self)
                    self.translatedText = try container.decode(String.self, forKey: .translatedText)
                    self.detectedSourceLanguage = try container.decode(String.self, forKey: .detectedSourceLanguage)
                  }
            }
            var translations: ([TranslatedText])
        }
        let data: Translations
    }

如何在解码后从 TranslatedText 获取属性到“do”块中的 var?

【问题讨论】:

    标签: json swift decode jsondecoder


    【解决方案1】:

    主要错误是命名自定义结构 Data,因为它会干扰 Foundation 结构 Data 并且解码 Data.self 失败。

    您不需要自定义初始化程序或 CodingKeys,这 3 个结构就足够了

    struct Root: Decodable {  let data: Translations }
    struct Translations: Decodable { let translations: [TranslatedText] }
    struct TranslatedText: Decodable { let detectedSourceLanguage, translatedText : String }
    

    现在解码Root.self 并得到translatedText,如下所述

    let decoder = JSONDecoder()
    do {
        let translated = try decoder.decode(Root.self, from: data!)
        let translatedText = translated.data.translations.first?.translatedText
        print(translatedText)
    } catch {
        print(error)
    }
    

    【讨论】:

      【解决方案2】:

      您提供的 JSON 无效。我假设您的意思是 JSON 是这样的:

      {
          "data": {
              "translations": [
                      {
                          "detectedSourceLanguage": "en",
                          "translatedText": "\U0434\U0430\U043d\U043d\U044b\U0435"
                      }
              ]
          }
      }
      

      除非您想要自定义 JSON 解码,否则您不必输入 CodingKeys 枚举或 init(from:)。您可以通过让默认解码自动发生来简化它。

      将您的模型修改为:

      struct Response: Codable {
          var data: Data
      }
      
      struct Data: Codable {
          var translations: [Translation]
      }
      
      struct Translation: Codable {
          var detectedSourceLanguage: String
          var translatedText: String
      }
      

      在您的do 块内,您不应强制解开try。您应该将try! 更改为try,这样当尝试失败时,它将触发catch 块。否则如果你使用try!会导致应用崩溃

      do里面你可以说:

      do {
          let response = try decoder.decode(Response.self, from: data!)
          let data = response.data
          let translations = data.translations
          let firstTranslation = translations[0]
          let detectedSourceLanguage = firstTranslation.detectedSourceLanguage
          let translatedText = firstTranslation.translatedText
      }
      

      【讨论】:

      • JSON 不等同于问题中的字典转储。键翻译的值是一个数组。
      • JSON 正是我发布的,如果是你写的会更容易
      • @VovaKotsiubenko 我编辑了我的答案以使翻译成为一个数组。 JSONDecoder 足够强大,可以将对象数组从 JSON 解码为 Array
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多