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只是一行数字。