Core data 核心数据:如何编写;“通用”;swift 3中的获取/删除功能?

Core data 核心数据:如何编写;“通用”;swift 3中的获取/删除功能?,core-data,swift3,Core Data,Swift3,在swift 2中,我有一个清除给定实体中所有对象的函数: private static func clearTable(tableName : String) { let appDel = UIApplication.sharedApplication().delegate as! AppDelegate let context : NSManagedObjectContext = appDel.managedObjectContext

在swift 2中,我有一个清除给定实体中所有对象的函数:

private static func clearTable(tableName : String)
    {
        let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
        let context : NSManagedObjectContext = appDel.managedObjectContext
        let request = appDel.persistentStoreCoordinator

        let fetchRequest = NSFetchRequest(entityName: tableName)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

        do {
            try request.executeRequest(deleteRequest, withContext: context)
        } catch let error as NSError {
            debugPrint(error)
        }
    }
最近我迁移到swift 3,现在看起来是这样的:

static func clearTable(_ tableName : String)
    {
        let appDel = UIApplication.shared.delegate as! AppDelegate
        //let context : NSManagedObjectContext = appDel.managedObjectContext
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        let request = NSFetchRequest(entityName: tableName)

        let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: tableName)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: NSFetchRequest(entityName: tableName))

        do {
            try request.execute(deleteRequest, with: context)
        } catch let error as NSError {
            debugPrint(error)
        }
    }
据我所知,现在我必须声明
request
fetchRequest
如下

let fetchRequest: NSFetchRequest<SomeEntity> = NSFetchRequest(entityName: "SomeEntity")
let-fetchRequest:NSFetchRequest=NSFetchRequest(entityName:“SomeEntity”)

问题是我事先不知道实体。swift 3中是否有任何解决方法或反射?我不熟悉swift和核心数据,这是获取或删除对象的正常方式吗?

核心数据中的所有结果类型,包括
NSManagedObject
都符合
NSFetchRequestResult
,因此将其用作类型

static func clearTable(_ tableName : String)
{
  let appDel = UIApplication.shared.delegate as! AppDelegate

  let context = appDel.persistentContainer.viewContext
  let request = NSFetchRequest<NSFetchRequestResult>(entityName: tableName)
  let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
  let persistentStoreCoordinator = context.persistentStoreCoordinator!

  do {
    try persistentStoreCoordinator.execute(deleteRequest, with: context)
  } catch let error as NSError {
    debugPrint(error)
  }
}
检查此项以获得更好的方法

我使用CodeDataStack模式分离关注点,以使代码更加干净

您可以使用扩展使代码更具动态性。不需要传递表名,只需调用
model.delete()
model.deleteAll()
。这是其他web框架中使用的常见模式

模型扩展.swift

extension NSManagedObject  {

  static func context() -> NSManagedObjectContext {
      let appDelegate = UIApplication.shared.delegate as! AppDelegate
    return appDelegate.coreData.context()
  }
  public func delete() {
    managedObjectContext?.delete(self)
  }

  public static func deleteAll() {
    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: self.fetchRequest())
    do {
      try context().execute(batchDeleteRequest)
    } catch {
      // Error Handling
    }
  }
}
单元测试:

// My entity name is `Location`
func test_deleteAll() {
    _ = fixture.buildTestLocation()
    _ = fixture.buildTestLocation()
    coreData.saveContext()

    Location.deleteAll()

    XCTAssertEqual(0, Location.all()?.count)
}
func test_delete() {
    let location = fixture.createTestLocation()
    XCTAssertEqual(1, Location.all()?.count)

    location.delete()
    coreData.saveContext()

    XCTAssertEqual(0, Location.all()?.count)
}

请注意,
Location.all()
是一个自定义方法。

现在我遇到了另一个错误,看起来像是request.execute()接受0个参数Dear vadian,我正在尝试相同的解决方案,但得到的错误是“在swift 4中使用未解析标识符'NSFETCHRESQUEST',是否需要导入?是的,您必须
导入CoreData
由于代码重复,您的代码有点混乱。您可以实例化相同的
NSFetchRequest
3x。请参阅我的答案,以获得替代解决方案。
// My entity name is `Location`
func test_deleteAll() {
    _ = fixture.buildTestLocation()
    _ = fixture.buildTestLocation()
    coreData.saveContext()

    Location.deleteAll()

    XCTAssertEqual(0, Location.all()?.count)
}
func test_delete() {
    let location = fixture.createTestLocation()
    XCTAssertEqual(1, Location.all()?.count)

    location.delete()
    coreData.saveContext()

    XCTAssertEqual(0, Location.all()?.count)
}