How to apply the type to a NSFetchRequest instance?

Related searches

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
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.

How to apply the type to a NSFetchRequest instance?, let request: NSFetchRequest<NSFetchRequestResult> = Level.fetchRequest(). or let request: NSFetchRequest<Level> = Level.fetchRequest(). depending� C#. [Foundation.Register ("NSFetchRequest", true)] public class NSFetchRequest : CoreData.NSPersistentStoreRequest, Foundation.INSCoding, IDisposable. type NSFetchRequest = class inherit NSPersistentStoreRequest interface INSCoding interface INativeObject interface IDisposable. Inheritance.

I think i got it working by doing this:

let request:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Level")

at least it saves and loads data from DataBase.

But it feels like it is not a proper solution, but it works for now.

NSFetchRequest, because NSFetchRequest is now a generic type. In their documents they wrote this: let request: NSFetchRequest<Animal> = Animal.fetchRequest. so if my result � An instance of NSFetch Request collects the criteria needed to select and optionally to sort a group of managed objects held in a persistent store. (See NSPersistent Store and NSManagedObject .) A fetch request must contain an entity description (an instance of NSEntity Description ) or an entity name that specifies which entity to search.

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.

Mastering In CoreData (Part 9 NSFetchRequest), An instance of NSFetchRequest collects the criteria needed to select and optionally to A special property description type intended for use with a fetch request. let request = NSFetchRequest(entityName: String) mais dans Swift 3 il donne erreur: paramètre générique " Type de résultat "ne pouvait être déduit . parce que NSFetchRequest est maintenant un type générique. Dans leurs documents ils écrivirent ceci: let request: NSFetchRequest<Animal> = Animal.fetchRequest

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

Loading Core Data objects using NSFetchRequest and , NSFetchRequest is use to access the existing data. It either returns an NSArray object of type NSManagedObject with zero or more objects,� The properties of the NSFetchRequest class described in this article, together with their in-use examples, demonstrate that the request functionality presented by the Core Data framework is very flexible and can be used to efficiently fetch data from your app’s database.

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

(tested and worked)

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

We're going to use NSFetchRequest in a really basic form for now, then add more you're using for your entity, then pass it to managed object context's fetch() method. The sorting is done through a special data type called NSSortDescriptor� The default value is managed Object Result Type. If you set the value to managed Object IDResult Type, and do not include property values in the request, sort orderings are demoted to “best efforts” hints. includes Pending Changes discusses with whether pending changes are taken into account when the result Type is set to managed Object

I have to create a NSFetchRequest for my iPhone App that returns the same results as the following SQL statement: SELECT week , year , SUM(duration) AS totalDuration FROM myTable GROUP

This happens “behind the scenes” when you use the @FetchRequest property wrapper in your SwiftUI view. No need to use your managed object context to perform the fetch request manually. For a more complete guide to using Core Data with SwiftUI, you can refer to the introduction I published. It includes an example project with all of the

NSFetchRequest() Default constructor that initializes a new instance of this class with no parameters. NSFetchRequest(NSCoder) A constructor that initializes the object from the data stored in the unarchiver object. NSFetchRequest(NSObjectFlag) Constructor to call on derived classes to skip initialization and merely allocate the object.

Comments
  • link to new features, where I found the code: developer.apple.com/library/prerelease/content/releasenotes/…
  • It's a method, so it should be let request: NSFetchRequest<Level> = Level.fetchRequest()
  • Or just let request = Level.fetchRequest()
  • @MartinR That would not pass compilation because it's ambigious.
  • @MartinR seems stack overflow members love you a lot. They'll upvote you blindly. :P
  • So for every entity, do I need to add extension code? Or that happens automatically? So if I have a "Dog" entity and "Cat" entity, do I need "extension Dog { @nonobjc... }" and "extension Cat { @nonobjc...}"?
  • @DaveG That extension is generated for you automatically.
  • Okay, ty, but I'm a bit confused because I tried 'let fetchRequest = NSFetchRequest<myEntityName>(entityName: "myEntityName")' and I got the error "Use of undeclared type "myEntityName"
  • Note: The method fetchRequest() is only available in iOS 10
  • @Sulthan Hi, When I tried with your code, the following error occurs. Type 'Project Name' does not conform to protocol 'NSFetchRequestResult'
  • I like this solution better, as I used to have a single method that took the entity name as a parameter and just passed back an array of NSManagedObjects.
  • Liked this too because it didn't require creating a custom class. Could just use entity name!
  • Underrated answer. Thanks!