我有这种类型的数据。
John Tylor : [StudentData.moreDetailsArray(type: "Full Time", status: "Graduated")]
我想只打印John Tylor:Full Time:Graduated而不是打印项目名称和数组键。
代码如下:
struct StudentData: Decodable {
let moreDetails: [moreDetailsArray]
let id: Int
let name: String
}
struct moreDetailsArray: Decodable {
let type: String
let status: String
}
func parseStudentData(){
let url = URL(string: "https://api.myjson.com/bins/11mamq")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
do{
if error == nil{
let json = try? JSONDecoder().decode([StudentData].self, from: data!)
for a in json! {
print("\(a.name)" ," : ", "\(a.moreDetails)")
}
}
} catch {
print("error getting status: \(error)")
}
}.resume()
}
}
答案 0 :(得分:0)
您正在尝试print
模型。您需要print
moreDetailsArray
模型的每个属性。
<强>代码:强>
print("\(a.name)" ," : ", "\(a.moreDetails.first!.type)" , " : ", "\(a.moreDetails.first!.status)")
或者您可以在不打开包装且以一个字符串打印的情况下执行此操作:
if let type = a.moreDetails.first?.type, let status = a.moreDetails.first?.status {
print("\(a.name) : \(type) : \(status)")
}
您应该按照另一个答案中的说明重命名模型对象。这对您的代码可读性和质量都有好处。
答案 1 :(得分:0)
我不认为moreDetailsArray需要是一个数组。
我会像这样实现它:
struct Student: Decodable, CustomStringConvertible {
let id: Int
let name: String
let moreDetail: StudentoreDetail
var description: String {
return "\(name) : \(additionalInformation.description)"
}
}
struct StudentAdditionalInfo: Decodable, CustomStringConvertible {
let type: String
let status: String
var description: String {
return "\(type) : \(status)"
}
}
然后您需要做的就是:
guard let data = data,
let students = try? JSONDecoder().decode([Student].self, from: data) else {
print("[DEBUG] - No data/json"
return
}
for student in students {
print(student.description)
}
如果你的moreDetails实际上是一个数组,你可以选择第一个项目(如果存在)。
struct Student: Decodable, CustomStringConvertible {
let id: Int
let name: String
let moreDetail: StudentMoreDetail
var description: String {
return "\(name) : \(moreDetail.first?.description)"
}
}
其他提示:
JSONDecoder().decode([StudentData].self, from: data**!**)
答案 2 :(得分:0)
假设您需要将moreDetails作为数组保留,并且只对数组中的第一项感兴趣:
print("\(a.name) : \(a.moreDetails[0].type) : \(a.moreDetails[0].status)")
此外,您命名为moreDetailsArray的结构实际上不是一个数组。但是,用于存储它的属性是一个数组。所以我建议您调用moreDetails属性moreDetailsArray,并将结构名称更改为MoreDetails。
答案 3 :(得分:0)
使用Codable
协议
import Foundation
typealias Students = [Student]
struct Student: Codable {
let id: Int
let name: String
let moreDetails: [MoreDetail]
}
struct MoreDetail: Codable {
let type, status: String
}
// MARK: Convenience initializers
extension Student {
init(data: Data) throws {
self = try JSONDecoder().decode(Student.self, from: data)
}
init(_ json: String, using encoding: String.Encoding = .utf8) throws {
guard let data = json.data(using: encoding) else {
throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
}
try self.init(data: data)
}
}
extension Array where Element == Students.Element {
init(students data: Data) throws {
self = try JSONDecoder().decode(Students.self, from: data)
}
}
使用它:
func parseStudentData(){
let url = URL(string: "https://api.myjson.com/bins/11mamq")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if let data = data , let students = try? Array.init(students: data){
students.forEach({ (student) in
if student.moreDetails.count > 0{
print("\(student.name) : \(student.moreDetails[0].type) : \(student.moreDetails[0].status)")
}else{
print(student.name)
}
})
}
}.resume()
}