Type 'Any' has no subscript memebers [duplicate] - swift

This question already has answers here:
Correctly Parsing JSON in Swift 3
(10 answers)
Closed 6 years ago.
When i converted to swift 3 , its saying type any has no subscript memebers.
let dataDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers)
let accessToken = dataDictionary["access_token"] as! AnyObject?
Ihave tried many possiblities but didn't worked.

The return type of JSONSerialization.jsonObject(with:options:) is Any which doesn't allow subscripting. You have to use explicit type conversion to subscript. If you're trying to cast the data to [String: Any] you could do the following:
if let dataDictionary = dataDictionary as? [String: Any] {
// dataDictionary["access_token"] as AnyObject
}

JSONSerialization.jsonObject throws an error so let catch it in a do catch block
do {
let dataDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String: Any]
let accessToken = dataDictionary["access_token"] as! AnyObject
} catch let error as NSError {
print(error)
}

Related

Parsing value with try? and guard returning different values [duplicate]

This question already has answers here:
Optional binding with try? and as? still produces an optional type
(2 answers)
Closed 5 years ago.
Language Used: Swift 3
Xcode Version: 8.3.2 (8E2002)
I have an extension on Data which parses the data into a JSONObject of type Any
extension Data {
func toJsonObject() -> Any? {
do {
return try JSONSerialization.jsonObject(with: self, options: [])
} catch {
print(error)
}
return nil
}
}
Now the weird thing is when I use guard the result object seems to be different when using toJsonObject() and try?
For example
guard let dictionary = data.toJsonObject() as? [String: Any] else {
return
}
dictionary is now of type [String: Any]
Whereas when I use this:
guard let dictionary = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
return
}
dictionary is now of type [String: Any]?
Isn't the result of the second code block supposed to be [String: Any] instead of the optional [String: Any]?
Is this a mistake on Swift or am I doing something wrong?
This is a feature of Swift, I'd say. The use of try? means that this becomes a double optional, it's trying to decode straight to that casting of as? [String: Any]. Plug this in and check the type on this to see the double optional in action:
// Becomes a type of `[String : Any]??`
let dictionary = try? JSONSerialization.jsonObject(with: Data(), options: []) as? [String: Any]
I think the answer you want is to just add some parentheses to clarify your intent:
guard let dictionary = (try? JSONSerialization.jsonObject(with: Data(), options: [])) as? [String: Any] else {
return
}

Error while parsing Json in swift 2.3

I am trying to parse this NSDictionary
{"fare":{"value":99.03,"fare_id":"12313545861568689494880005558558852","expires_at":1485864494,"display":"\u20b999.03","currency_code":"INR"},"trip":{"distance_unit":"mile","duration_estimate":720,"distance_estimate":2.76},"pickup_estimate":2}
My code is:
if let statusesArray = try? NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[String: Any]],
let user = statusesArray![0]["fare"] as? [String: Any],
let username = user["fare_id"] as? String {
// Finally we got the username
}
else
{
print("DONE")
}
But I am not getting the value fare ID. In fact its printing "DONE" from the else statement. I tried using apple's documentation of handling data,But the same error persist.
Your JSON response is Dictionary not Array, so type cast it to [String:AnyObject] and then get fare_id from the nested fare Dictionary.
if let dict = (try? NSJSONSerialization.JSONObjectWithData(data!, options: [])) as? [String: AnyObject],
let fareDict = dict["fare"] as? [String:AnyObject]
let username = fareDict["fare_id"] as? String {
print(username)
}

Ambiguous reference to member subscript with Array<Dictionary<NSObject, AnyObject>>

I am getting this "Ambiguous reference to member subscript" error for below code -
let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as! Dictionary<NSObject, AnyObject>
let items: Array<Dictionary<NSObject, AnyObject>> = resultsDict["items"] as! Array<Dictionary<NSObject, AnyObject>>
First of all I would not use NSObject with JSONSerialization, use [AnyHashable: Any] or [String : Any] instead. Secondly, I would recommend you use the shorthand dictionary and array syntax with brackets. I would also recommend using safe downcasts (as ?) with if let instead of forced downcasts (as!) for safety.
do {
if let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as? [String : Any] {
let items = resultsDict["items"] as? [[String : Any]]
// use items
}
} catch {
// handle error
}

How to resolve the error "ambiguous reference to member 'subscript'"

