it-roy-ru.com

Swift 3 Core Data Удалить объект

К сожалению, новая семантика Core Data сводит меня с ума. В моем предыдущем вопросе был чистый код, который не работал из-за неправильной автоматической генерации заголовочных файлов. Сейчас я продолжаю свою работу по удалению объектов. Мой код кажется очень простым: 

func deleteProfile(withID: Int) {
    let fetchRequest: NSFetchRequest<Profile> = Profile.fetchRequest()
    fetchRequest.predicate = Predicate.init(format: "profileID==\(withID)")
    let object = try! context.fetch(fetchRequest)
    context.delete(object)
} 

Я выполнил «жесткую» отладку с print(object) вместо context.delete(object), и он показал мне нужный объект…. Поэтому мне нужно просто удалить его.

Постскриптум нет deleteObject. Теперь NSManagedContext имеет только public func delete(_ sender: AnyObject?)

44
user6485277

Результатом выборки является массив управляемых объектов, в вашем случае [Event], так что вы можете перечислить массив и удалить все подходящие объекты .. Пример. (Используя try? вместо try!, чтобы избежать сбоя в случае ошибки извлечения): 

if let result = try? context.fetch(fetchRequest) {
    for object in result {
        context.delete(object)
    }
}

Если подходящих объектов не существует, выборка завершается успешно, но результирующий массив Пуст.


Примечание: В вашем коде object имеет тип [Event] и поэтому в 

context.delete(object)

компилятор создает вызов

public func delete(_ sender: AnyObject?)

метод NSObject вместо ожидаемого

public func delete(_ object: NSManagedObject)

метод NSManagedObjectContext. Вот почему ваш код компилируется , Но терпит неудачу во время выполнения.

64
Martin R

Хитрость здесь, это сохранить контекст после удаления ваших объектов.

let fetchRequest: NSFetchRequest<Profile> = Profile.fetchRequest()
fetchRequest.predicate = Predicate.init(format: "profileID==\(withID)")
let objects = try! context.fetch(fetchRequest)
for obj in objects {
    context.delete(obj)
}

do {
    try context.save() // <- remember to put this :)
} catch {
    // Do something... fatalerror
}

Я надеюсь, что это может кому-то помочь.

36
J. Lopes

Удалить основные объекты данных Swift 3

// MARK: Delete Data Records

func deleteRecords() -> Void {
    let moc = getContext()
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Person")

     let result = try? moc.fetch(fetchRequest)
        let resultData = result as! [Person]

        for object in resultData {
            moc.delete(object)
        }

        do {
            try moc.save()
            print("saved!")
        } catch let error as NSError  {
            print("Could not save \(error), \(error.userInfo)")
        } catch {

        }

}

// MARK: Get Context

func getContext () -> NSManagedObjectContext {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    return appDelegate.persistentContainer.viewContext
} 
18
Raj Joshi
func deleteRecords() {
    let delegate = UIApplication.shared.delegate as! AppDelegate
    let context = delegate.persistentContainer.viewContext

    let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "nameofentity")
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)

    do {
        try context.execute(deleteRequest)
        try context.save()
    } catch {
        print ("There was an error")
    }
}
8
Hitesh Chauhan

Swift 4.1 и 4.2

     let appDelegate = UIApplication.shared.delegate as! AppDelegate
     let context = appDelegate.persistentContainer.viewContext
     let requestDel = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
     requestDel.returnsObjectsAsFaults = false
  // If you want to delete data on basis of some condition then you can use NSPredicate
  //  let predicateDel = NSPredicate(format: "age > %d", argumentArray: [10])
  // requestDel.predicate = predicateDel


     do {
          let arrUsrObj = try context.fetch(requestDel)
          for usrObj in arrUsrObj as! [NSManagedObject] { // Fetching Object
              context.delete(usrObj) // Deleting Object
         }
     } catch {
          print("Failed")
     }

    // Saving the Delete operation
     do {
         try context.save()
     } catch {
         print("Failed saving")
     }
3
GSK

Swift 4 без использования строки для Entity

let fetchRequest: NSFetchRequest<Profile> = Profile.fetchRequest()
fetchRequest.predicate = Predicate.init(format: "profileID==\(withID)")

do {
    let objects = try context.fetch(fetchRequest)
    for object in objects {
        context.delete(object)
    }
    try context.save()
} catch _ {
    // error handling
}
2
Sonius

Я не уверен, что если это все-таки поможет, то для кого-то требуется оптимизированное решение, вы можете попытаться выполнить NSBatchDeleteRequest Opertaion 

Позволяет вам выполнить операцию удаления нескольких объектов одновременно, не загружая их в меня

fileprivate func deleteRecords(){
        debugPrint("Before","Making")
//Here UserNotification class is NSManagedObject Class.
        let request =  UserNotification.fetchRequest() as NSFetchRequest<UserNotification>

        let context = helper.persistentContainer.viewContext
        do{
            let deleteRequest = NSBatchDeleteRequest(fetchRequest: request as! NSFetchRequest<NSFetchRequestResult>)

            do{
                try context.execute(deleteRequest)
                debugPrint("Batch deleted")
            }
        }catch let error as NSError {
                debugPrint("Error",error)
        }
    }
0
nikhil nangia