Where clause missing CONTAINS comparison option #435

Closed
opened 2025-12-29 15:31:43 +01:00 by adam · 5 comments
Owner

Originally created by @vovsyannikov on GitHub (Jun 20, 2024).

In my project there's a stored property with search info. What I would like to do is fetch all the objects that contains some searchable string. Right now the only way I see doing it is through unsafe NSPredicate where I can't even user #keyPath(Document.searchInfo) to alleviate some of the risks

public func count(where predicate: Where<DBS.Document>, searchString: String? = nil) -> Int {
    do {
        var wholePredicate = predicate

        if let searchString, searchString.isEmpty == false {
            let searchPredicate = NSPredicate(format: "searchInfo CONTAINS %@", string)
            wholePredicate = wholePredicate && Where(searchPredicate)
        }
        
        let count = try transaction.fetchCount(
            From<DBS.Document>()
                .where(wholePredicate)
        )
        return count
    } catch {
        print("Error fetching document count: \(error.localizedDescription)")
        return 0
    }
}

Am I missing something or is it the only way of handling CONTAINS in CoreStore?

Originally created by @vovsyannikov on GitHub (Jun 20, 2024). In my project there's a stored property with search info. What I would like to do is fetch all the objects that contains some searchable string. Right now the only way I see doing it is through unsafe `NSPredicate` where I can't even user `#keyPath(Document.searchInfo)` to alleviate some of the risks ```Swift public func count(where predicate: Where<DBS.Document>, searchString: String? = nil) -> Int { do { var wholePredicate = predicate if let searchString, searchString.isEmpty == false { let searchPredicate = NSPredicate(format: "searchInfo CONTAINS %@", string) wholePredicate = wholePredicate && Where(searchPredicate) } let count = try transaction.fetchCount( From<DBS.Document>() .where(wholePredicate) ) return count } catch { print("Error fetching document count: \(error.localizedDescription)") return 0 } } ``` Am I missing something or is it the only way of handling `CONTAINS` in CoreStore?
adam closed this issue 2025-12-29 15:31:43 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Jun 21, 2024):

Yes, the type-syntax utilities are currently missing several predicate features. You can always write the raw String format for now, but as it is I'm still observing how the SwiftData utilities are evolving to see which ones we can hook up with CoreStore.

As always, if you have proposed implementations feel free to submit a PR.

@JohnEstropia commented on GitHub (Jun 21, 2024): Yes, the type-syntax utilities are currently missing several predicate features. You can always write the raw String format for now, but as it is I'm still observing how the SwiftData utilities are evolving to see which ones we can hook up with CoreStore. As always, if you have proposed implementations feel free to submit a PR.
Author
Owner

@JohnEstropia commented on GitHub (Jun 21, 2024):

Just a tip though, you can use %K so that you can still take advantage of #keyPath:

NSPredicate(format: "%K CONTAINS %@", #keyPath(Document.searchInfo), string)
@JohnEstropia commented on GitHub (Jun 21, 2024): Just a tip though, you can use `%K` so that you can still take advantage of `#keyPath`: ```swift NSPredicate(format: "%K CONTAINS %@", #keyPath(Document.searchInfo), string) ```
Author
Owner

@vovsyannikov commented on GitHub (Jun 21, 2024):

Just a tip though, you can use %K so that you can still take advantage of #keyPath:

NSPredicate(format: "%K CONTAINS %@", #keyPath(Document.searchInfo), string)

Yes I am aware of such method. However that's the problem: I get en error that searchInfo is not @objc marked. It's a @Field.Stored property so it seems that stringly typed NSPredicate is the only way out

@vovsyannikov commented on GitHub (Jun 21, 2024): > Just a tip though, you can use `%K` so that you can still take advantage of `#keyPath`: > > ```swift > NSPredicate(format: "%K CONTAINS %@", #keyPath(Document.searchInfo), string) > ``` Yes I am aware of such method. However that's the problem: I get en error that `searchInfo` is not `@objc` marked. It's a `@Field.Stored` property so it seems that stringly typed `NSPredicate` is the only way out
Author
Owner

@JohnEstropia commented on GitHub (Jun 21, 2024):

Ah, I see. Sorry, I thought your model was using the NSManagedObject mode. For the CoreStoreObject subclasses, you can do this instead:

NSPredicate(format: "%K CONTAINS %@", String(keyPath: \Document.$searchInfo), string)
@JohnEstropia commented on GitHub (Jun 21, 2024): Ah, I see. Sorry, I thought your model was using the `NSManagedObject` mode. For the `CoreStoreObject` subclasses, you can do this instead: ```swift NSPredicate(format: "%K CONTAINS %@", String(keyPath: \Document.$searchInfo), string) ```
Author
Owner

@vovsyannikov commented on GitHub (Jun 21, 2024):

Ah, I see. Sorry, I thought your model was using the NSManagedObject mode. For the CoreStoreObject subclasses, you can do this instead:

NSPredicate(format: "%K CONTAINS %@", String(keyPath: \Document.$searchInfo), string)

Oooh. That's neat. Thanks!

@vovsyannikov commented on GitHub (Jun 21, 2024): > Ah, I see. Sorry, I thought your model was using the `NSManagedObject` mode. For the `CoreStoreObject` subclasses, you can do this instead: > > ```swift > NSPredicate(format: "%K CONTAINS %@", String(keyPath: \Document.$searchInfo), string) > ``` Oooh. That's neat. Thanks!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#435