簡體   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