Florian Ldt
Florian Ldt

Reputation: 1235

Swift & Firebase - Could not cast value of type '__NSDictionaryM'

I am using Swift with Firebase and I am a little bit confused with this error : Could not cast value of type '__NSDictionaryM' (0x122ab6130) to 'Repeat.Expression' (0x1100004c0).

Here is a sample of the JSON file I use :

{
  "levels" : {
    "level1" : {
      "coverImage" : "lvl1",
      "expressions" : [ {
        "expression" : "Yes",
        "id" : 0
      }, {
        "expression" : "Yes",
        "id" : 1
      }, {
        "expression" : "Yes",
        "id" : 2
      }, {
        "expression" : "Yes",
        "id" : 3
      } ],
      "id" : 0,
      "title" : "Essentiel"
    },
    "level2" : {
      ...
    },
  }
}

Here are the two models I use :

struct Level {
    let id : Int
    let coverImage : String
    let title : String
    let expressions : [Expression]
}

struct Expression {
    let id : Int
    let expression : String
}

Finally, here is the function I use to fetch the levels :

var levels = [Level]()

func fetchLevels() {

        FIRDatabase.database().reference().child("levels").observe(.childAdded, with: { (snapshot) in

            if let dictionary = snapshot.value as? [String: AnyObject] {

                if let levelId = dictionary["id"], let levelCoverImage = dictionary["coverImage"], let levelTitle = dictionary["title"], let levelExpressions = dictionary["expressions"] {
                    let level = Level(
                        id: levelId as! Int,
                        coverImage: levelCoverImage as! String,
                        title: levelTitle as! String,
                        expressions: levelExpressions as! [Expression]
                    )
                    self.levels.append(level)
                }


                DispatchQueue.main.async{
                  self.collectionView?.reloadData()
                }


            }
        }, withCancel: nil)
    }

It appears that the problem is at the line expressions: levelExpressions as! [Expression]

Thank you very much for your help.

Have a good day.

Upvotes: 0

Views: 1162

Answers (1)

iAviator
iAviator

Reputation: 1447

let levelExpressions = dictionary["expressions"]

The above line returns array of dictionaries i.e.[[String:Any]] and needs to require that value to be mapped into your struct Expression.This can be done in 2 ways:-

1) You can use ObjectMapper to typecast the return value of above code.

2) Manually allocate the Expression object by parsing the return values of let levelExpressions = dictionary["expressions"] as! [[String:Any]] and assigning them to properties id and expression

Upvotes: 1

Related Questions