Swift NSDictionary get 0th value without knowing key name - ios

I have an NSDictionary that has a key like messageID5 and the value has three key/value pairs.
I know the NSDictionary only has 1 value in it because I limited my query to 1. But I don't know the name of the key. I just want the value, but I can't access it like an array [0]. You can access it just fine in PHP or Python. I've been trying a lot of different solutions for this basic problem, but a lot of them seem overly messy. anyValue[0] gives me a type error.

If you don't know your dictionary keys, you can get your NSDictionary allKeys.first property or allValues.first:
let dict = NSDictionary(dictionary: ["a":["b":1]])
let subDict = dict[dict.allKeys.first] as? [String:Any] ?? [:] // ["b": 1]
// or
let subDict = dict.allValues.first as? [String:Any] ?? [:] // ["b": 1]

The first thing to acknowledge is that key/value pairs in dictionaries does not maintain any specific order - this is required for an optimization in access to the contents of this structure.
As for your case if you're 100% sure you'll have only one value inside your dictionary you can use .allValues.first to retrieve the contained value. If your know that the type of your value is NSDictionary the whole code may look like this:
let childDictionary = rootDictionary.allValues.first as? NSDictionary

I suggest using (dictionary as Dictionary).values.first. That returns an optional, since it can fail if the dictionary is empty.
(Note that I edited this answer to cast the dictionary from an NSDictionary to a Dictionary so you an use the values property. NSDictionary doesn't have a values property, but Dictionary does.)

Related

Nested Dictionary in iOS Swift

I want to save a data in a dictionary in below format and then have to convert it into json.
[{"id":"1",
"name":[{"id":"2","name":"k"},{"id":"6","name":"kk"}]",
"pass":"123"},
{"id":"2",
"name":[{"id":"2","name":"k"},{"id":"6","name":"kk"}]",
"pass":"234"}
]
It got dictionary and single strings both within a dictionary. Here is what I'm trying, but unable to get the desirable result.
var myDictionary = Dictionary<String, AnyObject>()
let arrOfData = [["id":"1","pass":"123","name":[["id":"2","name":"k"],["id":"6","name":"kk"]]],
["id":"2","pass":"234","name":[["id":"2","name":"k"],["id":"6","name":"kk"]]]]
Here u can see the array of dictionary like Array<Dictionary,AnyObject> if you want to store in a single dictionary you can use it like let dict2 = ["data":arrOfData] Now this will convert into a single dictionary.

How do you Parse an Array of Dictionaries in Swift?

I'm new to swift and I am having difficulty parsing an array the array looks like this
MyArray [
[0]9keyValuePairs
[1]9keyValuePairs
]
I would like to add "MyArray.(0).ValueForKey:"Name" " to a UITableViewCell, but I can't quite figure out the correct syntax.
How is your array declared? If it is a array of something generic, ie [AnyObject] then you need to tell the type checker that the object in the array is a dictionary by casting it, otherwise you wont be able to access it as a dictionary.
If it is explicitly declared as an array of dictionaries ie [[String:AnyObject]] , then you just need to access the element in the array that you want, and then access the dictionary element you are interested in.
array[0] //how to get something out of an array
dictionary[key] //how to get something out of a dict
array[0][key] //how to get something out of an array of dicts
// if your array contents need to be cast, safely cast it using optional unwrapping
if let dict = array[0] as? [String:AnyObject] {
dict[key]
}

Could not cast value of type '__NSArrayM' to 'NSDictionary'

I have a json.I am trying to parse that with that code.But its says
Could not cast value of type '__NSArrayM' to 'NSDictionary'
do {
let dataDictionary: NSDictionary = try NSJSONSerialization.JSONObjectWithData(responseObject as! NSData, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary // <------ Error
if let customerArray = dataDictionary.valueForKey("cart") as? NSArray {
for js in customerArray {
let nameArray = js.valueForKey("name")
let idArray = js.valueForKey("id")
}
}
}
Thank you for your helps
The root object in your data is an array, not a object (dictionary).
You need to dynamically decide how to handle your JSON depending on the deserialized object.
What it's telling you is that the JSON object that you're parsing is not a dictionary, it's an array. So if you change it so that you treat its value as an array instead of a dictionary, you'll be able to iterate over that.
You need to reevaluate your JSON to ensure that it's structured the way you think it is. It would also be useful if you posted the JSON that you're trying to parse so that we can see it's structure as well.

How to create and access a NSDictionary in Swift

I am busy converting to Swift and am trying to figure out how to do the following in Swift
NSArray arrayOfStrings1 = {#"Substring1", #"Substring2", nil};
Dictionary dict = {#"MainString1", arrayOfStrings1};
So in Swift I have the following:
var dictionary = [String: Array<String>]() // is this correct ??
var array: [String] = ["Substring1", "Substring2"]
dictionary["MainString1"] = ["Substring1.1", "Substring1.2"]
dictionary["MainString2"] = ["Substring2.1", "Substring2.2"]
Now in order to access the array I use
let array = dictionary["MainString1"]
let item0 = array[0]
but this fails with a compiler error which seems to indicate that array is in fact a String not an array of strings.
What am I missing here?
The issue is actually that a subscript lookup for a Dictionary in Swift returns an optional value:
This is a pretty great feature - you can't be guaranteed that the key you're looking for necessarily corresponds to a value. So Swift makes sure you know that you might not get a value from your lookup.
This differs a little bit from subscript behavior for an Array, which will always return a value. This is a semantically-driven decision - it's common in languages for dictionary lookups to return null if there is no key - but if you try to access an array index that does not exist (because it's out of bounds), an exception will be thrown. This is how Swift guarantees you'll get a value back from an array subscript: Either you'll get one, or you'll have to catch an exception. Dictionaries are a little more lenient - they're "used to" not having the value you're asking for.
As a result, you can use optional binding to only use the item if it actually has a value, like so:
if let theArray = dictionary["MainString1"] {
let item0 = theArray[0]
} else {
NSLog("There was no value for key 'MainString1'")
}

Trouble Unpacking Dictionary of Dictionaries in Swift

I am having a devil of a time trying to work with Dictionaries in Swift. I have created the following Dictionary of Dictionaries but I am unable to unpack it.
var holeDictionary = Dictionary<String,Dictionary<String,Dictionary<String,Int>>>()
I can get the first Dictionary out with:
var aDictionary = holeDictionary["1"]
But trying to access the next Dictionary within it gives me an error as follows:
var bDictionary = aDictionary["key"] // [String : Dictionary<String, Int>]?' does not have a member named 'subscript'
I know what the contents of the Dictionaries are and can verify them with a println(aDictionary). So how can I get to the Dictionaries buried deeper down?
The key subscript on Dictionary returns an optional, because the key-value pair may or may not exist in the dictionary.
You need to use an if-let binding or force unwrap the optional before you can access it to subscript it further:
if let aDictionary = holeDictionary["1"] {
let bDictionary = aDictionary["key"]
}
Edit, to add forced unwrap example:
If you're sure that the key "1" exists, and you're okay with assert()ing at runtime if the key doesn't exist, you can force-unwrap the optional like this:
let bDictionary = holeDictionary["1"]!["key"]
And if you're sure that the key "key" will exist, you'd do this instead:
let bDictionary = holeDictionary["1"]!["key"]!
Accordingly to the swift documentation:
Because it is possible to request a key for which no value exists,
a dictionary’s subscript returns an optional value of the dictionary’s
value type
When you retrieve an item from a dictionary you have an optional value returned. The correct way to handle your case is:
var holeDictionary = Dictionary<String,Dictionary<String,Dictionary<String,Int>>>()
if let aDictionary = holeDictionary["1"] {
var bDictionary = aDictionary["key"]
}

Resources