繁体   English   中英

使用Alamofire和SwiftyJSON正确解析带有多个对象的JSON数组

[英]Correctly parsing through a JSON array with multiple objects using Alamofire and SwiftyJSON

我能够打印出回复。 但是,我无法遍历数组并对其进行初始化。 这就是我请求数据的方式:

Alamofire.request(url, method: .get, parameters: nil, encoding: URLEncoding.default).responseJSON { (response) in

    print(response.value!)

    guard let data = response.data else { return }
    let json = JSON(data: data)

    for r in json.arrayValue {
        let person = Person(json: r)
    }
}

我添加了断点,但是我无法理解为什么循环不会发生?

更新:

response.value! 例:

{
  "pagination": {
    "object_count": 1,
    "page_number": 1
  },
  "attendees": [
    {
      "id": "818060297",
      "quantity": 1,
      "profile": {
        "first_name": "John",
        "last_name": "Doe",
        "company": "Apple",
        "name": "John Doe",
        "email": "john_doe@testmail.com",
        "job_title": "CEO"
      },
      "status": "Attending"
    }
  ]
}

更新2

这是我的AttendeesProfile类:

class AttendeesProfile {

    var name: String?

    init(json: JSON) {
        self.name = json["name"].stringValue
    }

}

现在,我不确定如何使Attendee类正常工作:

class Attendees {

    var attendees = [String]()
    var attendeesProfile: AttendeesProfile!

    init(json: JSON) {
        // Something here
    }
}

我怀疑您的guard声明在循环遍历数组之前停止了代码流: guard let data = response.data else { return }

在此行中,您要说的是如果数据中包含某些内容,则代码流可以继续。 如果没有,请停止并返回。 因此,您永远不会到达循环语句。

您确定您的response.data包含某些内容并且与nil不同吗? 您的print(response.value!)显示了什么?

您必须转换响应数据。 您不能在未知数组上行走,建议您使用ObjectMapper库。 它可以将您的数据解析为您愿意的模型,如果收到的数据为零或不是您想要的模型,则可以轻松找到。 不要忘记打印response.data以确保确切的数据。 https://github.com/Hearst-DD/ObjectMapper

您可以实现一些符合Decodable的结构,除其他外,这将给您带来好处,即无需依赖SwiftyJSON即可运行代码。

从您提供的JSON数据开始,请考虑以下三个简单结构:

struct AttendeeArray: Decodable {
   let attendees: [Attendee]
}

struct Attendee: Decodable {
   let status: String
   let profile: AttendeeProfile
}

struct AttendeeProfile: Decodable {
   let name: String
   let age: Int
}

每个结构仅包含您在JSON对象中定义的变量。

现在,使用JSONDecoder您可以像调用以下代码一样简单地解码JSON数据:

do { 
   let array = try JSONDecoder().decode(AttendeeArray.self, from: data)
   // do whatever with your attendees array
} catch {
   // handle error if parsing fails
   print(error)
}

我创建了一个简单的Playground,您可以在其中添加以下代码和下面的Decodable结构来进行测试:

import Foundation

func decodeAttendees(json: String) -> AttendeeArray? {
   guard let data = json.data(using: .utf8) else { return nil }
   do {
       return try JSONDecoder().decode(AttendeeArray.self, from: data)
   } catch {
       print("Error: \(error)")
       return nil
   }
}

let json = """
{
   "attendees": [
       {
           "status": "attending",
           "profile": {
               "name": "Joe",
               "age": 22
           }
       },
       {
           "status": "not attending",
           "profile": {
               "name": "Bob",
               "age": 44
           }
       }
   ],
   "servlet": {
       "servlet-name": "cofaxCDS",
       "servlet-class": "org.cofax.cds.CDSServlet"
   }
}
"""

let arr = decodeAttendees(json: json)
arr?.attendees[0].profile.name //"Joe"
arr?.attendees[1].status //"not attending"

现在,对于您当前的Alamofire完成处理程序,我猜测将其修改为类似于以下内容的代码将很简单:

Alamofire.request(url, method: .get, parameters: nil, encoding:   URLEncoding.default).responseJSON { (response) in
   guard let data = response.data else { return //remember to error if data is nil }
   do {
      let array = JSONDecoder().decode(AttendeesArray.self, from: data)
      //update your UI to show the array, or pass it on to a completion hanldler
   } catch {
      //handle errors
   }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM