Contextual type 'AnyObject' cannot be used with dictionary literal multi level dictionary - swift

I'm running into an issue with creating a multi-level dictionary in Swift and have followed some of the suggestions presented here:
var userDict:[String:AnyObject]? = ["SystemId": "TestCompany",
"UserDetails" : ["firstName": userDetail.name, "userAddress" : "addressLine1" userDetail.userAdd1]]
The use of [String:AnyObject]? works for the first level of the Dict, but Swift is throwing the same error at the next level Dict, UserDetail[]. Any suggestions would be greatly appreciated

I'm not pretty sure what are the types of userDetail.name and userDetail.userAdd1 but if they are Strings you should let it [String:String]?
However, [String:Any]? should solve your problem. If you are sure that you want to let it [String:AnyObject]? (I don't think that you want to), you can do something like this:
var userDict:[String:AnyObject]? = ["SystemId": "TestCompany" as AnyObject,
"UserDetails" : ["firstName": userDetail.name, "userAddress" : userDetail.userAdd1] as AnyObject]
Hope this helped.

Related

How to add value to dictionary without replacing it?

I'm trying to append values inside dictionary without replacing it for example:
var dict = [String:Any]()
dict["login"] = ["user" : "jon"]
//...
//...
//...
dict["login"] = ["password": "1234"]
When I'm trying to add a value to login at the second time , it's overwrite the first value.
How can I append this data?
I'm using Swift 3.
Edit: let me rephrase my question a little bit.
I want to build a dynamic dictionary which I'll post it to alamoFire as body parameters. so if I have an JSON that looks like this:
{
"name" : "Jon",
"details" : {
"occupation" : "lifeguard"
"years_of_ex" : 3
}
"more_details" : "extra info"
"inner_body" : {
"someInfo" : "extra info"
}
... // there might be lots of other fields since it's dynamic
... // the server expect to have missing fields and not empty ones
}
I want to add dynamically details since I don't know how my Dictionary would looks like.
so adding to values to dictionary without override them is a must for me.
Define an intermediate variable and assign to it:
var dict = [String:Any]()
dict["login"] = ["user" : "jon"]
if var login = dict["login"] as? [String: String] {
login["password"] = "1234"
dict["login"] = login
}
To reflect for the edit in the question: without knowing the exact structure of the dictionary, you cannot modify it as you wish. Anyways, modifying a JSON dictionary directly is really bad practice.
Parse the JSON response into a custom object, modify the object as you wish, then encode the object back to JSON and use it as your request's body.
If you don't want to write the JSON parsing function yourself, have a look at ObjectMapper. It can both map a JSON response to objects and can also map an object to JSON.
you cannot directly "append" new values to a dinamic dictionary without knowing the type and content.
Since
dict["login"]
returns you a Any? you have no way to directly manipulate it.
Do you have any ideas of the possible combinations of the content of each dictionary leaf?
you could write a recursive methods that tries to downcast the content of the leaf and base on it, try to do something
switch dict["login"] {
case is [String: Any?]:
// check that the key does not already exist, to not replace it
case is [Int: Any?]:
// Do something else
}

Value of type 'String' does not conform to expected dictionary value type 'AnyObject'

I am getting this error when creating a dictionary in Swift:
Value of type 'String' does not conform to expected dictionary value
type 'AnyObject'
Code:
let joeSmith : [String : AnyObject] = ["Name" : "Joe Smith", "Height" : 42, "Soccer Expo" : true, "Guardian" : "Jim and Jan Smith"]
Swift 3
First of all a String in Swift is a struct and does not conform to AnyObject.
Solution #1
The best solution in Swift 3 is changing the type of the Dictionary Value from AnyObject to Any (which includes the String struct).
let joeSmith : [String : Any] = ["Name" : "Joe Smith", "Height" : 42, "Soccer Expo" : true, "Guardian" : "Jim and Jan Smith"]
Solution #2
However if you really want to keep the value fo the Dictionary defined as AnyObject you can force a bridge from the String struct to the NSString class adding as AnyObject as shown below (I did the same for the other values)
let joeSmith : [String : AnyObject] = [
"Name" : "Joe Smith" as AnyObject,
"Height" : 42 as AnyObject,
"Soccer Expo" : true as AnyObject,
"Guardian" : "Jim and Jan Smith" as AnyObject]
Swift 2
The problem here is that you defined the value of your dictionary to be AnyObject and String in Swift is NOT an object, it's a struct.
The compiler is complaining about String because is the first error but if your remove it, it will give you an error for the 42 which again is an Int an then a Struct.
And you will have the same problem with true (Bool -> Struct).
You can solve this problem in 2 ways:
Foundation #1
If you add import Foundation then the Swift struct is automatically bridged to NSString (which is an object) and the compiler is happy
Any #2
You replace AnyObject with Any. Now you can put any kind of value in your dictionary.
Considerations
IMHO we (Swift developers) should progressively stop relying on Objective-C bridging and use the second solution.
used it will helpfull
let plistDict: [String: Any] = ["key": "Value"]
OMHO If you are using Any or AnyObject you are missint the point of using a strongly typed language
because enums in swift can hold associated data a good answer here is to change the way you are using the language and create an enum that captures the different cases then use the enum as a type.
If the dictionary is actualy representing a class of its own than maybe you need to define the class.
either way what yo are doing should scream to you that something is wrong with your code.
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html

Dictionary Values in Swift

I am trying to access values I've set in a Swift dictionary. The dictionary has a String for the keys and values. My intent is to use the dictionary to set a string variable as I work through a series of URLs. In Objective-C I understand how this works. I have a string property called currentFeed that I pass the value of the dictionary to.
self.currentFeed = [NSString stringWithString: [self.URLDictionary objectForKey: #"FLO Cycling"]];
In Swift I am having a difficult time with this. I tried the following code and receive an error message.
self.currentFeed = self.URLDictionary["FLO Cycling"]
Error Message: "Cannot subscript a value of type '[String:String]' with an index of type 'String'.
For reference the dictionary was created in Swift in the following way. The constants were created with lets.
let kFLOCyclingURL = "http://flocycling.blogspot.com/feeds/posts/default?alt=rss"
let kTriathleteURL = "http://triathlon.competitor.com/feed"
let kVeloNewsURL = "http://velonews.competitor.com/feed"
let kCyclingNewsURL = "http://feeds.feedburner.com/cyclingnews/news?format=xml"
let kRoadBikeActionURL = "http://www.roadbikeaction.com/news/rss.aspx"
let kIronmanURL = "http://feeds.ironman.com/ironman/topstories"
The items were added to the dictionary with keys.
let URLTempDictionary = ["FLO Cycling" : kFLOCyclingURL, "Triathlete" : kTriathleteURL, "Velo News" : kVeloNewsURL, "Cycling News" : kCyclingNewsURL, "Road Bike Action" : kRoadBikeActionURL, "Ironman" : kIronmanURL]
Thanks for any help.
Take care,
Jon
This compiles fine for me. The only thing I noticed was that your dictionary is named URLTempDictionary and you're accessing URLDictionary. :)
Option a (safest, most robust)
if let dict = self.URLDictionary
{
self.currentFeed = dict["FLO Cycling"]
}
Option b (use with caution, possible runtime error)
self.currentFeed = dict!["FLO Cycling"]

Can't assign String to AnyObject?

Ok, this is a weird one. I'm looping through an array of what apparently is a Dictionary<String, AnyObject?!> (notice the ?!, it's not a typo). I'm trying to assign a String to one of its keys, but it's not working and I get the weird error below.
Has anyone seen anything like this?
Edit:
Some extra info: even the debugger says it's an AnyObject?!:
You cannot apply the Dictionary syntax on an Array.
Try this:
if var dict = fields as? [String: String]{
dict["test"] = "test"
}

Why I can not use SetValue for Dictionary?

Hello Everyone I am new in swift and In my app I declare a dictionary like this :
var imageDict : Dictionary<String, String> = [:]
and I want to set values for that dictionary like this :
imageDict.setValue(NSStringFromCGPoint(frame), forKey: NSString.stringWithString("/(tagValue)"));
But I got error like this :
Dictonary <String, String> does not have a member named 'setValue'
This question is from my previous question and can enybody explain my why I can not set value for that dictionar and can enybody tell me any other way to do that?
Thanks In advance.
Swift dictionary does not have method like setValue:forKey:. Only NSMutableDictionary has such methods. If you wish to assign value for key in swift, you should use subscripting. Here is the correct way to do it, if you wish to do it with swift dictionary.
var imageDict:[String: String] = [:]
imageDict["\(tagValue)"] = NSStringFromCGRect(frame)
Or if you wish to use NSMutableDictionary then, it looks like this,
var imageDict = NSMutableDictionary()
imageDict.setObject(NSStringFromCGRect(frame), forKey: "\(tagValue)")
I guess you need to use NSMutableDictionary.