Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 196 Vote(s) - 3.65 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to apply the type to a NSFetchRequest instance?

#1
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
Reply

#2
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()

}
Reply

#3
Swift 3.0 This should work.

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

#4
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
Reply

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

(tested and worked)

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

#6
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()
Reply

#7
What worked best for me so far was:

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

#8
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!
Reply

#9
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.
Reply

#10
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.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through