Search code examples
swiftswiftuicore-data

Can Core Data @fetchreqeust a specific field?


Is there a concise way to only pull back a single field from a @fetchreqeust so I can see if a specific id (UUID) exists the results of the @fetchrequest from Core Data?

I have a request which brings back a list of tokens, each having an id which is a UUID:

@FetchRequest(sortDescriptors: [SortDescriptor(\.id)])
var tokens: FetchedResults<Token>

and I am trying to create a function to see if the token has been downloaded already which should look something like this:

func isDownloaded(tokenId: UUID) -> Bool {
    
    return tokens.contains(tokenId)
}

Can I change the @fetchrequest to just pull back a list of the Token id's? When I do something like this:

@FetchRequest(sortDescriptors: [SortDescriptor(\.id)])
var tokens: FetchedResults<Token.ID>

I get an error:

Type 'Token.ID' (aka 'Optional') does not conform to protocol 'NSFetchRequestResult'

I saw this post for checking to see if a record exists before inserting it, but that's not what I am looking to do. I need the list of id's I have already downloaded into core data so I don't even allow the user to download the token. So I wanted to check, as I am looping through the list to display, to see if I should enable the download button or not. Doing a fetch each time seems cumbersome.

UPDATE

Based on @joshgalv's response and @JoakimDanielson's comments ended with this:

func isDownloaded(tokenId: UUID) -> Bool {
    tokens.contains(where: { $0.id == tokenId })
}

Solution

  • You may be able to combine this @FetchRequest initializer:

    init(fetchRequest: NSFetchRequest<Result>, animation: Animation? = nil)
    

    with this stackoverflow post. This would allow you to create a custom NSFetchRequest that would only query a single column of your object and allow you to pass that into your @FetchRequest instead. I haven't tried this but I think it would work.

    With that said I do think it would be easier to just use a regular @FetchRequest and get the property via managedObject.id in whatever case you want to use it, and I don't think you'd be saving much performance by only querying a single column.