Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3 iOS10 core data check if record already exist base on id

I'm developing an app with new CoreData and Swift3 on iOS10. How do we create new object only if the id is not exist (if object already exist, we pull out object from core data and modify it only)?

Something like

let objectID = someNumber

If exist with objectID = someNumber {
   //modify object
}else {
   //create new object
   //assign attribute
}

//save

I'm trying to use the new iOS10 Swift 3 syntax for CoreData. I'm using native code not with any 3rd party library. Think of using fetch but don't know what is the proper syntax for this task.

Update: thanks to @Jan I have found the way to check. my update question a bit is to create or update entity from given JSON. Here is my function

static func creatOrUpdateArticle(_ json: JSON, context: NSManagedObjectContext) ->Article {

        var article: Article

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Article")
        let predicateID = NSPredicate(format: "id == %@",json[Key.id].stringValue)
        fetchRequest.predicate = predicateID

        do {

            let results = try context.fetch(fetchRequest)
            if results.count > 0 {
                article = results.first as! Article
            }else {
                article = Article(context: context)
            }

            article.webUrl = json[Key.webUrl].string


        }
        catch let error {
            print(error.localizedDescription)
        }
        return article
    }

I'm getting the error: "variable article is used before being initialized". How can we make a function return an article or update existing one and return results?

like image 338
Lê Khánh Vinh Avatar asked Jun 20 '17 16:06

Lê Khánh Vinh


2 Answers

I assume you know how to create a and modify an object. For the missing exists part, you could use something like this:

func someEntityExists(id: Int) -> Bool {
    var fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "SomeEntity")
    fetchRequest.predicate = NSPredicate(format: "someField = %d", id)

    var results: [NSManagedObject] = []

    do {
        results = try managedObjectContext.fetch(fetchRequest)
    }
    catch {
        print("error executing fetch request: \(error)")
    }

    return results.count > 0
}

The new and more efficient way of doing this would be using NSFetchRequestResult.

func someEntityExists(id: Int) -> Bool {
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "SomeEntity")
    fetchRequest.includesSubentities = false

    var entitiesCount = 0

    do {
        entitiesCount = try managedObjectContext.count(for: fetchRequest)
    }
    catch {
        print("error executing fetch request: \(error)")
    }

    return entitiesCount > 0
}
like image 90
Jan Avatar answered Oct 22 '22 05:10

Jan


A little tip, you can rewrite the following:

if results.count > 0 {
    article = results.first as! Article
}else {
    article = Article(context: context)
}

as:

let article = results.first as? Article ?? Article(context: context)
like image 21
andrius3000 Avatar answered Oct 22 '22 07:10

andrius3000