Core Data in Swift: Only saving last object in a f

2019-01-06 23:00发布

问题:

I'm trying to save multiple objects in Core Data to the IPodSongs entity in a for loop, namely the title of the song currently in the for song in result{} loop. But my code only saves the very last song in the loop, and just keeps overwriting the same object. Instead of overwriting the same object, I need to create a new object each time. What am I doing wrong?

func fetchiPodSongsOnSignup() {

        var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

        var context: NSManagedObjectContext = appDel.managedObjectContext!

        var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject

        var request = NSFetchRequest(entityName: "IPodSongs")

        request.returnsObjectsAsFaults = false

        var results = context.executeFetchRequest(request, error: nil)


        let query = MPMediaQuery.songsQuery()

        let result = query.collections as! [MPMediaItemCollection]

        for song in result {

            for song in song.items as! [MPMediaItem] {

                newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

                println(newSong)

                context.save(nil)

            }
        }    

回答1:

You dont need to create a request to save new objects to Core Data. What you did wrong was create a single managed object, inserted it and then changeded it through the loop instead of creating a new object for each song.

This should work:

func fetchiPodSongsOnSignup() {

    var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    var context: NSManagedObjectContext = appDel.managedObjectContext!


    let query = MPMediaQuery.songsQuery()

    let result = query.collections as! [MPMediaItemCollection]

    for song in result {

        for song in song.items as! [MPMediaItem] {

            var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as NSManagedObject

            newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

            println(newSong)


        }
    }
    if context.save(&errorPointer == false {
        printlin("Error received while saving")
    }

}

Also put if context.save(&errorPointer == false {printlin("Error received while saving")} at the very end.



回答2:

You are using the same inserted object in all iterations :

for song in song.items as! [MPMediaItem] {
      newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

You are indeed changing the song's object value but you use the same instance which in turn is the same entity in the core db.

You need to use a new instance for every new song:

 var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject
 newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")


回答3:

Try this , this will work ....

Insert in for loop and save in outside loop ...

func fetchiPodSongsOnSignup() {

var appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

var context: NSManagedObjectContext = appDel.managedObjectContext!


let query = MPMediaQuery.songsQuery()

let result = query.collections as! [MPMediaItemCollection]

for song in result {

    for song in song.items as! [MPMediaItem] {

        var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as NSManagedObject

        newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

        context.insert(newSong)

    }
}
context.save(nil)
}


回答4:

This will work for you most probably! Try it!

for song in result {

        for song in song.items as! [MPMediaItem] {
            var newSong = NSEntityDescription.insertNewObjectForEntityForName("IPodSongs", inManagedObjectContext: context) as! NSManagedObject
            newSong.setValue("\(song.valueForProperty(MPMediaItemPropertyTitle))", forKey: "title")

            println(newSong)

            context.save(nil)

        }
    }