我对Swift和编程相对较新。我正在开发一个严重依赖从服务器下载的信息的应用程序。所以在很多ViewControllers中,我使用NSURLSession和NSJSONSerialization将JSON下载到我的应用程序中。
每次我想要下载字典时,例如timetableDict?["timetable"]["class"]["day"]["lesson"][0]["name"]
,Cannot subscript a value of type [String : AnyObject] with an index type of String
之类的内容都会显示为错误。
我明白我应该避免在我的代码中使用AnyObject,但服务器中的字典与这样的结构严重嵌套:
"timetable": ["class": ({
day = ({
lesson = ({
name = (MATHEMATICS, ENGLISH),
classOrder = 0,
teacher = (Someone)
}),
({
name = FRENCH,
classOrder = 1,
teacher = (Someone)
)}
)}
)}]
这种结构的问题在于它是嵌套的,并且当它到达“name”,“classOrder”和“teacher”时具有不同的类型。我很难不使用AnyObject。但是,这个错误在很长一段时间里一直让我讨厌。如果有人可以帮我解决这个问题,我将不胜感激。提前致谢!
答案 0 :(得分:2)
我建议看看SwiftyJSON:https://github.com/SwiftyJSON/SwiftyJSON
它是一个框架/库,旨在以比swift构建的更优雅的方式处理JSON(特别是对于像你这样的重型嵌套结构)。它易于使用,并有一个很好的教程。
编辑:(添加示例代码)
swiftyJSON教程的示例:
让JSONObject:AnyObject? = NSJSONSerialization.JSONObjectWithData(data,options:nil,error:nil)
if let statusesArray = JSONObject as? [AnyObject],
let status = statusesArray[0] as? [String: AnyObject],
let user = status["user"] as? [String: AnyObject],
let username = user["name"] as? String {
// Finally we got the username
}
即使可选链接相当混乱:
让JSONObject:AnyObject? = NSJSONSerialization.JSONObjectWithData(data,options:nil,error:nil)
if let username = (((JSONObject as? [AnyObject])?[0] as? [String: AnyObject])?["user"] as? [String: AnyObject])?["name"] as? String {
// What a disaster
}
使用swiftyJSON
let json = JSON(data: dataFromNetworking)
if let userName = json[0]["user"]["name"].string {
//Now you got your value
}
答案 1 :(得分:0)
@ Glenn提到的SwiftlyJSON并不是一个糟糕的系统(尽管我发现它过于依赖字符串查找,这很脆弱)。但更重要的是,您希望在一个位置验证和解析JSON,并将其转换为非JSON Swift数据结构,供程序的其余部分使用。 SwiftlyJSON可以成为一个不错的工具,但我会用它来将数据卸载到一个结构数组中。
在整个系统中使用JSON非常容易出错并且很麻烦,甚至包含在SwiftlyJSON中。如果您卸载一次数据,那么您可以检查错误一次以及您知道数据是否正确的其他任何地方。如果传递JSON结构,则必须每次检查并处理可能缺少或不正确的数据。考虑服务器以您不期望的格式向您发送JSON的情况。你想测试多少次?