Retrieve dictionary from dictionary swift - swift

I am converting objective c code in swift.
I am getting data from server which has a dictionaries in a dictionaries.
i am getting key value string but cannot get dictionary.
example data:
data = {
caption = hello;
image = {
a = "https://www.google.com/1024x1024";
b = "https://www.google.com/640x640";
c = "https://www.google.com/480x480";
d = "https://www.google.com/";
};
};
i can get caption
let dataDict = (mainDict[data] as? Dictionary<String,AnyObject>)!
Obj.caption=String(dataDict["caption"]!) //getting hello
Obj.imageDictionary = (dataDict["image"] as? Dictionary<String,String>)! //getting 0 key value pairs
initialised imageDictionary as
var imageDictionary = Dictionary<String, String>()
please suggest how to get the image dictionary, I want this dictionary to store in imageDictionary object.
Any suggestions would be highly appreciated!
Thanks in advance!

Try this:
let data : [String : Any] = ["caption" : "hello",
"image" :["a" : "https://www.google.com/1024x1024",
"b" : "https://www.google.com/640x640",
"c" : "https://www.google.com/480x480",
"d" : "https://www.google.com/",
]
]
let caption = data["caption"] as! String
let imageDictionary = data["image"] as! [String : String]
In imageDictionary, I am getting:
["b": "https://www.google.com/640x640", "a": "https://www.google.com/1024x1024", "d": "https://www.google.com/", "c": "https://www.google.com/480x480"]
Screenshot:

Related

Get child of dictionary with unknown parent key

I have a dictionary from type [String: Any] that looks like this
"arExtensions" : {
"images" : {
"-LmgO2yG_TWbfOM4Y8X3" : {
"imagePath" : "https://firebasestorage.googleapis.com/v0/b/gpk-citycards.appspot.com/o/ARResources%2F78E88F6D-52F0-43A3-B585-9760D19F0B81?alt=media&token=be3a664f-a94b-4ead-bea4-1197155c016e",
"position" : "bottom"
},
"-LmgO4qaMKupHZIAEoLk" : {
"imagePath" : "https://firebasestorage.googleapis.com/v0/b/gpk-citycards.appspot.com/o/ARResources%2FC7303CF9-0E86-4DC6-A5F5-2761537F0A30?alt=media&token=1f928774-8221-474b-881e-7f395e439131",
"position" : "rightMiddle"
},
"-LmgO9vLT8rEx9Ndog4S" : {
"imagePath" : "https://firebasestorage.googleapis.com/v0/b/gpk-citycards.appspot.com/o/ARResources%2F9132B5B6-E904-4BCE-B56A-0271CB901A7D?alt=media&token=bd66cd1d-494b-4a82-8d74-6e00ac8c8ae6",
"position" : "leftMiddle"
}
}
}
I want to add the images into an object.
var imageObjects: [ImageObject] = []
I know that I can get the values with the keys like this
let dictImages: [String: Any] = dictArExtensions["images"] as! [String : Any]
unfortunately I don't know the key of the children of images.
with two iteration, first to get the key, second to get the needed values i solved the problem like this
var imageKeys: [String] = []
for dict in dictImages{
print(dict.key)
imageKeys.append(dict.key)
print(dict.value)
}
for keys in imageKeys{
let dictImage: [String: Any] = dictImages[keys] as! [String : Any]
let imagePath = dictImage["imagePath"] as? String
let position = dictImage["position"] as? String
imageObjects.append(ImageObject(imagePath: imagePath!, position: position!))
}
but, it seems like a bad solution.
Is there a better or rather more professional solution to this?
You can enumerate the dictionary very simply with key and value but the key is actually unused.
And if you declare the child dictionary as [String:String] you can get rid of the type cast
for (_, value) in dictImages {
let dictImage = value as! [String:String]
let imagePath = dictImage["imagePath"]
let position = dictImage["position"]
imageObjects.append(ImageObject(imagePath: imagePath!, position: position!))
}
Please read the section about dictionaries in the Language Guide

Array Added duplicate object

