我有这种类型的数据。
John Tylor : [StudentData.moreDetailsArray(type: "Full Time", status: "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()
}
}
您正在尝试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)")
}
您应该重命名模型对象,如其他答案中所述。这将有利于您的代码可读性和质量。
假设您需要将moreDetails保留为数组,并且只对数组中的第一项感兴趣:
print("(a.name) : (a.moreDetails[0].type) : (a.moreDetails[0].status)")
此外,您命名为 moreDetailsArray 的结构并不是真正的数组。但是,用于存储此属性的属性是一个数组。因此,我建议您调用moreDetails属性moreDetailsArray,并将结构的名称更改为MoreDetails。
使用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()
}
我不认为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**!**)
- 以正确的大小写(大写首字母(命名新类型,例如类、结构、枚举等
- 尝试遵循黄金之路,警卫声明可以在这里为您提供帮助。
- 不要命名像moreDetailsArray这样的东西,它是一个结构,而不是一个数组,尽管你在数组中使用它