Search code examples
iosswiftcore-dataswift3

Delete a record from an Entity in core data


I'm working on a project in swift 3.0 where I have a core data module with an entity called "PlayListDetails". This holds two sub- elements names playlistName and trackID. So each playlist name has a trackID interline with it. My requirement is to delete a particular tuple when the indexPath.row is been passed. Though I have implemented a method once I execute the method it gives me an exception saying "fatal error: Index out of range". My methods are as bellow Where I save data and the method I use to delete data.

save

 public static func savePlaylistDetails(audio:[(title:String,healerName:String,trackUrl:String, trackID:String, imageUrl: String)] = [], playListName: String) {

        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        let newPlaylist = NSEntityDescription.insertNewObject(forEntityName: PlayList_DETAILS_ENTITY, into: context)

        let track = audio.map{$0.trackID}
        print("Track",track)

        let trackId = track[0]

        print("ID is :",trackId)
        newPlaylist.setValue(playListName, forKey:"playlistName")
        newPlaylist.setValue(trackId, forKey:"trackID")

        do{
            try context.save();
            print("Saved.....")
        }
        catch{
            print("There was an error")
        }
    }

Delete // this is where I get the exception, and I pass the selected rowIndex to the function

func deleteCoreData(rowIndex: Int) {
    let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    var playList = [PlayListDetails] ()
    managedContext.delete(playList[rowIndex]) // this is where the exception throws


    do {
         try managedContext.save()

    }catch{
        print("fail")
    }

}

What am I missing ??


Solution

  • If you are trying to delete item with specific index, i have provided solution for deleting item at index (this might cause array out of bound exception), but i recommend to use predicate, lets say that may be id, name of item that you are willing to delete.

    I am providing solution with perception from your question, You can use process of fetching entity from DB and delete that particular item you want to remove.

    Please manage to add following code, Do not forgot to use predicate if you want to delete some particular item

     func deleteCoreData(rowIndex: Int) {
    
        let managedContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    
        do{
            //1. Create Request
            let request: NSFetchRequest<PlayListDetails> = PlayListDetails.fetchRequest()
    
            //Predicate is optional as per need
            //let predicate = NSPredicate(format: "playlistId = %@", id)
            //request.predicate = predicate
    
            //2. Result object
            let results = try managedObjectcontext.fetch(request as! NSFetchRequest<NSFetchRequestResult>)
    
            guard results.count > 0 else {
                print("No tems available handle error")
                return
            }
    
            for i in 0...results.count-1 {
    
                if i == rowIndex {
                    let theItem = results[index] as NSManagedObject
                    managedObjectcontext.delete(item)
                }
            }
             /*
            for item in results as! [NSManagedObject]{
                print(item)
                //hit delete for item you want
                managedObjectcontext.delete(item)
            } */
    
            do {
                try managedObjectcontext.save() // <- remember to put this :)
    
            } catch {
                // Do something... fatalerror
                print("handle error")
                return
            }
    
        } catch{
            print(error)
            print("handle error")
            return
    
        }
        print("handle error")
    
    }
    

    Update

    "This is the query i wants to execute sir.. Delete all from PlayListDetails where trackId=123 and playlistName= demo How would I achieve this in above code"

    Using predicate

    //use predicate for single predicate and compound for multiple predicate 
    //Predicate is optional as per need
    let predicate = NSPredicate(format: "trackId = %@", id)
    let predicate2 = NSPredicate(format: "name = %@", "some name")
    
    //let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate, predicate2])
    
        request.predicate = predicate
    

    on delete section use

    for item in results as! [NSManagedObject]{
                    print(item)
                    //hit delete for item you want
                    managedObjectcontext.delete(item)
                }