Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getting "fatal error: NSArray element failed to match the Swift Array Element type" when trying to read values from an array of class objects

Tags:

ios

swift

swift2

There is an issue that i can't understand and can not find an answer to: i have this method in a tableViewCOntroller that is calling another viewCOntroller with TableView inside it

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "ShowBook" {
        if let selectedIndexPath = tableView.indexPathForSelectedRow {
            let books = categoryStore.allCategories[selectedIndexPath.row].books

            let destinationVC = segue.destinationViewController as! BookViewController
            destinationVC.books = books
        }
    }
}

Then in the BookViewController i have this just for testing:

var books = [Book]()

override func viewDidLoad() {
    super.viewDidLoad()

    print(books[0].name)
}

I can see that the books var is an array that is holding books:

class Book {
var name: String = ""
var id: Int = -1
var categoryId: Int = -1
var bookAuthor: String = ""
var level1Name: String = ""
var level2Name: String = ""
var level3Name: String = ""
var level4Name: String = ""
var levels: Int = -1
var orderKey: Int = -1
var viewCount: Int = -1
var viewLevel: Int = -1
var chapters: [AnyObject] = []

}

so i am getting an array of books with 13 key/value pairs dictionary in the books var

when i'm trying to print any thing, lets say:

print(books[0].name)

I get the error:

fatal error: NSArray element failed to match the Swift Array Element type

and i can't understand why...

p.s The transition is working and i can see the next table but then getting the fatal error

enter image description here

like image 323
Erez Avatar asked May 21 '16 10:05

Erez


1 Answers

Ok, let's start with your error.

fatal error: NSArray element failed to match the Swift Array Element type

A swift array is complaining that one of it's elements is not what it's expecting. The NSArray element does not match the swift array element.

Now we know that a NSArray can store different types of elements, for example, NSNumber, NSDictionary, NSString... you get the picture. So clearly our issue here is type related.

Now looking at your segue code we can see that we do not actually state what type books is, we let swift's type inference work it out for us. This is where our first sign of the issue occurs. You are expecting an array of [Book] but for some reason you are getting a type of NSArray.

If you make the change from:

let books = categoryStore.allCategories[selectedIndexPath.row].books
let books : [Book] = categoryStore.allCategories[selectedIndexPath.row].books

You will now crash at this line, because you are now stating the type expected.

Full Method:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "ShowBook" {
        if let selectedIndexPath = tableView.indexPathForSelectedRow {
            let books : [Book] = categoryStore.allCategories[selectedIndexPath.row].books

            let destinationVC = segue.destinationViewController as! BookViewController
            destinationVC.books = books
        }
    }
}

This is backed up by your debugger console output, it says that you have an array of 13 NSDictionary types.

This means you need to investigate where you populate the [Book] array - i.e. categoryStore.allCategories

like image 144
Peter Hornsby Avatar answered Oct 06 '22 00:10

Peter Hornsby