8
\$\begingroup\$

I have this code that I am using to delete all records from an entity. The question is can it be done better or is already the best?

    func deleteIncidents() {
    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext!
    let request = NSFetchRequest(entityName: "Incidents")
    request.returnsObjectsAsFaults = false

        do {
            let incidents = try context.executeFetchRequest(request)

            if incidents.count > 0 {

                for result: AnyObject in incidents{
                    context.deleteObject(result as! NSManagedObject)
                    print("NSManagedObject has been Deleted")
                }
                try context.save() } } catch {}
    }
\$\endgroup\$
9
\$\begingroup\$
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDel.managedObjectContext!

The type annotations are not necessary, the Swift compiler can infer the type automatically:

let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
let context = appDel.managedObjectContext!

request.returnsObjectsAsFaults = false

This makes no sense here because you don't want to access any properties of the returned objects. On the contrary, only the managed object ID is needed to delete objects and no properties need to be fetched at all, so this should be replaced by

request.includesPropertyValues = false

to increase the performance.


I prefer to cast the return value from the fetch request immediately

let incidents = try context.executeFetchRequest(request) as! [NSManagedObject]

this makes both the type annotation : AnyObject and the cast as! NSManagedObject obsolete.


You have to decide how an error should be handled, but I would at least print some message when running in debug mode

} catch let error as NSError {
    debugPrint(error)
}

to detect possible problems.


Starting with iOS 9, objects can be deleted directly in the store without loading them into memory. This would look like this:

func deleteIncidents() {
    let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
    let context = appDel.managedObjectContext!
    let coord = appDel.persistentStoreCoordinator

    let fetchRequest = NSFetchRequest(entityName: "Incidents")
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

    do {
        try coord.executeRequest(deleteRequest, withContext: context)
    } catch let error as NSError {
        debugPrint(error)
    }
}

There is a catch (!) however: Existing objects already loaded into the managed object context are not automatically removed, and doing so it a bit tricky. See https://www.bignerdranch.com/blog/new-in-core-data-and-ios-8-batch-updating/ for more information.

\$\endgroup\$
  • \$\begingroup\$ I used all of your suggestions and code is working much faster. Also I used the if #available(iOS 9.0, *) so that iOS 9 devices can take advantage of the speedy code for it. Then run my tweaked code base your suggestions to support older iOS. \$\endgroup\$ – MwcsMac Sep 9 '15 at 16:48

protected by Jamal Nov 19 '16 at 6:16

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.