Reputation: 452
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
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
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
Reputation: 17685
NS
counterparts only when absolutely necessaryThe 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