iOS 9 JSON 解析循环

Posted

技术标签:

【中文标题】iOS 9 JSON 解析循环【英文标题】:iOS 9 JSON Parsing loop 【发布时间】:2015-10-08 18:10:10 【问题描述】:

我正在创建一个应该从数据库中检索一些 JSON 的应用程序。

这就是我的 JSON 的样子:

["id":"1","longitude":"10","latitude":"10","visibility":"5","timestampAdded":"2015-10-01 15:01:39","id":"2","longitude":"15","latitude":"15","visibility":"5","timestampAdded":"2015-10-01 15:06:25"]

这是我使用的代码:

if let jsonResult = JSON as? Array<Dictionary<String,String>> 

                    let longitudeValue = jsonResult[0]["longitude"]
                    let latitudeValue = jsonResult[0]["latitude"]
                    let visibilityValue = jsonResult[0]["visibility"]

                    print(longitudeValue!)
                    print(latitudeValue!)
                    print(visibilityValue!)

如您所见,它只从 JSON 中获取第一个块,如果根本没有 JSON,它会崩溃,但如果我希望它计算数量并用它制作一个数组,如下所示:

var longitudeArray = [10, 15]
var latitudeArray = [10, 15]

等等……

我还需要它与 Apple Watch 兼容,所以我不能使用 SwiftyJSON。

我该怎么办?我真的希望你能帮助我!

谢谢。


已解决!

问题已由“Eric D”解决。

这是代码:

do 
    if let url = NSURL(string: "YOU URL HERE"),
        let data = NSData(contentsOfURL: url),
        let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [[String:AnyObject]] 

        print(jsonResult)
        let longitudeArray = jsonResult.flatMap  $0["longitude"] as? String 
        let latitudeArray = jsonResult.flatMap  $0["latitude"] as? String 
        print(longitudeArray)
        print(latitudeArray)

    
 catch let error as NSError 
    print(error.description)

非常感谢埃里克!! :-)

【问题讨论】:

您只会得到一个值,因为您只是从数组jsonResult[0] 中提取第一个值。如果它为空,它会崩溃,因为尝试从数组中获取不存在的索引会崩溃。 使用jsonResult.length()的for循环 为什么不使用 NSJSONSerialization?这将为您提供所提供数据的完整字典。比你可以用语言和纬度的名称填充这个字典并将结果填充到数组中 别忘了我只是使用NSData(contentsOfURL: url) 在 Playground 中运行测试,不要在 prod 中使用它,而是使用异步方法来下载数据。 :) 是的,我知道,谢谢你 Eric :-) 【参考方案1】:

您可以使用flatMap 来获取您的元素数组:

let longitudeArray = jsonResult.flatMap  $0["longitude"] as? String 
let latitudeArray = jsonResult.flatMap  $0["latitude"] as? String 

等等

flatMap 类似于map,但解包了可选项,这已经足够了,因为我们需要安全地转换从 json 数组中的每个字典中获取的对象的类型。

$0 表示它所应用到的数组的flatMap 的当前迭代中的对象。


如果您当前使用的是 SwiftyJSON,那么应该是:

let longitudeArray = jsonResult.flatMap  $1["longitude"].string 
let latitudeArray = jsonResult.flatMap  $1["latitude"].string 

因为.string 是 SwiftyJSON 的可选字符串值获取器。

但正如您所说,您不想(不再)使用它,因此您需要使用NSJSONSerialization 来解码您的 JSON 数据,Web 和 SO 上有很多示例。然后你就可以使用我原来的答案了。

【讨论】:

当我这样做时,Xcode 会变白并且无法编译:-/ 您确定您使用的是 Xcode 7 吗?此代码适用于 Swift 2,因为您的问题已被标记,因此需要 Xcode 7。 是的,我正在使用 Xcode 7(更准确地说是 Xcode 7.1 Beta) 在 Xcode 7.1b 中为我工作。我不知道你为什么不能使用它,这绝对是标准代码。您的 Xcode 安装可能有问题。 如果你没问题,让我们做一个测试:在 Playground 中运行 this test code。只需将 URL 替换为您的。然后告诉我发生了什么。【参考方案2】:

您已经获得了一个包含所有元素的数组(不仅仅是第一个元素。您只是在访问第一个元素)。 jsonResult 是一个字典数组。每个字典(在本例中,基于您提供的 json)包含以下元素:id、经度、纬度、可见性和 timestampAdded。为了访问它们中的每一个,您可以简单地循环 jsonResult 并访问第 i 个元素(并不总是第 0 个元素)。这也将防止您在 json 为空白或无效时遇到的崩溃(因为您只会检查 jsonResult 中的有效元素。

这将使您能够灵活地创建您希望创建的自定义数组(例如,为了创建一个包含所有经度的数组,您只需在循环 jsonResult 时将该元素添加到新数组中)。但是,如果您想省去手动构建这些数组的麻烦并假设您可以控制 json 结构,我建议将接收到的 json 更改为相关结构(字典或数组而不是字典数组) ,因此它会更好地满足您的需求,并以“开箱即用”的相关格式为您提供结果。

【讨论】:

是的,我知道。显然我不够清楚,但感谢您的回答,我很感激! :-) 但是我怎么计算它的数量呢? 获取jsonResult.length()

以上是关于iOS 9 JSON 解析循环的主要内容,如果未能解决你的问题,请参考以下文章

ios 在json解析过程中浮点型字符串出现精度丢失问题

iOS Playground中的Json解析do方法不解析

iOS - Json解析精度丢失处理(NSString, Double, Float)

JSON循环遍历解析

iOS9 - NSURLSession 无法解析响应但 AlamoFire 工作

快速解析 JSON 并在数组中循环时出错