Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

grandM

macrumors 68000
Original poster
Oct 14, 2013
1,551
309
So guys, I'm back with yet another question. I have two tables in my Core Data Stack. One of them is called BookCategory with attribute name. The other is called Book with attribute name. BookCategory has a relationship to Book called books. Book has a relationship to BookCategory called category. I'm trying to start from BookCategory and show all the books which name contains a specific character. My books array keeps returning nil. The names of the book do contain the character though. What am I doing wrong? Thanks again!

Code:
func booksContainingTheLetter(letter: String) {

        let fetchRequest = NSFetchRequest(entityName: "BookCategory")
//        let text = NSExpression(forKeyPath: "books.name")
//        let i = NSExpression(forConstantValue: "i")
//        let predicate = NSComparisonPredicate(leftExpression: text, rightExpression: i, modifier: NSComparisonPredicateModifier.AnyPredicateModifier, type: NSPredicateOperatorType.ContainsPredicateOperatorType, options: NSComparisonPredicateOptions.CaseInsensitivePredicateOption)

        let predicate = NSPredicate(format: "books.name contains %@", letter)

        fetchRequest.predicate = predicate
        var books: [Book]?
        do {
            books = try self.managedObjectContext.executeFetchRequest(fetchRequest) as? [Book]
        } catch {
            print("No book has the letter \(letter) in its name")
        }
 

        for book in books as [Book]! {

            print("Book is titled \(book.name!)")

        }

     

    }
 
Last edited:
I figured it out!
Code:
let fetchRequest = NSFetchRequest(entityName: "BookCategory")

       

//        let text = NSExpression(forKeyPath: "books.name")

//        let i = NSExpression(forConstantValue: "i")

//        let predicate = NSComparisonPredicate(leftExpression: text, rightExpression: i, modifier: NSComparisonPredicateModifier.AnyPredicateModifier, type: NSPredicateOperatorType.ContainsPredicateOperatorType, options: NSComparisonPredicateOptions.CaseInsensitivePredicateOption)

        print("\(letter)")

        let predicate = NSPredicate(format: "books.name contains[cd] %@", letter)

        fetchRequest.predicate = predicate

       

        var categories: [BookCategory]?

        do {

            categories = tryself.managedObjectContext.executeFetchRequest(fetchRequest) as? [BookCategory]

        } catch {

            print("geen categorie")

        }

       

        for categorie in categories! {

            print("de categorie heet \(categorie.name!)")

        }
 
If you were to find that the case insensitive search is too slow one option would be to add another attribute to your entity that lowercased the book title. Searching that attribute using contains should work and might be faster if your character is also lowercased.
 
  • Like
Reactions: grandM
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.