NEW: Learn to build amazing SwiftUI apps for macOS with my new book! >>

SOLVED: Core Data: Fetch Requests Templates in the XCDataModelD. How to substitute values for placeholders?

Forums > Swift

So we all use the core data "data model" file to create entities, their properties, and their relationships. Paul has several great articles and videos on how to do this.

Did you know that you can also embed fetch requests as templates into the data model?

Not sure how to provide graphic here. I am not clever enough to figure this out.

Then you can use the method fetchRequestFromTemplate(withName:) to pull the template from the model and execute it. I don't see this feature discussed in blogs or in 'how to' videos.

This is where I am stumped. I would like to have a template in the core data 'data model' file. I'd like the template to hold a variable, in this example called "NAME".

Then, in code, I want to pull text from a TextField and pass it TO THE TEMPLATE. I'd like the template to substitute my text value for the placeholder (NAME) and execute the fetchRequest.

How? How do I substitute my variable for the placeholder? This should be easy, but I am not clever enough to figure this out.

func getByName(name: String) {
      let substitute = ["NAME" : name]  // HOW DO I DO THIS PART ?      NAME   or $NAME  
      let byName = getFetchRequest(withName: "byName", variables: substitute) as? NSFetchRequest<Group>
      do {
          groups = try manager.context.fetch(byName!)
      } catch let error {
          print("Bungled the fetch template. \(error.localizedDescription)")
      }
  }

// Works great with templates that have hard coded values. But, I'd like to provide values via placeholders....
func getFetchRequest(withName name: String, variables: [String : Any]) -> NSFetchRequest<NSFetchRequestResult>? {
      // mom is the Managed Object Model
      // this should select the template from the data model and substitute values for the placeholders.
      // This line should return a fetch request, but fails.
      let fetchRequest = mom.fetchRequestFromTemplate(withName: name, substitutionVariables: variables)
      return fetchRequest
  }

1      

Paul wrote an excellent piece asking Apple to provide code examples for all their APIs. This would have helped a great deal. Reimagining Apple's Documentation

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. Then you have to craft a predicate that conforms to NSPredicate syntax AND holds your variables.

Here's an example:

name BEGINSWITH $ARTISTS_NAME

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!

let fetchTemplate = "byArtist" // this is the name in the xcdatamodeld file.
let subs = ["ARTISTS_NAME" : "Taylor Swift"] // Paul's 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.

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Spend less time managing in-app purchase infrastructure so you can focus on building your app. RevenueCat gives everything you need to easily implement, manage, and analyze in-app purchases and subscriptions without managing servers or writing backend code.

Get Started

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.