Swift 虽然使用了;护卫出租&引用;“未打开包装”;错误

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

我有“可选类型的值”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 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 ist
AnyObject?
所以我需要用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中,应该使用数据而不是NSData
Data
没有读取文件内容的选项,因此使用
NSData
-
NSData(contentsOf:krakenURL)