核心数据:如何编写" generic"在swift 3中获取/删除功能?

时间:2016-10-04 09:03:21

标签: core-data swift3

我有一个函数清除了给定实体中的所有对象,在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)
        }
    }

据我所知,现在我必须声明requestfetchRequest之类的

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

问题在于我事先并不了解实体。 swift 3中是否有任何解决方法或反思?我是swift和核心数据的新手,这是获取或删除对象的常用方法吗?

2 个答案:

答案 0 :(得分:3)

核心数据中的所有结果类型(包括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)
  }
}

这是删除实体所有项目的推荐方法 但是,部署目标必须是≥iOS9 / macOS 10.11。

PS:在Swift 3中,我声明了函数

static func clear(table tableName : String) { ...

答案 1 :(得分:0)

查看此batch delete example以获得更好的方式。

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

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

ModelExtension.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()是一种自定义方法。