2015-05-31 72 views
1
class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let url = NSURL(string: "https://api.forecast.io/forecast/MYKEYHERE/") 
     let session = NSURLSession.sharedSession() 
     let task: NSURLSessionDownloadTask = session.downloadTaskWithURL(url!, completionHandler: { (location: NSURL!, response: NSURLResponse!, error: NSError!) -> Void in 
      if error == nil { 
       let data = NSData(contentsOfURL: location) 
       let json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as! NSDictionary! 
       println(json) 
      } 
     }) 
     task.resume() 

    } 

這是爲天氣API下載任務的代碼。只是想知道爲什麼我得到的錯誤:爲什麼我的代碼在線程6中運行時崩潰了:NSOperationQueue?

Thread 6: EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP, subcode=0x0).

非常感謝。

回答

0

由於響應不是JSON(或者JSON不是字典),您會收到此錯誤。因此,解析JSON時,使用可選的結合優雅地處理nil或非字典的錯誤,也許是檢查響應的主體,如果失敗的話,如:

let task = session.downloadTaskWithURL(url!) { location, response, error in 
    if error == nil { 
     let data = NSData(contentsOfURL: location) 
     var error: NSError? 
     if let json = NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: &error) as? NSDictionary { 
      println("json = \(json)") 
     } else { 
      println("error = \(error)") 
      let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) 
      println("not json; responseString = \(responseString)") 
      println(response) 
     } 
    } 
} 
task.resume() 

此外,請注意,使用JSONObjectWithData時,你不僅想要優雅地檢查錯誤,但是如上所述,您通常也想使用error參數。

順便說一句,請確保在URL中包含經度和緯度,如forecast.ioAPI documentation所述,否則您將得到非JSON錯誤響應。即使您修復了網址以避免發生此錯誤,您仍然應該對錯誤進行一些適當的處理(如上所述),否則無論何時出現服務器問題,您的應用程序都可能會崩潰。

+0

感謝Rob,這非常有幫助。但我只是想知道,當你說使用錯誤參數時,我認爲你指的是可選的'var error:NSError?'的initalisation,但你爲什麼要這樣做?該錯誤是否已經在完成處理程序中初始化? –

+0

有兩個錯誤對象:有一個與網絡請求相關聯,但還有'JSONObjectWithData'的'error'參數。我擔心後者。如果網絡請求成功(即,沒有'NSError'對象被傳遞給閉包),您仍然需要一些變量來保存JSON解析生成的任何錯誤。 – Rob

相關問題