TmSmth
TmSmth

Reputation: 452

Although use of "guard let", "not unwrapped" error

I have "Value of optional Type “AnyObject?” not unwrapped did you mean to use ! or?" error on the line 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
}
}

I don't get why the guard let doesn't work, thanks ! P.S : I know it's swift 2 and not 3 here, but i'm still working with xcode 7

Upvotes: 1

Views: 784

Answers (3)

Marcus
Marcus

Reputation: 2321

As suggested already in the comments, I think you need to be much more explicit on your types here. I know the compiler doesn't require you to do this, but i find it helps both with my thinking and avoids the compiler getting confused if I am always fully explicit. Remember in your case the function needs to return a String, not AnyObject, so you need to make sure you have a String. So my version of your function (and I have made some assumptions on the types, but hopefully you get the gist) would be as follows:

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
    }
}

Hope that helps.

Upvotes: 1

vadian
vadian

Reputation: 285069

You have to optional downcast all dictionaries to the proper type

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}

and the final value

let prix = tableauDeux["o"] as? String

Upvotes: 0

user1046037
user1046037

Reputation: 17685

Overview:

  • Compilation Error messages states that the types are wrong
  • As @David had stated try to use native types as much as possible and use NS counterparts only when absolutely necessary

Code:

The code below is in Swift 3 on Xcode 8. If you are using an older version, make the necessary changes.

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
    }
}

Upvotes: 1

Related Questions