I get the error:
Ambiguous reference to member 'subscript'
On the following code:
let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
guard let jsonDictionary = jsonObject as? [NSObject: AnyObject],
let photos = jsonDictionary["photos"] as? [String: AnyObject], // this line is giving the error
let photosArray = photos["photo"] as [[String: AnyObject]] else {
print("Error")
}
Previous posts have suggested that I change the type from [String: AnyObject] to [AnyObjectHashable: Any]. This hasn't fixed the error. Can someone explain why this error is occurring and how it can be resolved?
You can replace this, for making dictionary in swift 3 you can use like [String: Any] instead of [String: AnyObject]
let jsonObject = try JSONSerialization.jsonObject(with: data, options: [])
guard let jsonDictionary = jsonObject as? [String: Any],
let photos = jsonDictionary["photos"] as? [String: AnyObject], // this line is giving the error
let photosArray = photos["photo"] as? [[String: Any]] else {
print("Error")
}
print(jsonDictionary)

Problems with getting values out of nested dictionary in Swift 3 and Xcode 8

I parse JSON with this :
let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers)
and get the following nested dictionary as a result
{ response = { GeoObjectCollection = { featureMember =
(
{ GeoObject = { Point = { pos = "40.275713 59.943413"; }; }; },
{ GeoObject = { Point = { pos = "40.273162 59.944292"; }; }; }
);
};
};
}
I'm trying to get the values of coordinates out of this dictionary and save them into new latutudeString and longitudeString variables
Until Xcode 8 GM it worked for me with this code:
if let jsonCoordinatesString: String = dictionary["response"]!!["GeoObjectCollection"]!!["featureMember"]!![0]["GeoObject"]!!["Point"]!!["pos"]!! as? String {
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
But since I've installed Xcode 8 GM i receive an error:
Type Any has no Subscript members
How to fix it it Swift 3 with Xcode 8 ? I've read that I can cast it but don't know exactly how to make it work with my nested dictionary in swift 3 with the latest Xcode. I've read can't resolve "Ambiguous use of subscript" but it really did not helped me in my case.
Your JSON data has this type in Swift:
[String: [String: [String: [[String: [String: [String: String]]]]]]]
I would avoid using such a too deeply nested type, but you can write something like this, if you dare use it:
enum MyError: Error {
case invalidStructure
}
do {
guard let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as? [String: [String: [String: [[String: [String: [String: String]]]]]]] else {
throw MyError.invalidStructure
}
if let jsonCoordinatesString: String = dictionary["response"]?["GeoObjectCollection"]?["featureMember"]?[0]["GeoObject"]?["Point"]?["pos"] {
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
} catch let error {
print(error)
}
But you may be hiding some irrelevant members of the JSON data, which might break this as? conversion.
So, you can go step by step, in some cases "need to" in Swift 3, like this:
do {
guard let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as? [String: AnyObject] else {
throw MyError.invalidStructure
}
if
let response = dictionary["response"] as? [String: AnyObject],
let geoObjectCollection = response["GeoObjectCollection"] as? [String: AnyObject],
let featureMember = geoObjectCollection["featureMember"] as? [[String: AnyObject]],
!featureMember.isEmpty,
let geoObject = featureMember[0]["GeoObject"] as? [String: AnyObject],
let point = geoObject["Point"] as? [String: AnyObject],
let jsonCoordinatesString = point["pos"] as? String
{
var latLongArray = jsonCoordinatesString.components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
} catch let error {
print(error)
}
(lets are mandatory for each Optional-bindings in Swift 3. And you can change all AnyObjects to Anys, if you prefer.)
The problem is that you have not specify the type of dictionary object, you need to explicitly specify the type of dictionary object as Dictionary like this way.
let dictionary = try JSONSerialization.jsonObject(with: geocodingResultsData as Data, options: .mutableContainers) as! [String: Any]
if let response = dictionary["response"] as? [String: Any],
let geoObjectCollection = response["GeoObjectCollection"] as? [String: Any],
let featureMember = geoObjectCollection["featureMember"] as? [[String: Any]] {
if let geoObject = featureMember[0]["GeoObject"] as? [String: Any],
let point = geoObject["Point"] as? [String: String] {
let latLongArray = point["pos"].components(separatedBy: " ")
let latitudeString = latLongArray[1]
let longitudeString = latLongArray[0]
}
}