在 Swift 3 中正确解析 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39423367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Correctly Parsing JSON in Swift 3
提问by user2563039
I'm trying to fetch a JSON response and store the results in a variable. I've had versions of this code work in previous releases of Swift, until the GM version of Xcode 8 was released. I had a look at a few similar posts on StackOverflow: Swift 2 Parsing JSON - Cannot subscript a value of type 'AnyObject'and JSON Parsing in Swift 3.
我正在尝试获取 JSON 响应并将结果存储在变量中。在 Xcode 8 的 GM 版本发布之前,我已经在以前的 Swift 版本中使用了此代码的版本。我在 StackOverflow 上看了一些类似的帖子:Swift 2 Parsing JSON - Cannot subscript a value of type 'AnyObject'and JSON Parsing in Swift 3。
However, it seems the ideas conveyed there do not apply in this scenario.
但是,那里传达的想法似乎不适用于这种情况。
How do I correctly parse the JSON reponse in Swift 3? Has something changed in the way JSON is read in Swift 3?
如何正确解析 Swift 3 中的 JSON 响应?在 Swift 3 中读取 JSON 的方式有什么改变吗?
Below is the code in question (it can be run in a playground):
下面是有问题的代码(它可以在操场上运行):
import Cocoa
let url = "https://api.forecast.io/forecast/apiKey/37.5673776,122.048951"
if let url = NSURL(string: url) {
if let data = try? Data(contentsOf: url as URL) {
do {
let parsedData = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments)
//Store response in NSDictionary for easy access
let dict = parsedData as? NSDictionary
let currentConditions = "\(dict!["currently"]!)"
//This produces an error, Type 'Any' has no subscript members
let currentTemperatureF = ("\(dict!["currently"]!["temperature"]!!)" as NSString).doubleValue
//Display all current conditions from API
print(currentConditions)
//Output the current temperature in Fahrenheit
print(currentTemperatureF)
}
//else throw an error detailing what went wrong
catch let error as NSError {
print("Details of JSON parsing error:\n \(error)")
}
}
}
Edit:Here is a sample of the results from the API call after print(currentConditions)
编辑:以下是 API 调用后的结果示例print(currentConditions)
["icon": partly-cloudy-night, "precipProbability": 0, "pressure": 1015.39, "humidity": 0.75, "precipIntensity": 0, "windSpeed": 6.04, "summary": Partly Cloudy, "ozone": 321.13, "temperature": 49.45, "dewPoint": 41.75, "apparentTemperature": 47, "windBearing": 332, "cloudCover": 0.28, "time": 1480846460]
回答by vadian
First of all never load data synchronously from a remote URL, use always asynchronous methods like URLSession.
首先,永远不要从远程 URL 同步加载数据,始终使用异步方法,例如URLSession.
'Any' has no subscript members
'Any' 没有下标成员
occurs because the compiler has no idea of what type the intermediate objects are (for example currentlyin ["currently"]!["temperature"]) and since you are using Foundation collection types like NSDictionarythe compiler has no idea at all about the type.
发生的原因是编译器不知道中间对象是什么类型(例如currentlyin ["currently"]!["temperature"]),并且由于您使用 Foundation 集合类型,例如NSDictionary编译器根本不知道类型。
Additionally in Swift 3 it's required to inform the compiler about the type of allsubscripted objects.
此外,在 Swift 3 中,需要通知编译器所有下标对象的类型。
You have to cast the result of the JSON serialization to the actual type.
您必须将 JSON 序列化的结果转换为实际类型。
This code uses URLSessionand exclusivelySwift native types
此代码的用途URLSession和专门斯威夫特本地类型
let urlString = "https://api.forecast.io/forecast/apiKey/37.5673776,122.048951"
let url = URL(string: urlString)
URLSession.shared.dataTask(with:url!) { (data, response, error) in
if error != nil {
print(error)
} else {
do {
let parsedData = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
let currentConditions = parsedData["currently"] as! [String:Any]
print(currentConditions)
let currentTemperatureF = currentConditions["temperature"] as! Double
print(currentTemperatureF)
} catch let error as NSError {
print(error)
}
}
}.resume()
To print all key / value pairs of currentConditionsyou could write
要打印currentConditions您可以编写的所有键/值对
let currentConditions = parsedData["currently"] as! [String:Any]
for (key, value) in currentConditions {
print("\(key) - \(value) ")
}
A note regarding jsonObject(with data:
关于jsonObject(with data以下事项的说明:
Many (it seems all) tutorials suggest .mutableContainersor .mutableLeavesoptions which is completely nonsense in Swift. The two options are legacy Objective-C options to assign the result to NSMutable...objects. In Swift any variable is mutable by default and passing any of those options and assigning the result to a letconstant has no effect at all. Further most of the implementations are never mutating the deserialized JSON anyway.
许多(似乎都是)教程建议.mutableContainers或.mutableLeaves选项在 Swift 中完全是无稽之谈。这两个选项是传统的 Objective-C 选项,用于将结果分配给NSMutable...对象。在 Swift 中var,默认情况下任何iable 都是可变的,传递任何这些选项并将结果分配给let常量根本没有任何影响。此外,大多数实现无论如何都不会改变反序列化的 JSON。
The only (rare) option which is useful in Swift is .allowFragmentswhich is required if if the JSON root object could be a value type(String, Number, Boolor null) rather than one of the collection types (arrayor dictionary). But normally omit the optionsparameter which means No options.
.allowFragments如果 JSON 根对象可以是值类型(String, Number, Boolor null)而不是集合类型之一(arrayor dictionary),则唯一(罕见)在 Swift 中有用的选项是必需的。但通常省略options表示No options的参数。
===========================================================================
================================================== ==========================
Some general considerations to parse JSON
解析 JSON 的一些一般注意事项
JSON is a well-arranged text format. It's very easy to read a JSON string. Read the string carefully. There are only six different types –?two collection types and four value types.
JSON 是一种排列整齐的文本格式。读取 JSON 字符串非常容易。仔细阅读字符串。只有六种不同的类型——两种集合类型和四种值类型。
The collection types are
集合类型是
- Array- JSON: objects in square brackets
[]- Swift:[Any]but in most cases[[String:Any]] - Dictionary- JSON: objects in curly braces
{}- Swift:[String:Any]
- 数组- JSON:方括号中的对象
[]- Swift:[Any]但在大多数情况下[[String:Any]] - 字典- JSON:花括号中的对象
{}- Swift:[String:Any]
The value types are
值类型是
- String- JSON: any value in double quotes
"Foo", even"123"or"false"– Swift:String - Number- JSON: numeric values notin double quotes
123or123.0– Swift:IntorDouble - Bool- JSON:
trueorfalsenotin double quotes – Swift:trueorfalse - null- JSON:
null– Swift:NSNull
- 字符串- JSON:双引号中的任何值
"Foo",偶数"123"或"false"– Swift:String - 数字- JSON:数字值不在双引号中
123或123.0- Swift:Int或Double - Bool- JSON:
true或false不在双引号中 - Swift:true或false - null- JSON:
null– Swift:NSNull
According to the JSON specification all keys in dictionaries are required to be String.
根据 JSON 规范,字典中的所有键都必须是String.
Basically it's always recommeded to use optional bindings to unwrap optionals safely
基本上总是建议使用可选绑定来安全地解包可选
If the root object is a dictionary ({}) cast the type to [String:Any]
如果根对象是字典 ( {}) 将类型强制转换为[String:Any]
if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [String:Any] { ...
and retrieve values by keys with (OneOfSupportedJSONTypesis either JSON collection or value type as described above.)
并通过使用 (OneOfSupportedJSONTypes是 JSON 集合或值类型的键检索值,如上所述。)
if let foo = parsedData["foo"] as? OneOfSupportedJSONTypes {
print(foo)
}
If the root object is an array ([]) cast the type to [[String:Any]]
如果根对象是数组 ( []) 则将类型强制转换为[[String:Any]]
if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] { ...
and iterate through the array with
并遍历数组
for item in parsedData {
print(item)
}
If you need an item at specific index check also if the index exists
如果您需要特定索引处的项目,请检查该索引是否存在
if let parsedData = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]], parsedData.count > 2,
let item = parsedData[2] as? OneOfSupportedJSONTypes {
print(item)
}
}
In the rare case that the JSON is simply one of the value types –?rather than a collection type – you have to pass the .allowFragmentsoption and cast the result to the appropriate value type for example
在极少数情况下,JSON 只是值类型之一——而不是集合类型——例如,您必须传递.allowFragments选项并将结果转换为适当的值类型
if let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? String { ...
Apple has published a comprehensive article in the Swift Blog: Working with JSON in Swift
Apple 在 Swift 博客中发表了一篇综合文章:在 Swift 中使用 JSON
===========================================================================
================================================== ==========================
In Swift 4+ the Codableprotocol provides a more convenient way to parse JSON directly into structs / classes.
在 Swift 4+ 中,该Codable协议提供了一种更方便的方法来将 JSON 直接解析为结构/类。
For example the given JSON sample in the question (slightly modified)
例如问题中给定的 JSON 示例(略有修改)
let jsonString = """
{"icon": "partly-cloudy-night", "precipProbability": 0, "pressure": 1015.39, "humidity": 0.75, "precip_intensity": 0, "wind_speed": 6.04, "summary": "Partly Cloudy", "ozone": 321.13, "temperature": 49.45, "dew_point": 41.75, "apparent_temperature": 47, "wind_bearing": 332, "cloud_cover": 0.28, "time": 1480846460}
"""
can be decoded into the struct Weather. The Swift types are the same as described above. There are a few additional options:
可以解码成 struct Weather。Swift 类型与上述相同。还有一些额外的选项:
- Strings representing an
URLcan be decoded directly asURL. - The
timeinteger can be decoded asDatewith thedateDecodingStrategy.secondsSince1970. - snaked_casedJSON keys can be converted to camelCasewith the
keyDecodingStrategy.convertFromSnakeCase
- 表示 an 的字符串
URL可以直接解码为URL。 - 的
time整数可以被解码为Date与所述dateDecodingStrategy.secondsSince1970。 - snaked_casedJSON键可被转化为驼峰与
keyDecodingStrategy.convertFromSnakeCase
struct Weather: Decodable {
let icon, summary: String
let pressure: Double, humidity, windSpeed : Double
let ozone, temperature, dewPoint, cloudCover: Double
let precipProbability, precipIntensity, apparentTemperature, windBearing : Int
let time: Date
}
let data = Data(jsonString.utf8)
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Weather.self, from: data)
print(result)
} catch {
print(error)
}
Other Codable sources:
其他可编码来源:
回答by discorevilo
A big change that happened with Xcode 8 Beta 6 for Swift 3 was that id now imports as Anyrather than AnyObject.
与Xcode中8 Beta中发生了6雨燕3的一大变化是,现在的id进口的Any,而不是AnyObject。
This means that parsedDatais returned as a dictionary of most likely with the type [Any:Any]. Without using a debugger I could not tell you exactly what your cast to NSDictionarywill do but the error you are seeing is because dict!["currently"]!has type Any
这意味着它parsedData作为最有可能类型为 的字典返回[Any:Any]。如果不使用调试器,我无法确切地告诉你你的演员NSDictionary会做什么,但你看到的错误是因为dict!["currently"]!有类型Any
So, how do you solve this? From the way you've referenced it, I assume dict!["currently"]!is a dictionary and so you have many options:
那么,你如何解决这个问题?从你引用它的方式来看,我假设dict!["currently"]!是一本字典,所以你有很多选择:
First you could do something like this:
首先你可以做这样的事情:
let currentConditionsDictionary: [String: AnyObject] = dict!["currently"]! as! [String: AnyObject]
This will give you a dictionary object that you can then query for values and so you can get your temperature like this:
这将为您提供一个字典对象,然后您可以查询该对象的值,这样您就可以获得这样的温度:
let currentTemperatureF = currentConditionsDictionary["temperature"] as! Double
Or if you would prefer you can do it in line:
或者,如果您愿意,可以按顺序进行:
let currentTemperatureF = (dict!["currently"]! as! [String: AnyObject])["temperature"]! as! Double
Hopefully this helps, I'm afraid I have not had time to write a sample app to test it.
希望这会有所帮助,恐怕我没有时间编写示例应用程序来测试它。
One final note: the easiest thing to do, might be to simply cast the JSON payload into [String: AnyObject]right at the start.
最后一个注意事项:最简单的方法可能是在开始时简单地将 JSON 有效负载转换为[String: AnyObject]正确的。
let parsedData = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments) as! Dictionary<String, AnyObject>
回答by BhuShan PaWar
let str = "{\"names\": [\"Bob\", \"Tim\", \"Tina\"]}"
let data = str.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
if let names = json["names"] as? [String]
{
print(names)
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
回答by David Siegel
I built quicktypeexactly for this purpose. Just paste your sample JSON and quicktype generates this type hierarchy for your API data:
我正是为此目的构建了quicktype。只需粘贴您的示例 JSON,然后 quicktype 就会为您的 API 数据生成此类型层次结构:
struct Forecast {
let hourly: Hourly
let daily: Daily
let currently: Currently
let flags: Flags
let longitude: Double
let latitude: Double
let offset: Int
let timezone: String
}
struct Hourly {
let icon: String
let data: [Currently]
let summary: String
}
struct Daily {
let icon: String
let data: [Datum]
let summary: String
}
struct Datum {
let precipIntensityMax: Double
let apparentTemperatureMinTime: Int
let apparentTemperatureLowTime: Int
let apparentTemperatureHighTime: Int
let apparentTemperatureHigh: Double
let apparentTemperatureLow: Double
let apparentTemperatureMaxTime: Int
let apparentTemperatureMax: Double
let apparentTemperatureMin: Double
let icon: String
let dewPoint: Double
let cloudCover: Double
let humidity: Double
let ozone: Double
let moonPhase: Double
let precipIntensity: Double
let temperatureHigh: Double
let pressure: Double
let precipProbability: Double
let precipIntensityMaxTime: Int
let precipType: String?
let sunriseTime: Int
let summary: String
let sunsetTime: Int
let temperatureMax: Double
let time: Int
let temperatureLow: Double
let temperatureHighTime: Int
let temperatureLowTime: Int
let temperatureMin: Double
let temperatureMaxTime: Int
let temperatureMinTime: Int
let uvIndexTime: Int
let windGust: Double
let uvIndex: Int
let windBearing: Int
let windGustTime: Int
let windSpeed: Double
}
struct Currently {
let precipProbability: Double
let humidity: Double
let cloudCover: Double
let apparentTemperature: Double
let dewPoint: Double
let ozone: Double
let icon: String
let precipIntensity: Double
let temperature: Double
let pressure: Double
let precipType: String?
let summary: String
let uvIndex: Int
let windGust: Double
let time: Int
let windBearing: Int
let windSpeed: Double
}
struct Flags {
let sources: [String]
let isdStations: [String]
let units: String
}
It also generates dependency-free marshaling code to coax the return value of JSONSerialization.jsonObjectinto a Forecast, including a convenience constructor that takes a JSON string so you can quickly parse a strongly typed Forecastvalue and access its fields:
它还生成无依赖的封送处理代码以将 的返回值哄骗JSONSerialization.jsonObject到 a 中Forecast,包括一个接受 JSON 字符串的便捷构造函数,以便您可以快速解析强类型Forecast值并访问其字段:
let forecast = Forecast.from(json: jsonString)!
print(forecast.daily.data[0].windGustTime)
You can install quicktype from npm with npm i -g quicktypeor use the web UIto get the complete generated code to paste into your playground.
您可以使用npm 安装 quicktypenpm i -g quicktype或使用 Web UI来获取完整的生成代码以粘贴到您的 Playground 中。
回答by Marco Weber
Updatedthe isConnectToNetwork-Functionafterwards, thanks to this post.
更新了isConnectToNetwork-Function之后,由于这个职位。
I wrote an extra method for it:
我为它写了一个额外的方法:
import SystemConfiguration
func loadingJSON(_ link:String, postString:String, completionHandler: @escaping (_ JSONObject: AnyObject) -> ()) {
if(isConnectedToNetwork() == false){
completionHandler("-1" as AnyObject)
return
}
let request = NSMutableURLRequest(url: URL(string: link)!)
request.httpMethod = "POST"
request.httpBody = postString.data(using: String.Encoding.utf8)
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse , httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
//JSON successfull
do {
let parseJSON = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
DispatchQueue.main.async(execute: {
completionHandler(parseJSON as AnyObject)
});
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
}
task.resume()
}
func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
loadingJSON("yourDomain.com/login.php", postString:"email=\(userEmail!)&password=\(password!)") { parseJSON in
if(String(describing: parseJSON) == "-1"){
print("No Internet")
} else {
if let loginSuccessfull = parseJSON["loginSuccessfull"] as? Bool {
//... do stuff
}
}
.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
let ret = (isReachable && !needsConnection)
return ret
}
So now you can easily call this in your app wherever you want
所以现在你可以在你的应用程序中随时随地轻松调用它
let urlString = "https://api.forecast.io/forecast/apiKey/37.5673776,122.048951"
let url = URL.init(string: urlString)
URLSession.shared.dataTask(with:url!) { (data, response, error) in
guard error == nil else {
print(error)
}
do {
let Data = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
// Note if your data is coming in Array you should be using [Any]()
//Now your data is parsed in Data variable and you can use it normally
let currentConditions = Data["currently"] as! [String:Any]
print(currentConditions)
let currentTemperatureF = currentConditions["temperature"] as! Double
print(currentTemperatureF)
} catch let error as NSError {
print(error)
}
}.resume()
回答by Arun K
The problem is with the API interaction method. The JSON parsing is changed only in syntax. The main problem is with the way of fetching data. What you are using is a synchronous way of getting data. This doesn't work in every case. What you should be using is an asynchronous way to fetch data. In this way, you have to request data through the API and wait for it to respond with data. You can achieve this with URL session and third party libraries like Alamofire. Below is the code for URL Session method.
问题在于 API 交互方法。JSON 解析仅在语法上发生变化。主要问题在于获取数据的方式。您正在使用的是一种获取数据的同步方式。这并不适用于所有情况。您应该使用的是一种异步方式来获取数据。这样,你就必须通过 API 请求数据并等待它响应数据。您可以使用 URL 会话和第三方库(如Alamofire. 下面是 URL Session 方法的代码。
let json: Dictionary<String, Any>? = ["current": ["temperature": 10]]
回答by J. Doe
Swift has a powerful type inference. Lets get rid of "if let" or "guard let" boilerplate and force unwraps using functional approach:
Swift 具有强大的类型推断功能。让我们摆脱“if let”或“guard let”样板,并使用函数式方法强制展开:
- Here is our JSON. We can use optional JSON or usual. I'm using optional in our example:
- 这是我们的 JSON。我们可以使用可选的 JSON 或通常的。我在我们的例子中使用了 optional :
/// Curry
public func curry<A, B, C>(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
return { a in
{ f(a,
let temperature = (extract("temperature") § extract("current") § json) ?? NSNotFound
) }
}
}
/// Function that takes key and optional dictionary and returns optional value
public func extract<Key, Value>(_ key: Key, _ json: Dictionary<Key, Any>?) -> Value? {
return json.flatMap {
cast(let str = "{\"names\": [\"Bob\", \"Tim\", \"Tina\"]}"
let data = str.data(using: String.Encoding.utf8, allowLossyConversion: false)!
do {
let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: AnyObject]
if let names = json["names"] as? [String] {
print(names)
}
} catch let error as NSError {
print("Failed to load: \(error.localizedDescription)")
}
[key])
}
}
/// Function that takes key and return function that takes optional dictionary and returns optional value
public func extract<Key, Value>(_ key: Key) -> (Dictionary<Key, Any>?) -> Value? {
return curry(extract)(key)
}
/// Precedence group for our operator
precedencegroup RightApplyPrecedence {
associativity: right
higherThan: AssignmentPrecedence
lowerThan: TernaryPrecedence
}
/// Apply. g § f § a === g(f(a))
infix operator § : RightApplyPrecedence
public func §<A, B>(_ f: (A) -> B, _ a: A) -> B {
return f(a)
}
/// Wrapper around operator "as".
public func cast<A, B>(_ a: A) -> B? {
return a as? B
}
- Helper functions. We need to write them only once and then reuse with any dictionary:
- 辅助功能。我们只需要编写它们一次,然后在任何字典中重复使用:
{
"User":[
{
"FirstUser":{
"name":"John"
},
"Information":"XY",
"SecondUser":{
"name":"Tom"
}
}
]
}
- And here is our magic - extract the value:
- 这是我们的魔法 - 提取值:
import Foundation
struct RootClass : Codable {
let user : [Users]?
enum CodingKeys: String, CodingKey {
case user = "User"
}
init(from decoder: Decoder) throws {
let values = try? decoder.container(keyedBy: CodingKeys.self)
user = try? values?.decodeIfPresent([Users].self, forKey: .user)
}
}
struct Users : Codable {
let firstUser : FirstUser?
let information : String?
let secondUser : SecondUser?
enum CodingKeys: String, CodingKey {
case firstUser = "FirstUser"
case information = "Information"
case secondUser = "SecondUser"
}
init(from decoder: Decoder) throws {
let values = try? decoder.container(keyedBy: CodingKeys.self)
firstUser = try? FirstUser(from: decoder)
information = try? values?.decodeIfPresent(String.self, forKey: .information)
secondUser = try? SecondUser(from: decoder)
}
}
struct SecondUser : Codable {
let name : String?
enum CodingKeys: String, CodingKey {
case name = "name"
}
init(from decoder: Decoder) throws {
let values = try? decoder.container(keyedBy: CodingKeys.self)
name = try? values?.decodeIfPresent(String.self, forKey: .name)
}
}
struct FirstUser : Codable {
let name : String?
enum CodingKeys: String, CodingKey {
case name = "name"
}
init(from decoder: Decoder) throws {
let values = try? decoder.container(keyedBy: CodingKeys.self)
name = try? values?.decodeIfPresent(String.self, forKey: .name)
}
}
Just one line of code and no force unwraps or manual type casting. This code works in playground, so you can copy and check it. Here is an implementation on GitHub.
回答by J. Doe
This is an other way to solve your problem. So please check out below solution. Hope it will help you.
这是解决您的问题的另一种方法。所以请查看以下解决方案。希望它会帮助你。
do {
let res = try JSONDecoder().decode(RootClass.self, from: data)
print(res?.user?.first?.firstUser?.name ?? "Yours optional value")
} catch {
print(error)
}
回答by Abishek T
If I create model using previous json Using this link [blog]: http://www.jsoncafe.comto generate Codable structure or Any Format
如果我使用以前的 json 创建模型使用此链接 [博客]:http: //www.jsoncafe.com生成可编码结构或任何格式
Model
模型
##代码##Parse
解析
##代码##
