简体   繁体   中英

Swift CoreData compare string with entities

I am browsing a NSArray and sending what I get on a Core Data, like this:

let json2:NSArray = NSJSONSerialization.JSONObjectWithData(data.dataUsingEncoding(NSUTF8StringEncoding)!, options: NSJSONReadingOptions.MutableContainers, error: &error) as! [NSArray]

        for dict in json2 {
            var apps = [String]()

            //Creation du lien vers la base SQLite
            let entityDescription = NSEntityDescription.entityForName("Task", inManagedObjectContext: self.context!)
            let nTask = Task(entity: entityDescription!, insertIntoManagedObjectContext: self.context)


            let request = NSFetchRequest()
            request.entity = entityDescription
            var error: NSError?
            var objects = self.context?.executeFetchRequest(request, error: &error)


            if let summary = dict["summary"] as? String{
                nTask.summary = summary
            }


            if let description = dict["description"] as? String{
                nTask.detail = description
            }


            if let context = dict["context"] as? String{
                nTask.context = context
            }


            if let due = dict["due"] as? String {
                nTask.date = due
            }else{
                nTask.date = "No Ending Date"
            }

            if let status = dict["status"] as? String{
                nTask.status = status
            }

            if let responsible = dict["responsible"] as? String{
                nTask.responsable = responsible
            }

            if let id = dict["id"] as? String{
                nTask.id = id
            }

            println(nTask)



            /*let match = objects![0] as! NSManagedObject
            let result = match.valueForKey("id") as! String
            println(result)

            if result != nTask.id{*/
                self.context?.save(nil)
            //}

The send works well, the Core Data is populated, everything seems to be ok.

What is commented is what I'm looking for and what doesn't work at the moment. I want to check if the nTask.id which is a String, the value of the "id" key, is equal of any id already existing on my Core Data "Task" on the attribute "id".

I'm creating the entity description, the request and what the request returns, and then try to compare with the nTask.id but it always matches, I always access to my self.context?.save(nil) , I get doubloons and I don't want it..0. This is what I'm trying to do:

let entityDescription = NSEntityDescription.entityForName("Task", inManagedObjectContext: self.context!) //creation of the Entity Description for my Entity, "Task"
    let request = NSFetchRequest()
    request.entity = entityDescription //Creation of the request on the Entity "Task"
    var error: NSError?
    var objects = self.context?.executeFetchRequest(request, error: &error) //Results are sent to my variable objects
let match = objects![0] as! NSManagedObject 
    let result = match.valueForKey("id") as! String
    println(result)

    if result != nTask.id{ //try to compare what the request return with the nTask.id
        self.context?.save(nil)
    }

Am I doing something wrong or am I missing something? I just want to check if the nTask.id already exists on my CoreData, and if it don't exist, send the complete Task to my CoreData.

Thank you for your help.

Regards.

Your current code fetches ALL the Task objects, but compares the id of only the first one in the resulting array ( objects ). So duplicates elsewhere in this array will not be detected.

Restructure your code slightly, to check first whether there is an existing Task with the relevant id . Use the fetch request that you have but include a predicate to fetch ONLY any Task objects that have the relevant id . If you get 0 results, create the new Task . If you get 1 or more results: you need to decide how to handle that, but the code below will update the attribute values of the existing object:

for dict in json2 {
    var apps = [String]()
    var nTask : Task

    //Creation du lien vers la base SQLite
    let entityDescription = NSEntityDescription.entityForName("Task", inManagedObjectContext: self.context!)

    if let relevantID = dict["id"] as? String {
        let request = NSFetchRequest()
        request.entity = entityDescription
        request.predicate = NSPredicate(format:"id == %@",relevantID)
        var error: NSError?
        var objects = self.context?.executeFetchRequest(request, error: &error)
        if objects!.count == 0 {
            nTask = Task(entity: entityDescription!, insertIntoManagedObjectContext: self.context)
        } else {
            // You need to decide: create a new object and delete the old
            // update the old object with the new attribute values, or 
            // just ignore the new values
            // The following will update the existing Task object
            nTask = objects![0] as! Task
        }
    } else { // no `id` to match against, so just create a new Task
            nTask = Task(entity: entityDescription!, insertIntoManagedObjectContext: self.context)
    }
    // Now update the attribute values...
    if let summary = dict["summary"] as? String{
        nTask.summary = summary
    }
    if let description = dict["description"] as? String{
        nTask.detail = description
    }
    if let context = dict["context"] as? String{
        nTask.context = context
    }
    if let due = dict["due"] as? String {
        nTask.date = due
    }else{
        nTask.date = "No Ending Date"
    }
    if let status = dict["status"] as? String{
        nTask.status = status
    }
    if let responsible = dict["responsible"] as? String{
        nTask.responsable = responsible
    }
    if let id = dict["id"] as? String{
        nTask.id = id
    }
    println(nTask)

    self.context?.save(nil)
}

Note that this should work, but is not very efficient. You might want to read the Apple Core Data Programming Guide section on "Efficiently importing data" for more efficient algorithms.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM