Shocked how little documentation there is for this method!
fetchrequestfromtemplate
I can create fetch requests in code. HOWEVER! I would like to store a fetchRequest template in the xcdatamodeld file in my iOS app.
Have a simple entity "State" with one attribute "Name".
Added a FetchRequest named "newStates" to the xcdatamodeld file using the format
(mom = core data's managed object model)
newStatesRequest is a proper, simple fetch request.
Because it is a proper fetch request, this runs fine.
However, I would like to substitute variables! So I added a different FetchRequest to xcdatamodeld named "byName" using this format
Substitution variables is [String: Any] in the documentation. Documentation says my fetch request's predicate (byNameRequest.predicate) should be
I have tried dozens of variations. Would be pleased if a Core Data boffin could provide a clean, working example!
fetchrequestfromtemplate
I can create fetch requests in code. HOWEVER! I would like to store a fetchRequest template in the xcdatamodeld file in my iOS app.
Have a simple entity "State" with one attribute "Name".
Added a FetchRequest named "newStates" to the xcdatamodeld file using the format
I can execute fetchRequestFromTemplate method in code like this:name begins with New
Code Block newStatesRequest = mom.fetchRequestFromTemplate(withName: "newStates", substitutionVariables [null: null])
(mom = core data's managed object model)
newStatesRequest is a proper, simple fetch request.
Because it is a proper fetch request, this runs fine.
However, I would like to substitute variables! So I added a different FetchRequest to xcdatamodeld named "byName" using this format
In code I tried:name begins with $NAME
Code Block let thisState = "North" byNameRequest = mom.fetchRequestFromTemplate(withName: "byName", substitutionVariables: ["$NAME" : thisState])
Substitution variables is [String: Any] in the documentation. Documentation says my fetch request's predicate (byNameRequest.predicate) should be
but it's returned to me asname begins with North
Substitution is not working for me. I fear I am not wiring up the variable names with the substitution dictionary. Dollar signs? No dollar signs? Quotes? No quotes?name begins with $NAME
I have tried dozens of variations. Would be pleased if a Core Data boffin could provide a clean, working example!
Here's the solution I found.
First, you can create predicates in the core data modeler using pick lists. Very easy to say you want all states that begin with "New". Or all sodas that contain "Cola". But these are static fetch requests.
What if you'd like to insert a varible?
In this case, you need to select the Custom Predicate in the data modeler. Don't use the convenient pull down predicate builder. Use the Custom Predicate. Then you have to craft a predicate that conforms to NSPredicate syntax AND holds your variables.
Here's an example:
Code Block name BEGINSWITH $ARTISTS_NAME // This is the custom predicate in the xcdatamodeld file.
Please note the variable begins with a $.
Now that this template is stored in your xcdatamodeld file in your project, you can extract the fetch request template with code, and substitute variables harvested from your awesome SwiftUI interface! Sweet!
Code Block let fetchTemplate = "byArtist" // this is the name in the xcdatamodeld file. let subs = ["ARTISTS_NAME" : "Taylor Swift"] // A favorite example let fetchRequest = mom.fetchRequestFromTemplate(withName: fetchTemplate, substitutionVariables: subs) print ("Predicate is: \(fetchRequest.predicate)")
This will return a proper fetchRequest with the predicate: name BEGINSWITH "Taylor Swift"
Please Note! You must include the $ before the variable name IN THE xcdatamodeld file. BUT you do NOT include the $ in the substitution dictionary. Not sure why. I hope a core data boffin might explain this? Seems a relic leftover from printf days.
How To Improve the Documentation:
1. Spell it out! If developers want to include variables in their templates, let them know they MUST use the custom predicate.2. Give an example, or three! An example is a painless way to convey the dictionary's key does not have the $ used in the custom predicate. Maybe explain this with a humorous footnote.
3. Share the use case. Seems this is a convenient way to encapsulate fetch requests along with the data model. Is it more efficient? Are there other clever uses for storing fetch requests in the xcdatamodeld file?