简体   繁体   中英

Could not cast value of type 'Swift.Array<Any>' to 'Swift.Dictionary<Swift.String, Any>'

I have the following dictionary that I am placing in an array.

//Collections
var myShotArray      = [Any]()
var myShotDictionary = [String: Any]()

myShotDictionary = ["shotnumber": myShotsOnNet, "location": shot as Any, "timeOfShot": Date(), "period": "1st", "result": "shot"]

myShotArray.append(myShotDictionary as AnyObject)

I then pass the array over to my tableview

myGoalieInforamtionCell.fillTableView(with: [myShotArray])

In my TableView

   var myShotArray = [Any]()

   func fillTableView(with array: [Any]) {
        myShotArray = array
        tableView.reloadData()

        print("myShotArray \(myShotArray)")
    }

   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell            = Bundle.main.loadNibNamed("ShotInformationTableViewCell", owner: self, options: nil)?.first as! ShotInformationTableViewCell

        let positionInArray = myShotArray[indexPath.row] as! [String : Any]  //Could not cast value of type 'Swift.Array<Any>' (0x103991ac0) to 'Swift.Dictionary<Swift.String, Any>' (0x1039929b0).

        cell.myGoalieShotInformationShotNumberLabel.text = positionInArray["shotnumber"]! as? String

        return cell
    }

Why do I get the above error the subject?

Thanks in advance.

When you call myGoalieInforamtionCell.fillTableView you are passing [myShotArray] - those square brackets mean that you have put myShotArray inside another array, so what you are actually passing to fillTableView is [[[String:Any]]] - an array of array of dictionary.

You can fix your immediate problem by simply removing those brackets;

myGoalieInforamtionCell.fillTableView(with: myShotArray)

However, you have way too many Any 's there. You should take advantage of Swift's strong typing, which will avoid this sort of error.

I would suggest that you use a Struct rather than a dictionary for your data and then you can type things correctly. Something like:

enum Period {
    case first
    case second
    case third
    case fourth
}

struct ShotInfo {
    let shotNumber: Int
    let location: String // Not sure what this type should be
    let timeOfShot: Date
    let period: Period
    let result: Bool
}

var myShotArray = [ShotInfo]()

let shot = ShotInfo(shotNumber: myShotsOnNet, location: shot, timeOfShot: Date(), period: .first, result: true}

myShotArray.append(shot)

myGoalieInforamtionCell.fillTableView(with: myShotArray)

func fillTableView(with array: [ShotInfo]) {
    myShotArray = array
    tableView.reloadData()

    print("myShotArray \(myShotArray)")
}

If you have this and you mistakenly said fillTableView(with: [myShotArray]) Xcode will tell you straight away that you have a mismatch between the argument type and the expected type which is much better than discovering your error at run time when your program crashes.

Here:

myGoalieInforamtionCell.fillTableView(with: [myShotArray])

You're wrapping your array in an additional array, so you are getting your array instead of your dictionary when you access it to populate your cell.

It should just be:

myGoalieInforamtionCell.fillTableView(with: myShotArray)

At a minimum you should be declaring myShotArray as [[String: Any]] and changing the parameter to fillTableView to also be [[String: Any]] so that the compiler would catch this mistake. It would also allow you to remove the force cast that is throwing your error.

You should really be creating a struct/class and passing an array of those instead of dictionaries though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM