Swift 虽然使用了;护卫出租&引用;“未打开包装”;错误
我有“可选类型的值”AnyObject?“未展开。您是想使用!还是?“Swift 虽然使用了;护卫出租&引用;“未打开包装”;错误,swift,Swift,我有“可选类型的值”AnyObject?“未展开。您是想使用!还是?“guard let tableauDeux= func attraperJSON() -> String? { guard let krakenURL = NSURL(string: "https://api.kraken.com/0/public/Ticker?pair=XXBTZEUR") else { print("Probleme adresse") return nil } guard let
guard let tableauDeux=
func attraperJSON() -> String? {
guard let krakenURL = NSURL(string: "https://api.kraken.com/0/public/Ticker?pair=XXBTZEUR") else {
print("Probleme adresse")
return nil
}
guard let tickerData = NSData(contentsOfURL: krakenURL) else {
print("Problème ticker data")
return nil
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(tickerData, options: [])
guard let tableauUn = json["result"] else {return nil }
guard let tableauDeux = tableauUn["XXBTZEUR"] else { return nil}
let prix = tableauDeux["o"]
return prix
} catch {
return nil
}
}
我不明白为什么警卫让不起作用,谢谢!
附言:我知道这里是swift 2而不是3,但我仍然在使用xcode 7,你必须选择将所有字典向下转换为正确的类型
guard let json = try NSJSONSerialization.JSONObjectWithData(tickerData, options: []) as? [String:AnyObject] else { return nil }
guard let tableauUn = json["result"] as? [String:AnyObject] else {return nil }
guard let tableauDeux = tableauUn["XXBTZEUR"] as? [String:AnyObject] else { return nil}
最后的价值呢
let prix = tableauDeux["o"] as? String
概述:
- 编译错误消息表示类型错误
- 正如@David所说的,尽可能多地使用本机类型,只有在绝对必要时才使用
对应类型NS
Xcode 8
上的Swift 3
中。如果您使用的是旧版本,请进行必要的更改。
func attraperJSON() -> String? {
//Use URL instead of NSURL
guard let krakenURL = URL(string: "https://api.kraken.com/0/public/Ticker?pair=XXBTZEUR") else {
print("Probleme adresse")
return nil
}
guard let tickerData = NSData(contentsOf: krakenURL) else {
print("Problème ticker data")
return nil
}
do {
//Use "as?" to convert to desired type
let json = try JSONSerialization.jsonObject(with: tickerData as Data, options: []) as? [String : Any]
//Use "as?" to convert to desired type
guard let tableauUn = json?["result"] as? [String : Any],
let tableauDeux = tableauUn["XXBTZEUR"] as? [String : String] else {
return nil
}
let prix = tableauDeux["o"]
return prix
} catch {
return nil
}
}
正如评论中已经提到的,我认为您需要在这里更明确地说明您的类型。我知道编译器不需要你这样做,但我发现这对我的思维很有帮助,如果我总是完全显式的话,也可以避免编译器感到困惑。请记住,在您的例子中,函数需要返回字符串,而不是任何对象,因此您需要确保您有一个字符串。因此,我对函数的版本(我对类型做了一些假设,但希望您能理解要点)如下所示:
func attraperJSON() -> String? {
guard let krakenURL : NSURL = NSURL(string: "https://api.kraken.com/0/public/. Ticker?pair=XXBTZEUR") else {
print("Probleme adresse")
return nil
}
guard let tickerData ; NSData = NSData(contentsOfURL: krakenURL) else {
print("Problème ticker data")
return nil
}
do {
if let json : [String : AnyObject] = try NSJSONSerialization.JSONObjectWithData(tickerData, options: []) as? [String : AnyObject] {
guard let tableauUn : [String : AnyObject] = json["result"] as? [String : AnyObject] else { return nil }
guard let tableauDeux : [String : String] = tableauUn["XXBTZEUR"] as? [String : String] else { return nil }
let prix : String = tableauDeux["o"]
return prix
} catch let retrievalError {
print("Error in \(#function): \(retrievalError.localizedDescription)")
// please put error handling code here
return nil
}
}
希望能有所帮助。首先,使用本地Swift类型(
URL
、Data
和JSONSerialization
)。其次,使用Xcode检查变量的类型,查看每个变量的类型。您应该将json
强制转换为“[String:Any]”,而不是将其解析为AnyObject
。检查错误消息并查看类型(选项单击变量)。错误不是由选项引起的,而是由错误的类型引起的。@user1046037 tableauUn istAnyObject?
所以我需要用guard let打开它,不是吗?@DávidPásztor你的意思是let json=try NSJSONSerialization.JSONObjectWithData(tickerData,options:[])as![String:Any]
?查看答案,但答案在Swift 3中。不要注释编译器可以推断的类型。你让事情变得更糟。谢谢你的回答,但我想避免使用“如果让”@vadian注释类型是什么意思?@TmSmth注释类型是冒号和等号前的let
或var
表达式中变量名后的类型。基本上,只有在极少数情况下,如果编译器无法推断类型并会抱怨,类型注释才是必要的。这不是一个真正的主题,但我感谢您的评论-我非常有兴趣了解更多关于这一点的原因。@vadian谢谢,直截了当地说,它是有效的!我试着让tableauDeux=tableauUn[“XXBTZEUR”]作为?[String:String]否则{return nil}并且后面的行没有强制转换,为什么它不工作?谢谢@例如,Sparky的tableauDeux
的类型应该是[String:AnyObject]
,但是您正在注释String
。这是一个错误。你应该避免这种不必要的错误。在NSURL
行中,您可以清楚地看到它是NSURL
。注释是多余的。@TmSmth它不起作用,因为tableauUn[“XXBTZEUR”]
的值是[String:AnyObject]
而不是[String:String]
。大多数字典值都是数组。@vadian哦,是的,我只是检查url,即使对于键“o”,它只是一个字符串,对于其他值,它是数组,谢谢!在Swift 4中,JSON解析通过Codable
变得更好。在Swift 3中,应该使用数据而不是NSDataData
没有读取文件内容的选项,因此使用NSData
-NSData(contentsOf:krakenURL)