Please Review my code below, When I add dictionary object to NSMutableArry, it gives me duplicate object.
tempArray is array where i want to save all objects.
fields is another array from where i will filter some objects.
let tempArray = NSMutableArray()
for i in 0..<fields.count {
let dict = NSMutableDictionary()
dict .setValue(fields[i].value(forKey: "interface_id"), forKey: "interface_id")
dict .setValue(fields.fields[i].value(forKey: "type"), forKey: "type")
dict .setValue(fields.fields[i].value(forKey: "icon"), forKey: "icon")
if fields.fields[i].value(forKey: "type") == "Name"{
dict .setValue("First Name", forKey: "label_name")
dict .setValue("first_column", forKey: "column_name")
tempArray.add(dict)
dict .setValue("Last Name", forKey: "label_name")
dict .setValue("last_column", forKey: "column_name")
tempArray.add(dict)
}
}
OutPut
(
{
"interface_id" = 1;
"type" = "Name";
"icon" = "G.JPG";
"label_name" = "Last Name";
"column_name" = "last_column";
},
{
"interface_id" = 2;
"type" = "Name";
"icon" = "G.JPG";
"label_name" = "Last Name";
"column_name" = "last_column";
}
)
But Expected Output :
(
{
"interface_id"=1;
"type"="Name";
"icon"="G.JPG";
"label_name"="First Name";
"column_name"="first_column";
},
{
"interface_id"=2;
"type"="Name";
"icon"="G.JPG",
"label_name"="Last Name";
"column_name"="last_column";
}
)
You have a error in your code.
In same for loop iteration, you do this :
if fields.fields[i].value(forKey: "type") == "Name"{
dict .setValue("First Name", forKey: "label_name")
dict .setValue("first_column", forKey: "column_name")
tempArray.add(dict)
dict .setValue("Last Name", forKey: "label_name")
dict .setValue("last_column", forKey: "column_name")
tempArray.add(dict)
}
which will first set the label_name to First Name and then correct it to Last Name.
Because you don't change anything in regarding the loop iteration, there should be no difference between each loop.
EDIT:
Thanks to comment from #rmaddy.
I totally agree: Do not use NSMutableDictionary inside Swift, unless you really know why you need it. (Objects referencing,... - NSMutableDictionary and Dictionary from Swift has different memory management rules).
Also I would avoid using .setValue or .setObject for that matter. I would rather use
dict["column_name"] = "last_column"
I think it is more clear.
Steps of your code (explained):
First you create array
so:
let tempArray = NSMutableArray() // ---> tempArray = []
You go trough first loop of iteration (i == 0 )
You create dictinary
so:
let dict = NSMutableDictionary() // ----> dict = {}
You add three values inside
so:
dict .setValue(fields[i].value(forKey: "interface_id"), forKey: "interface_id")
dict .setValue(fields.fields[i].value(forKey: "type"), forKey: "type")
dict .setValue(fields.fields[i].value(forKey: "icon"), forKey: "icon")
// -----> dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG"}
Then you check if "type" == "Name"
Because it is true you add
so:
dict .setValue("First Name", forKey: "label_name")
dict .setValue("first_column", forKey: "column_name")
// -----> dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG", "label_name": "First Name", "column_name": "first_column"}
you add this dictionary to array
so:
// -----> tempArray = [dict] // Notice that I put here only pointer to the dict
you change dictionary to
so:
// -----> dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG", "label_name": "Last Name", "column_name": "last_column"}
In this moment, you change object witch dict is pointing at: so this mean that inside tempArray now you have this new values in first position :
// it is still
// -----> tempArray = [dict]
// but : dict = {"interface_id" : 1, "type" : "Name", "icon" : "G.JPG", "label_name": "Last Name", "column_name": "last_column"}
That is the reason why don't use NSMutableDictinary and NSMutableArray in Swift if you absolutely don't know why you are using them
The suggested code would be:
var tempArray: [Any] = []
for i in 0..<fields.count {
let dict:[String:String] = [:]
dict["interface_id"] = fields[i].value(forKey: "interface_id")
dict["type"] = fields.fields[i].value(forKey: "type")
dict["icon"] = fields.fields[i].value(forKey: "icon")
if dict["type"] == "Name"{
dict["label_name"] = "First Name"
dict["column_name"] = "first_column"
tempArray.append(dict)
// In Swift Array we append object not reference, so this is working now.
dict["label_name"] = "Last Name"
dict["column_name"] = "last_column"
tempArray.add(dict)
}
}

NSTextField to Label by using TextField as the name of an dictionary

Swift4, Xcode9.3, Cocoa App.
How to change the string of labelMain to a dictionary word,
with a string key?
for example, a user put in "dict1" in the TextField,
the app should recognized that it is in the dict1 dictionary key "2",
and the label should print out "word2", instead of other words.
let dict0 : Dictionary<String, String> = ["0" : "word0", "1" : "word1"]
let dict1 : Dictionary<String, String> = ["2" : "word2", "3" : "word3"]
labelMain.stringValue = TextField.stringValue["2"]
error: Cannot subscript a value of type 'String' with an index of type 'String'
Create a dictionary that maps dictionary names to the actual dictionary:
let dict0 : Dictionary<String, String> = ["0" : "word0", "1" : "word1"]
let dict1 : Dictionary<String, String> = ["2" : "word2", "3" : "word3"]
let dictMap = ["dict0": dict0, "dict1": dict1]
if let dict = dictMap[TextField.stringValue], let word = dict["2"] {
labelMain.stringValue = word
}
or using optional chaining:
if let word = dictMap[TextField.stringValue]?["2"] {
labelMain.stringValue = word
}
or combined with the nil coalescing operator to provide a default value if none was found:
labelMain.stringValue = dictMap[TextField.stringValue]?["2"] ?? ""

