0Day Forums
How to apply the type to a NSFetchRequest instance? - Printable Version

+- 0Day Forums (https://0day.red)
+-- Forum: Coding (https://0day.red/Forum-Coding)
+--- Forum: Swift (https://0day.red/Forum-Swift)
+--- Thread: How to apply the type to a NSFetchRequest instance? (/Thread-How-to-apply-the-type-to-a-NSFetchRequest-instance)

Pages: 1 2


How to apply the type to a NSFetchRequest instance? - Sirencaustics397 - 07-18-2023

In Swift 2 the following code was working:

let request = NSFetchRequest(entityName: String)

but in Swift 3 it gives error:

> Generic parameter "ResultType" could not be inferred

because `NSFetchRequest` is now a generic type. In their documents they wrote this:

let request: NSFetchRequest<Animal> = Animal.fetchRequest

so if my result class is for example `Level` how should I request correctly?

Because this not working:

let request: NSFetchRequest<Level> = Level.fetchRequest


RE: How to apply the type to a NSFetchRequest instance? - Mrgeorgiannernodgebdca - 07-18-2023

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

func loadItemsCategory() {

let request: NSFetchRequest<Category> = Category.fetchRequest()

do {
categoryArray = try context.fetch(request)
} catch {
print(error)
}

tableView.reloadData()

}


RE: How to apply the type to a NSFetchRequest instance? - stagnancy549622 - 07-18-2023

Swift 3.0 This should work.

let request: NSFetchRequest<NSFetchRequestResult> = NSManagedObject.fetchRequest()
request.entity = entityDescription(context)
request.predicate = predicate


RE: How to apply the type to a NSFetchRequest instance? - Proparus995 - 07-18-2023

I had the same issue and I solved it with the following steps:

- Select your xcdatamodeld file and go to the Data Model Inspector
- Select your first Entity and go to Section class
- Make sure that Codegen "Class Definition" is selected.
- Remove all your generated Entity files. You don't need them anymore.

After doing that I had to remove/rewrite all occurences of fetchRequest as XCode seem to somehow mix up with the codegenerated version.

HTH


RE: How to apply the type to a NSFetchRequest instance? - secondar749552 - 07-18-2023

This is the simplest way to migrate to Swift 3.0, just add `<Country>`

(tested and worked)

let request = NSFetchRequest<Country>(entityName: "Country")


RE: How to apply the type to a NSFetchRequest instance? - oralwusvhrzzr - 07-18-2023

Here are some generic CoreData methods that might answer your question:

import Foundation
import Cocoa

func addRecord<T: NSManagedObject>(_ type : T.Type) -> T
{
let entityName = T.description()
let context = app.managedObjectContext
let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)
let record = T(entity: entity!, insertInto: context)
return record
}

func recordsInTable<T: NSManagedObject>(_ type : T.Type) -> Int
{
let recs = allRecords(T.self)
return recs.count
}


func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T]
{
let context = app.managedObjectContext
let request = T.fetchRequest()
do
{
let results = try context.fetch(request)
return results as! [T]
}
catch
{
print("Error with request: \(error)")
return []
}
}

func query<T: NSManagedObject>(_ type : T.Type, search: NSPredicate?, sort: NSSortDescriptor? = nil, multiSort: [NSSortDescriptor]? = nil) -> [T]
{
let context = app.managedObjectContext
let request = T.fetchRequest()
if let predicate = search
{
request.predicate = predicate
}
if let sortDescriptors = multiSort
{
request.sortDescriptors = sortDescriptors
}
else if let sortDescriptor = sort
{
request.sortDescriptors = [sortDescriptor]
}

do
{
let results = try context.fetch(request)
return results as! [T]
}
catch
{
print("Error with request: \(error)")
return []
}
}


func deleteRecord(_ object: NSManagedObject)
{
let context = app.managedObjectContext
context.delete(object)
}

func deleteRecords<T: NSManagedObject>(_ type : T.Type, search: NSPredicate? = nil)
{
let context = app.managedObjectContext

let results = query(T.self, search: search)
for record in results
{
context.delete(record)
}
}

func saveDatabase()
{
let context = app.managedObjectContext

do
{
try context.save()
}
catch
{
print("Error saving database: \(error)")
}
}

Assuming that there is a NSManagedObject setup for Contact like this:

class Contact: NSManagedObject
{
@NSManaged var contactNo: Int
@NSManaged var contactName: String
}

These methods can be used in the following way:

let name = "John Appleseed"

let newContact = addRecord(Contact.self)
newContact.contactNo = 1
newContact.contactName = name

let contacts = query(Contact.self, search: NSPredicate(format: "contactName == %@", name))
for contact in contacts
{
print ("Contact name = \(contact.contactName), no = \(contact.contactNo)")
}

deleteRecords(Contact.self, search: NSPredicate(format: "contactName == %@", name))

recs = recordsInTable(Contact.self)
print ("Contacts table has \(recs) records")

saveDatabase()


RE: How to apply the type to a NSFetchRequest instance? - parolee166 - 07-18-2023

What worked best for me so far was:

let request = Level.fetchRequest() as! NSFetchRequest<Level>



RE: How to apply the type to a NSFetchRequest instance? - inez14 - 07-18-2023

I also had "ResultType" could not be inferred errors. They cleared once I rebuilt the data model setting each entity's Codegen to "Class Definition". I did a brief writeup with step by step instructions here:

[To see links please register here]


By "rebuilt" I mean that I created a new model file with new entries and attributes. A little tedious, but it worked!


RE: How to apply the type to a NSFetchRequest instance? - beaudette615 - 07-18-2023

The simplest structure I found that works in 3.0 is as follows:

let request = NSFetchRequest<Country>(entityName: "Country")

where the data entity Type is Country.

When trying to create a Core Data BatchDeleteRequest, however, I found that this definition does not work and it seems that you'll need to go with the form:

let request: NSFetchRequest<NSFetchRequestResult> = Country.fetchRequest()

even though the ManagedObject and FetchRequestResult formats are supposed to be equivalent.



RE: How to apply the type to a NSFetchRequest instance? - Sirzipper680 - 07-18-2023

let request: NSFetchRequest<NSFetchRequestResult> = Level.fetchRequest()

or

let request: NSFetchRequest<Level> = Level.fetchRequest()

depending which version you want.

You have to specify the generic type because otherwise the method call is ambiguous.

The first version is defined for `NSManagedObject`, the second version is generated automatically for every object using an extension, e.g:

extension Level {
@nonobjc class func fetchRequest() -> NSFetchRequest<Level> {
return NSFetchRequest<Level>(entityName: "Level");
}

@NSManaged var timeStamp: NSDate?
}

The whole point is to remove the usage of String constants.