Swift 5:如何从 JSONDecoder().decode 获取数据?
Posted
技术标签:
【中文标题】Swift 5:如何从 JSONDecoder().decode 获取数据?【英文标题】:Swift 5: How can i get data from 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?
【问题讨论】:
【参考方案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
以上是关于Swift 5:如何从 JSONDecoder().decode 获取数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何准备 API 响应以在 swift 中与 jsonDecoder 一起使用
如何在 swift 中使用 JSONDecoder 输入调整?
Swift - 使用 JSONDecoder 解码 JSON 数据
Swift4 JSONDecoder 期望解码 Dictionary<String, Any> 但找到了一个数组 [重复]