Can You Make an Entity a Variable?

Does anyone know if it's possible to make an entity into a variable so that when you call the fetch request function, you can just pass in the entity? I'm trying to avoid having to create 27 separate functions. Thanks!

You’ll need to elaborate on this to get some useful replies. Maybe a code example with 2-3 functions demonstrating the duplication you want to avoid?

Thanks, Nickolas! What I'm trying to do is make a generic fetch request function and use a variable for the entity like this:

func fetchVocab(theEntity: of some type) {
let request = NSFetchRequest<theEntity>(entityName: theEntity)
do {
try savedItems = container.viewContext.fetch(request)
} catch let error {
print("Error Fetching (error)")
}
}

Then, I want to call the function passing in the entity:

self .fetchVocab(RevEntity)

Otherwise, I will need to create 27 separate functions like the one above. As I said, I don't know if what I want to do is possible, or if it is, of what type to make the variable. Hopefully, that was more helpful. Thanks, again!

Yes, you can declare a function like func fetchVocab<Entity>(_ entity: Entity.Type) where Entity : NSManagedObject and use it like fetchVocab(RevEntity.self) or fetchVocab(AnotherEntity.self), or any other type that matches the listed where constraints (in this example, that is any type that is a subclass of NSManagedObject).

What these angle brackets signify is a type system language feature called generics. It is quite a large topic, I would advise reading the chapter in the Swift Programming Language book to get an initial understanding about it.

Thanks, Benjamin. The call to the function looks like it should work (no errors). But I'm getting two errors in the function itself.

Also, is this the book you're referring to? The Swift Programming Language 5.6 PDF – Apps Dissected

Thanks!

The book is released by Apple in the Apple Books Store. There’s a similar web version here.

Couple issues with this I can see at a glance: errant semicolon before the where. Just delete it.

Secondly, you won’t be able to pass the entity directly there, as it is expecting a string. When you remove the semicolon and rebuild, it should highlight the type issue and hopefully you can spot the problem. You’ll need to use a property of the entity to get the name.

Thanks for providing that resource. I've taken the time to read through it and I'm able to grasp the concepts although apparently, not entirely. According to the documentation and the code examples provided, it seems to me that my code should look like this:

This is my understanding of the code:

"Entity" inside the angle brackets <> is a placeholder that tells Swift that a variable of that type can be of any type, as long as it conforms to a specific type. "entity" is the variable that we're making of type "Entity," and we're making "Entity" of type NSManagedObject, which in turn, we're doing by using the "where" keyword. The where keyword tells Swift that whenever our code uses a variable where an NSManagedObject is expected, that variable will be of type NSManagedObject. In this case, our variable is "entity."

But as you can see by the errors it generates, either my understanding is deficient or else my implementation of it. All further assistance is greatly appreciated! Thanks!

Not a bad attempt!

Couple things. Firstly, between the angle brackets here you cannot have variables, you can only have names of static types. A generic can be that name, as a generic is like a placeholder for a type. So rather than NSFetchRequest<entity>, you need NSFetchRequest<Entity> (note the uppercase 'E').

Secondly, this is subtle but important — if you declare the function parameter as just entity: Entity, then what you are saying is you want the caller to provide an instance of that type, so you would use it like fetchrevGVocab(MyObject()). However, that is not your intent. You are simply trying to supply the type of the variable, not an instance of it. That is, your ultimate goal is to write fetchrevGVocab(MyObject.self). To achieve this, you need to declare the function parameter as Entity.Type.

So your completed function declaration would be fetchrevGVocab<Entity>(entity: Entity.Type) where Entity : NSManagedObject {.

If you make that fix, the compiler will then complain about the NSFetchRequest initialiser, where you need to pass a string rather than the entity type — you can get this from Entity.entity().name.

QOL Note: Once you get this building, it probably makes sense to rename the function to something more generic and readable.

My most profound thanks for all your help, Benjamin! But alas, it's still not working and to be honest, I don't think I'm inclined to pursue it any further. In fact, I've decided to just go back to Realbasic (aka Xojo). I know, I know, Xojo is a toy compared to Swift and Xcode. But the thing is, I'm 59, and I haven't worked as a programmer professionally since 2008. I decided to try to learn SwiftUI because I had an idea for a iOS app and I didn't feel like shelling out 300.00 for a Xojo license to create it. But I feel even less like taking the next 3 years to finish this project, so I'm opting to shell out the money.

Thanks again, for everything!