How do I add more items to this type of name value pair array? [duplicate]

I have a simple Dictionary which is defined like:
var dict : NSDictionary = [ 1 : "abc", 2 : "cde"]
Now I want to add an element into this dictionary: 3 : "efg"
How can I append 3 : "efg" into this existing dictionary?
You're using NSDictionary. Unless you explicitly need it to be that type for some reason, I recommend using a Swift dictionary.
You can pass a Swift dictionary to any function expecting NSDictionary without any extra work, because Dictionary<> and NSDictionary seamlessly bridge to each other. The advantage of the native Swift way is that the dictionary uses generic types, so if you define it with Int as the key and String as the value, you cannot mistakenly use keys and values of different types. (The compiler checks the types on your behalf.)
Based on what I see in your code, your dictionary uses Int as the key and String as the value. To create an instance and add an item at a later time you can use this code:
var dict = [1: "abc", 2: "cde"] // dict is of type Dictionary<Int, String>
dict[3] = "efg"
If you later need to assign it to a variable of NSDictionary type, just do an explicit cast:
let nsDict = dict as! NSDictionary
And, as mentioned earlier, if you want to pass it to a function expecting NSDictionary, pass it as-is without any cast or conversion.
you can add using the following way and change Dictionary to NSMutableDictionary
dict["key"] = "value"
I know this might be coming very late, but it may prove useful to someone.
So for appending key value pairs to dictionaries in swift, you can use updateValue(value: , forKey: ) method as follows :
var dict = [ 1 : "abc", 2 : "cde"]
dict.updateValue("efg", forKey: 3)
print(dict)
SWIFT 3 - XCODE 8.1
var dictionary = [Int:String]()
dictionary.updateValue(value: "Hola", forKey: 1)
dictionary.updateValue(value: "Hello", forKey: 2)
dictionary.updateValue(value: "Aloha", forKey: 3)
So, your dictionary contains:
dictionary[1: Hola, 2: Hello, 3: Aloha]
If your dictionary is Int to String you can do simply:
dict[3] = "efg"
If you mean adding elements to the value of the dictionary a possible solution:
var dict = Dictionary<String, Array<Int>>()
dict["key"]! += [1]
dict["key"]!.append(1)
dict["key"]?.append(1)
Swift 3+
Example to assign new values to Dictionary. You need to declare it as NSMutableDictionary:
var myDictionary: NSMutableDictionary = [:]
let newValue = 1
myDictionary["newKey"] = newValue
print(myDictionary)
For whoever reading this for swift 5.1+
// 1. Using updateValue to update the given key or add new if doesn't exist
var dictionary = [Int:String]()
dictionary.updateValue("egf", forKey: 3)
// 2. Using a dictionary[key]
var dictionary = [Int:String]()
dictionary[key] = "value"
// 3. Using subscript and mutating append for the value
var dictionary = [Int:[String]]()
dictionary[key, default: ["val"]].append("value")
In Swift, if you are using NSDictionary, you can use setValue:
dict.setValue("value", forKey: "key")
Given two dictionaries as below:
var dic1 = ["a": 1, "c": 2]
var dic2 = ["e": 3, "f": 4]
Here is how you can add all the items from dic2 to dic1:
dic2.forEach {
dic1[$0.key] = $0.value
}
Dict.updateValue updates value for existing key from dictionary or adds new new key-value pair if key does not exists.
Example-
var caseStatusParams: [String: AnyObject] = ["userId" : UserDefault.userID ]
caseStatusParams.updateValue("Hello" as AnyObject, forKey: "otherNotes")
Result-
▿ : 2 elements
- key : "userId"
- value : 866
▿ : 2 elements
- key : "otherNotes"
- value : "Hello"
[String:Any]
For the fellows using [String:Any] instead of Dictionary below is the extension
extension Dictionary where Key == String, Value == Any {
mutating func append(anotherDict:[String:Any]) {
for (key, value) in anotherDict {
self.updateValue(value, forKey: key)
}
}
}
As of Swift 5, the following code collection works.
// main dict to start with
var myDict : Dictionary = [ 1 : "abc", 2 : "cde"]
// dict(s) to be added to main dict
let myDictToMergeWith : Dictionary = [ 5 : "l m n"]
let myDictUpdated : Dictionary = [ 5 : "lmn"]
let myDictToBeMapped : Dictionary = [ 6 : "opq"]
myDict[3]="fgh"
myDict.updateValue("ijk", forKey: 4)
myDict.merge(myDictToMergeWith){(current, _) in current}
print(myDict)
myDict.merge(myDictUpdated){(_, new) in new}
print(myDict)
myDictToBeMapped.map {
myDict[$0.0] = $0.1
}
print(myDict)
To add new elements just set:
listParameters["your parameter"] = value
There is no function to append the data in dictionary. You just assign the value against new key in existing dictionary. it will automatically add value to the dictionary.
var param = ["Name":"Aloha","user" : "Aloha 2"]
param["questions"] = "Are you mine?"
print(param)
The output will be like
["Name":"Aloha","user" : "Aloha 2","questions" : ""Are you mine"?"]
To append a new key-value pair to a dictionary you simply have to set the value for the key. for eg.
// Initialize the Dictionary
var dict = ["name": "John", "surname": "Doe"]
// Add a new key with a value
dict["email"] = "john.doe#email.com"
print(dict)
Output -> ["surname": "Doe", "name": "John", "email": "john.doe#email.com"]
var dict = ["name": "Samira", "surname": "Sami"]
// Add a new enter code herekey with a value
dict["email"] = "sample#email.com"
print(dict)
Up till now the best way I have found to append data to a dictionary by using one of the higher order functions of Swift i.e. "reduce". Follow below code snippet:
newDictionary = oldDictionary.reduce(*newDictionary*) { r, e in var r = r; r[e.0] = e.1; return r }
#Dharmesh In your case, it will be,
newDictionary = dict.reduce([3 : "efg"]) { r, e in var r = r; r[e.0] = e.1; return r }
Please let me know if you find any issues in using above syntax.
Swift 5 happy coding
var tempDicData = NSMutableDictionary()
for temp in answerList {
tempDicData.setValue("your value", forKey: "your key")
}
I added Dictionary extension
extension Dictionary {
func cloneWith(_ dict: [Key: Value]) -> [Key: Value] {
var result = self
dict.forEach { key, value in result[key] = value }
return result
}
}
you can use cloneWith like this
newDictionary = dict.reduce([3 : "efg"]) { r, e in r.cloneWith(e) }
if you want to modify or update NSDictionary then
first of all typecast it as NSMutableDictionary
let newdictionary = NSDictionary as NSMutableDictionary
then simply use
newdictionary.setValue(value: AnyObject?, forKey: String)

