Swift / NSURLSession JSON 下载 / 在解包可选值时意外发现 nil



我正在下载数据并使用viewDidLoad()中的以下代码进行处理:

 NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://api.fixer.io/latest?base=USD")!, completionHandler: { (data, response, error) -> Void in
       // Check if data was received successfully
       if error == nil && data != nil {
          do {
             // Convert NSData to Dictionary where keys are of type String, and values are of any type
             let json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! [String:AnyObject]
             // Access specific key with value of type String
             let dollarToDollarDict = json["rates"] as! NSDictionary
             SpeedLog.print(dollarToDollarDict)
             let dollarToDollarNSNumber = dollarToDollarDict.valueForKey("EUR")
             let dollarToDollarString = String(dollarToDollarNSNumber)
             SpeedLog.print(dollarToDollarString)
             self.dollarExchangeRateStr = dollarToDollarString
             } catch {
               // Something went wrong
             }
           }
       }).resume()

print(dollarToDollarDict)打印出正确的字典。 print(dollarToDollarString)打印出我想要的正确所需字符串:"可选(1.1303)"

但是当我想通过按下按钮在dollarToDollarString中使用字符串时,带有:

func dollarBtnFunc(button: UIButton!) {
    if dollarExchangeRateStr != "" {
        SpeedLog.print("DOLLAR downloaded", dollarExchangeRateStr)            
        let dollarExchangeRateDouble = Double(dollarExchangeRateStr)!
        tableCounterData = ["(numberInt) $", "(numberInt * dollarExchangeRateDouble) €"]
    } else if dollarExchangeRateStr == "" {
        SpeedLog.print("DOLLAR not downloaded, Dollar = 0.89")
        tableCounterData = ["(numberInt) $", "(numberInt * 0.89) €"]
    }
    currentButton = "dollarBtnFunc"
}

我在let dollarExchangeRateDouble = Double(dollarExchangeRateStr)!上得到了unexpectedly found nil while unwrapping an Optional value.

我错过了什么?为什么字符串nil?我之前打印了正确的值...为什么一旦我想稍后使用它,它就不再是我的字符串的一部分?非常感谢帮助。

您的问题出在以下 2 行中:

let dollarToDollarNSNumber = dollarToDollarDict.valueForKey("EUR")
let dollarToDollarString = String(dollarToDollarNSNumber)

dollarToDollarDict.valueForKey("EUR")返回一个可选,因此dollarToDollarNSNumber是可选的。

使用可选项调用 String 初始值设定项会"Optional(...)"因此,稍后将该字符串传递给 Double 初始值设定项时,它会失败,因为它包含字母。

您需要通过执行以下操作来解开从valueForKey中获得的值:

if let dollarToDollarNSNumber = dollarToDollarDict.valueForKey("EUR") {
    let dollarToDollarString = String(dollarToDollarNSNumber)
    SpeedLog.print(dollarToDollarString)
    self.dollarExchangeRateStr = dollarToDollarString
} else {
    self.dollarExchangeRateStr = ""
}
我相信

你的问题在于将dollarExchangeRateStr转换为双倍。Double("foo") 返回一个可选选项,该选项可能在转换时失败,因此它是 nil,在强制解开包装时会失败。

改变

func dollarBtnFunc(button: UIButton!) {
   if let exchangeRateStr = dollarExchangeRateStr {
      SpeedLog.print("DOLLAR downloaded", exchangeRateStr )            
      let dollarExchangeRateDouble = Double(exchangeRateStr ) {
         tableCounterData = ["(numberInt) $", "(numberInt * dollarExchangeRateDouble) €"]
      }
      else {
         print("your string to double conversion failed")
      }
   } else if dollarExchangeRateStr == "" {
      SpeedLog.print("DOLLAR not downloaded, Dollar = 0.89")
      tableCounterData = ["(numberInt) $", "(numberInt * 0.89) €"]
   }
   currentButton = "dollarBtnFunc"
}

从您的评论来看,dollarExchangeRateStr 也是一个可选的,这意味着您也需要解开它,请注意 if let exchangeRateStr = dollarExchangeRateStr

干杯!

最新更新