JAH-FH
JAH-FH

Reputation: 119

Using filter on Swift Array gives "cannot invoke filter with an argument list of type (Object) throws -> Bool," but the argument doesn't throw

I'm having trouble figuring out exactly what kind of argument list Swift is expecting here, because I am getting an error when I call "filter" on a swift array.

Here is my code:

func setDefaultBook()
{
    var book: Book

    let fetchRequest: NSFetchRequest<Book> = Book.fetchRequest()
    if let fetchResults = try? managedObjectContext.fetch(fetchRequest) {
        book = fetchResults.filter { $0.title == defaultBookTitle }
    }

    ...
}

A book is an NSManagedObject, and a book's title is a simple String property - an @NSManaged var. There is nothing special about the title here, and there's nothing to indicate that checking a title would throw. However, I get an error on the filter line that says:

"Cannot invoke 'filter' with an argument list of type '((Book) throws -> Bool)'

Clearly I'm missing something, because this comparison doesn't look to me like it would ever throw. I've tried a couple of other ways of doing this, and I keep getting the same error.

Building out the closure like so doesn't help:

book = fetchResults.filter { book in
    book.title == defaultBookTitle
}

And setting a predicate to do the same thing doesn't help either:

let predicate: (Book) -> Bool = { $0.title == self.defaultBookTitle }
book = fetchResults.filter(predicate)

I keep getting the same error as before.

Anyone have any idea why swift thinks that the argument here is (Book) throws -> Bool instead of just (Book) -> Bool?

Has anyone run into this error before? Any suggestions to fix it are appreciated.

Upvotes: 3

Views: 687

Answers (1)

vadian
vadian

Reputation: 285069

The error message might be misleading. The result of filter is always an array

var books = [Book]()

let fetchRequest: NSFetchRequest<Book> = Book.fetchRequest()
if let fetchResults = try? managedObjectContext.fetch(fetchRequest) {
    books = fetchResults.filter { $0.title == defaultBookTitle }
}

But why not let Core Data filter the records:

var books = [Book]()

let fetchRequest: NSFetchRequest<Book> = Book.fetchRequest()
fetchRequest.predicate = NSPredicate(format:"title = %@", defaultBookTitle)
do {
   books = try managedObjectContext.fetch(fetchRequest)
} catch {
  print(error)
}

Upvotes: 6

Related Questions