0

I have a problem trying to create a JSON object. Everything is fine until I try to create a second level element with nil values:

var json = [String: AnyObject]()
json["id"] = 1234567

let secondLevel : [String: AnyObject] = ["i1": 12, "i2": "not nil"]
json["secondLevel"] = secondLevel

This is fine, but if I try:

let secondLevel : [String: AnyObject?] = ["i1": 12, "i2": nil]
json["secondLevel"] = secondLevel

I got the following error:

cannot assign a value of type '[String : AnyObject?]' to a value of type 'AnyObject?'

What does it means? Isn't a [String:AnyObject?] of AnyObject type?

What could I do to avoid this error?

Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
Antonio Romano
  • 285
  • 3
  • 13
  • I tried `json["secondLevel"] = secondLevel as? AnyObject` but threaded the whole `secondLevel` object as nil, so not good – Antonio Romano Jul 15 '15 at 10:22
  • I don't know at priori the value of the element, null is a value in JSON standard. By the way i don't understand your previous comment – Antonio Romano Jul 15 '15 at 10:25

3 Answers3

4

You can use Any instead of AnyObject

Type Casting for Any and AnyObject

Swift provides two special type aliases for working with non-specific types:

AnyObject can represent an instance of any class type. Any can represent an instance of any type at all, apart from function types.

NOTE: Use Any and AnyObject only when you explicitly need the behavior and capabilities they provide. It is always better to be specific about the types you expect to work with in your code.

From The Swift Programming Language

var json = [String: Any]()
json["id"] = 123452

let secondLevel : [String: Any?] = ["i1": 12, "i2": nil]
json["secondLevel"] = secondLevel

print(json)
Community
  • 1
  • 1
Tikhonov Aleksandr
  • 13,945
  • 6
  • 39
  • 53
0

The key was not use Any instead of AnyObject, I couldn't change the type. The solution is to use an object to manipulate nil value like:

let secondLevel : [String: AnyObject] = ["i1": 12, "i2": NSNull()]
json["secondLevel"] = secondLevel
Antonio Romano
  • 285
  • 3
  • 13
0

You should probably check out the following links:

Here they mention why your code does not work. The first link demonstrates how you can properly create a dictionary object containing multiple nested dictionaries.

The second link will show you why your code does not work. It seems the dictionary object is a struct, not a class. A struct does not inherit from the AnyObject class. Hence you can not cast a dictionary to an AnyObject object. Perhaps you should use an NSDictionary object instead as suggested in the second link.

What I mean by using NSDictionary:

var secondLevel: NSDictionary = [
    "i1" : 12,
    "i2" : "not nil"
]

var json: [String: AnyObject] = []
json["id"] = 1234567
json["secondLevel"] = secondLevel
Community
  • 1
  • 1
Orion
  • 1,258
  • 2
  • 14
  • 32
  • Since I use an external library (Alamofire) I have to use `[String: AnyObject]`, is a precondition. – Antonio Romano Jul 15 '15 at 11:30
  • So instead of trying to put nested dictionaries (struct -> [String : AnyObject]) into the AnyObject, you might just be better off using NSDictionary. Note that if you're trying to add objects to the NSDictionary, you have to use NSMutableDictionary instead. – Orion Jul 15 '15 at 11:50