0

I have a .json file that I am serializing into a Swift dictionary.

typealias Dict = Dictionary<String,AnyObject>
       func loadDictionaryFromJSON(filePath:String) -> Dict
    {
        var JSONData:NSData! = NSData.dataWithContentsOfMappedFile(filePath) as NSData
        var JSONError:NSError?
        let swiftObject:AnyObject = NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions.AllowFragments, error: &JSONError)!
        if let nsDictionaryObject = swiftObject as? NSDictionary
        {
            if let dictionaryObject = nsDictionaryObject as Dictionary?
            {
                return dictionaryObject as Dict
            }else
            {
                println("Error could not make dictionary from NSDictionary in \(self)")
            }
        }else
        {
            "Error could not make NSDictionary in \(self)"
        }

        println("Empty dictionary passed, fix it!")
        return Dict()
    }

However, I am having trouble getting the objects this now. My .json is basically a dictionary of dictionaries (with various levels of nesting). So to start I am grabbing each object in the top level (which are all dictionaries).

for object in objects
        {
            var dict:Dictionary<String,AnyObject> = object
        }

However, the above line throws the error

(key: AnyObject, value: AnyObject)' is not convertible to 'Dictionary<String, AnyObject>

How can I properly cast each object in my Dictionary to a Dictionary <String,AnyObject>?

Aggressor
  • 13,323
  • 24
  • 103
  • 182

2 Answers2

0

Angled brackets are archaic Swift AFAICT (except in protocols?) Why do you need the type alias? And if you create it, why are you not using it in your loop?

Can you drop the alias and the angled brackets and use the [:] format everywhere and see what happens?

For example, does the following work better?

for o in objects {
    var dict = o as [String : AnyObject]
}

If objects is already typed you could just call it dictionary and do:

for dict in dictionaries {
    continue
}
clearlight
  • 12,255
  • 11
  • 57
  • 75
  • Also if objects is already downcast to [String : AnyObject], you shouldn't need to downcast it at all. I prefer to rely on getting type of the receiver in a var definition from the source whenever possible. For example if you say var lbl = UILabel(), lbl will implicitly be defined as though you wrote var lbl : UILabel = UILabel() or var lbl = UILabel() as UILabel or some other pointless overkill construct :-) – clearlight Feb 25 '15 at 21:11
  • Thanks but this does not work. I did some looking around and it turns out Im trying to cast a tuple as a dictionary. Im going through it now using (key,value). http://stackoverflow.com/questions/26890565/key-anyobject-value-anyobject-does-not-have-a-member-named-subscript – Aggressor Feb 25 '15 at 21:12
  • tuples and thruples definitely aren't dictionaries. Glad you figured that out. After programming in Swift arduously for 3 or 4 months when I look at Objective C now I want to vomit :-) I love the flexibility and ease and succinctness of Swift over all, but it does, like any languages, have its limitations and annoyances. – clearlight Feb 25 '15 at 21:17
  • Yes swift is miles ahead of objc, but there are some major features and bugs at present. All the crashes I get while dealing with JSON serializations are crashing my xcode :( and no refactoring also sucks! But in 1 years time Im sure they can get swift up to speed – Aggressor Feb 25 '15 at 21:24
  • Swift 1.2 has cool changes, but Xcode 6.3/swift 1.2 is buggiest so far. I have been using using Stephen Celis' SQLite for Swift https://github.com/stephencelis/SQLite.swift (excellent port!!!!) and it works flawlessly under Xcode 6.2 beta, but crashes (due to Swift memory bugs, according to the author who's filed a rdar, and which Apple has updated Swift since then) in Xcode 6.3 beta/Swift 1.2. But 6.3 is way ahead of the curve so if you're working with that you're really working on treacherous ground. – clearlight Feb 25 '15 at 21:31
0
for (key,value) in objects
        {
            var object:Dict = value as Dict
        }

It turns out it was giving me a tuple and I needed to cast the value as a Dictionary.

See '(key: AnyObject, value: AnyObject)' does not have a member named 'subscript' for more info.

Community
  • 1
  • 1
Aggressor
  • 13,323
  • 24
  • 103
  • 182