使用 Alamofire 和 SwiftyJSON 正确解析具有多个对象的 JSON 数组
Posted
技术标签:
【中文标题】使用 Alamofire 和 SwiftyJSON 正确解析具有多个对象的 JSON 数组【英文标题】:Correctly parsing through a JSON array with multiple objects using Alamofire and SwiftyJSON 【发布时间】:2017-11-13 16:49:24 【问题描述】:我可以打印出回复。但是我无法遍历数组并对其进行初始化。这就是我请求数据的方式:
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
现在我不确定如何让参加者类正常工作:
class Attendees
var attendees = [String]()
var attendeesProfile: AttendeesProfile!
init(json: JSON)
// Something here
【问题讨论】:
在不知道您在此处传递的数据是什么(或 JSON 的结构)的情况下,很难为您提供有助于解决问题的具体答案。 我将如何向您显示响应,因为它包含大量数据。 结构会有所帮助,那么它是包含许多孩子的***对象吗?这些孩子是否包含孩子等?你能在lldbpo json.arrayValue.count
看看有没有条目吗?
@AdamFallon 请查看更新后的答案
【参考方案1】:
我怀疑您的 guard
语句会在您循环遍历数组之前停止您的代码流:guard let data = response.data else return
通过这一行,您是说如果数据有某些东西,那么代码流可以继续。如果没有,请停止并返回。所以,你永远不会到达你的循环语句。
你确定你的response.data
有什么东西和nil 不同吗?你的print(response.value!)
有什么东西?
【讨论】:
当我在guard let
之后运行断点时,它会到达下一行。如果我打印 response.data 我得到▿ Optional<Data> ▿ some : 56757 bytes - count : 56757 ▿ pointer : 0x00007fed5f07e200 - pointerValue : 140657478328832
你可以尝试打印你的 json 常量吗?
我知道了expression produced error: error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0xfffffffffffffff8). The process has been returned to the state before expression evaluation.
哦,糟糕的错误!如果你打印你的常量数据?也许您的 JSON 初始化程序有问题,并且没有初始化您的 json 常量。所以,你的 json 常量是空的,你的循环没有理由循环。
当我在控制台打印出json后守卫让我得到整个json数组。它看起来好像在返回一个字典【参考方案2】:
您必须转换您的响应数据。你不能在未知的阵列上行走 我建议你使用 ObjectMapper 库。它可以将您的数据解析为您愿意的模型,如果收到的数据为零或不是您想要的模型,您可以轻松找到。不要忘记打印 response.data 以确保数据到底是什么。 https://github.com/Hearst-DD/ObjectMapper
【讨论】:
对不起,我没用过这个框架。仅使用 SwiftyJSON 就不可能实现它吗?如果不能,您能演示一下如何使用它来解决我的问题吗? 您确定您的回复不为空且方式正确吗? 是的,这正是我所展示的。response.data = 56757 bytes
打印时告诉我 json 和 json.arrayValue
尝试字符串(数据:response.data!,编码:.utf8)【参考方案3】:
您可以实现几个符合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
【讨论】:
感谢您的详细解答。您是否建议使用 SwiftyJSON 在解析具有多个对象的 JSON 数组时存在限制?与此同时,我会尝试你的建议,看看我能做些什么。我只是觉得我已经在我的应用程序中使用不同的方法来解析 JSON 数据。或者这是正常的吗? SwiftyJSON 绝对是一个很棒的框架,它提供了很大的灵活性。我自己也用它。但是,我认为您至少应该知道替代方案。现在 Apple 添加了Codable
协议,处理原生对象的 JSON 编码/解码变得比以前容易得多。以上是关于使用 Alamofire 和 SwiftyJSON 正确解析具有多个对象的 JSON 数组的主要内容,如果未能解决你的问题,请参考以下文章
SwiftyJson 和 Alamofire 使用的解码结构
如何使用 Alamofire 和 SwiftyJSON 正确解析 JSON
如何将 RxSwift 与 AlamoFire 和 SwiftyJSON 一起使用?
无法使用“((Any))”类型的参数列表调用“JSON” - 使用 AlamoFire 和 SwiftyJSON