Ios 由于展开,网络呼叫失败

Ios 由于展开,网络呼叫失败,ios,swift,cocoa-touch,nsdictionary,Ios,Swift,Cocoa Touch,Nsdictionary,这是我对forecast.io进行网络调用的代码。 在ViewController中,我有: private let apiKey = ""//my key override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let baseURL = NSURL(string: "https:

这是我对
forecast.io
进行网络调用的代码。 在
ViewController
中,我有:

private let apiKey = ""//my key

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let baseURL = NSURL(string: "https://api.forecast.io/forecast/\(apiKey)")
    let forecastURL = NSURL(string: "37.8267,-122.423", relativeToURL : baseURL)

    let sharedSession = NSURLSession.sharedSession()
    let downloadTask : NSURLSessionDownloadTask = sharedSession.downloadTaskWithURL(forecastURL!, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in
        if (error == nil) {
            let dataObject = NSData(contentsOfURL: location)
            let weatherDictionary : NSDictionary = NSJSONSerialization.JSONObjectWithData(
                dataObject!, options: nil, error: nil) as! NSDictionary
        }
    })
    downloadTask.resume()
}
我正在尝试将数据设置到
NSDictionary
中,以便能够访问它。我有一个bug(绿线),它与
weatherDictionary
有关:

致命错误:在展开可选值时意外发现nil


我正在解包
数据对象
,那么会有什么问题呢?

你真的,说真的,需要摆脱强制解包的习惯。如果每当你得到一个可选的,你只要使用
要打开它,您将永远遇到这些问题

这是一个版本的内部代码,用于检查每个回合的选项:

let sharedSession = NSURLSession.sharedSession()
let downloadTask = sharedSession.downloadTaskWithURL(forecastURL!)
{ location, response, error in

    if let error = error {
        // log error
    }
    else if let dataObject = NSData(contentsOfURL: location) {

        let weatherObj: AnyObject? = NSJSONSerialization.JSONObjectWithData(
            dataObject, options: nil, error: nil)

        if let weatherDictionary = weatherObj as? NSDictionary {

        }
        else {
            // log error with conversion of weather to dictionary
        }

    }
    else {
        // log error with dataObject
    }
}
是的,这样写的时间更长,也更烦人(不过,类型推断将有助于走另一条路——您不必显式地键入所有内容,例如,在回调中,我更清楚的是不必键入类型)

是的,有时您肯定知道某个值不会为零,因此强制展开该值更容易、更清晰(例如,使用
NSURL
–只要不涉及用户输入,您就可以非常安全地使用该值)

但是,在您不经常碰到零值错误之前,最好以这种方式编写代码

一旦你对处理选项感到更舒服,就要编写更整洁的代码

您可能还想考虑在处理JSON结果时使用更强的类型,例如,您可以执行以下操作:

if let weatherDictionary = weatherObj as? [String:AnyObject]

等处理字典内部时。同样,如果您相信
forecast.io
总是以正确的形式提供有效的JSON数据,您可以跳过这一步,强制执行所有操作,但在编写代码时,这将更难调试,并且您的代码可能会在生产中崩溃(而不是优雅地失败)如果您恢复了损坏的数据。

weatherDictionary应该有一个nil值。请检查DataObject是否已验证返回了有效的JSON?JSON真的代表了一个字典吗顺便说一句():使用错误参数!!注释weatherdictionary和println(dataObject)告诉我它不是JSON。但是weatherDictionary不应该是JSON吗?如果不是,那可能就是问题所在,因为dataObject只是一行数字。