简体   繁体   English

Swift 2 - 类型转换和可选链接

[英]Swift 2 - Type casting and optional chaining

I am relatively new to Swift and programming.我对 Swift 和编程比较陌生。 I'm developing an app which heavily relies on information downloaded from the server.我正在开发一个严重依赖从服务器下载的信息的应用程序。 So in a lot of ViewControllers, I use NSURLSession and NSJSONSerialization to download the JSON into my app.所以在很多 ViewController 中,我使用 NSURLSession 和 NSJSONSerialization 将 JSON 下载到我的应用程序中。

Every time I wanted to subscript the dictionary, for example timetableDict?["timetable"]["class"]["day"]["lesson"][0]["name"] , something like Cannot subscript a value of type [String : AnyObject] with an index type of String shows up as an error.每次我想对字典进行下标时,例如timetableDict?["timetable"]["class"]["day"]["lesson"][0]["name"] ,例如Cannot subscript a value of type [String : AnyObject] with an index type of String显示为错误。

I understand that I should avoid using AnyObject in my code, but the dictionary from the server is heavily nested with structures like this one:我知道我应该避免在我的代码中使用 AnyObject,但是来自服务器的字典大量嵌套了这样的结构:

"timetable": ["class": ({
                        day = ({
                            lesson = ({
                                   name = (MATHEMATICS, ENGLISH),
                                   classOrder = 0,
                                   teacher = (Someone)
                                      }),
                                     ({
                                   name = FRENCH,
                                   classOrder = 1,
                                   teacher = (Someone)
                                      )}
                               )}
                        )}]

The problem with this structure is that it is heavily nested and has different types when it gets to "name", "classOrder" and "teacher".这种结构的问题在于,当它涉及到“name”、“classOrder”和“teacher”时,它是严重嵌套的并且具有不同的类型。 It is very hard for me not to use AnyObject.我很难不使用 AnyObject。 However, this error has been annoying for me for a very long time.但是,这个错误让我很烦很长时间。 I would greatly appreciate it if someone could help me out on this.如果有人能帮助我解决这个问题,我将不胜感激。 Thanks in advance!提前致谢!

I suggest taking a look at SwiftyJSON : https://github.com/SwiftyJSON/SwiftyJSON我建议看看 SwiftyJSON : https : //github.com/SwiftyJSON/SwiftyJSON

It's a framework/library designed to handle JSON in a very much more elegant way than what's build into swift (especially for heavy nested structures like yours).它是一个框架/库,旨在以比 swift 中内置的方式(尤其是像您这样的重型嵌套结构)更优雅的方式处理 JSON。 It's easy to use and has an excellent tutorial.它易于使用并且有一个很好的教程。

EDIT: (Added sample code)编辑:(添加示例代码)

Example from the swiftyJSON tutorial :来自 swiftyJSON 教程的示例:

let JSONObject: AnyObject?让 JSONObject: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) = 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
}

even with optional chaining quite messy :即使使用可选链接也很混乱:

let JSONObject: AnyObject?让 JSONObject: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) = 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
}

With swiftyJSON使用 swiftyJSON

let json = JSON(data: dataFromNetworking)
if let userName = json[0]["user"]["name"].string {
  //Now you got your value
}

SwiftlyJSON that @Glenn mentions is not a bad system (though I find it over-reliant on string lookups, which is fragile). @Glenn 提到的 SwiftlyJSON 并不是一个糟糕的系统(尽管我发现它过度依赖字符串查找,这很脆弱)。 The deeper point, however, is that you want to validate and parse your JSON in one place, and turn it into a non-JSON Swift data structure for use by the rest of your program.然而,更深层次的一点是,您希望在一个地方验证和解析您的 JSON,并将其转换为非 JSON Swift 数据结构以供程序的其余部分使用。 SwiftlyJSON can be a decent tool for doing that, but I would use it to unload data into a an array of structs. SwiftlyJSON 是一个不错的工具,但我会用它来将数据卸载到一个结构数组中。

Working with JSON throughout your system is extremely error-prone and cumbersome, even wrapped up in SwiftlyJSON.在整个系统中使用 JSON 非常容易出错和繁琐,甚至包含在 SwiftlyJSON 中。 If you unload the data once, then you can check for errors one time and everywhere else you know that the data is correct.如果您卸载数据一次,那么您可以一次检查错误,并且可以在其他任何地方检查数据是否正确。 If you pass around JSON structures, then you must check every single time and deal with possibly missing or incorrect data.如果您传递 JSON 结构,那么您必须每次都检查并处理可能丢失或不正确的数据。 Think through the case where the server sends you JSON in a format you didn't expect.考虑一下服务器以您意想不到的格式向您发送 JSON 的情况。 How many times do you want to test for that?你想为此测试多少次?

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

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