Change value of dictionary within array in Swift 2

I'm trying to change a value of a dictionary that is within an array. I made a small prototype in PlayGround:
var arr = [NSDictionary]()
arr.append(["name":"blue","view":"<object id=\"6787\">","visible":"true","locked":"false"])
arr.append(["name":"yellow","view":"<object id=\"345\">","visible":"true","locked":"false"])
arr.append(["name":"green","view":"<object id=\"123\">","visible":"false","locked":"true"])
//test remove
arr.removeAtIndex(2)
arr.count
//test edit
let nameChange = arr[1]
nameChange.setValue("black", forKey: "name")
arr[1]
But an error occurred, and I can not solve:
Some can help me?
Because you created your dictionary as NSDictionary - the values can't change once they are set. But you still want to change them using setValue() and thats why you have the error. The fix is easy, change it to NSMutableDictionary. BUT. You shouldn't use Objective-C API, when you have Swift API. Thats why you should use Swift's Dictionary. How? e.g.
var arr = [[String:String]]()
arr.append(["name":"blue","view":"<object id=\"6787\">","visible":"true","locked":"false"])
arr.append(["name":"yellow","view":"<object id=\"345\">","visible":"true","locked":"false"])
arr.append(["name":"green","view":"<object id=\"123\">","visible":"false","locked":"true"])
//test remove
arr.removeAtIndex(2)
arr.count
//test edit
var nameChange = arr[1]
nameChange["name"] = "black"
Finally Got Some Code,
let DuplicateArray: NSArray = array
let DuplicateMutableArray: NSMutableArray = []
DuplicateMutableArray.addObjectsFromArray(DuplicateArray as [AnyObject])
var dic = (DuplicateMutableArray[0] as! [NSObject : AnyObject])
dic["is_married"] = "false"
DuplicateMutableArray[self.SelectedIndexPath] = dic
array = []
array = (DuplicateMutableArray.copy() as? NSArray)!
//Output Will Be Like
array = [
{
"name": "Kavin",
"Age": 25,
"is_married": "false"
},
{
"name": "Kumar",
"Age": 25,
"is_married": "false"
}
]