如何将types应用于NSFetchRequest实例?

在Swift 2中,以下代码正在工作:

let request = NSFetchRequest(entityName: String) 

但在Swift 3中却出现错误:

通用参数“ResultType”无法推断

因为NSFetchRequest现在是一个genericstypes。 他们在文件中写到:

 let request: NSFetchRequest<Animal> = Animal.fetchRequest 

所以如果我的结果类是例如Level我应该如何正确地要求?

因为这不起作用:

 let request: NSFetchRequest<Level> = Level.fetchRequest 

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

要么

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

取决于你想要的版本。

您必须指定genericstypes,否则方法调用是不明确的。

第一个版本是为NSManagedObject定义的,第二个版本是使用扩展为每个对象自动生成的,例如:

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

重点是删除string常量的使用。

我想我是这样做的:

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

至less它从DataBase中保存和加载数据。

但感觉这不是一个合适的解决scheme,但它现在起作用。

我发现在3.0中工作的最简单的结构如下:

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

数据实体的types是国家。

当试图创build一个核心数据BatchDeleteRequest,但是,我发现这个定义不起作用,似乎你需要去的forms:

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

即使ManagedObject和FetchRequestResult格式应该是等效的。

这是迁移到Swift 3.0的最简单的方法,只需添加<Country>

(testing和工作)

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

以下是一些可能回答你的问题的通用CoreData方法:

 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)") } } 

假设有一个NSManagedObject设置为这样的联系人:

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

这些方法可以按照以下方式使用:

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

我也有“ResultType”不能被推断的错误。 一旦我重build数据模型,将每个实体的Codegen设置为“Class Definition”,他们就清除了。 我在这里一步步地做了一个简短的说明:

使用Swift 3在Xcode 8中寻找修订后的NSPersistentContainer的清晰教程

通过“重build”我的意思是我创build了一个新的模型文件与新的条目和属性。 有点乏味,但它的工作!

迄今为止最适合我的是:

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

我有同样的问题,我解决了以下步骤:

  • select您的xcdatamodeld文件并转到数据模型检查器
  • select你的第一个实体,并去部分类
  • 确保Codegen“类定义”被选中。
  • 删除所有生成的实体文件。 你不再需要他们了。

这样做后,我不得不删除/重写fetchRequest的所有出现XCode似乎以某种方式与codegenerated版本混淆。

HTH