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 ??
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)
}