web-dev-qa-db-fra.com

Vérification des données de base de Swift 3 iOS 10 si un enregistrement existe déjà en fonction de l'identifiant

Je développe une application avec les nouveaux CoreData et Swift3 sur iOS10. Comment créer un nouvel objet uniquement si l'identifiant n'existe pas (si l'objet existe déjà, nous extrayons l'objet des données de base et ne le modifions que)?

Quelque chose comme

let objectID = someNumber

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

//save

J'essaie d'utiliser la nouvelle syntaxe iOS10 Swift 3 pour CoreData. Je n'utilise pas de code natif avec aucune bibliothèque tierce. Pensez à utiliser fetch mais ne savez pas quelle est la syntaxe appropriée pour cette tâche.

Mise à jour: grâce à @Jan, j'ai trouvé le moyen de vérifier. Ma question de mise à jour est un peu de créer ou de mettre à jour une entité à partir de JSON donné. Voici ma fonction

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
    }

Je reçois le message d'erreur suivant: "l'article de variable est utilisé avant d'être initialisé". Comment pouvons-nous faire en sorte qu'une fonction retourne un article ou mettre à jour un article existant et renvoyer les résultats?

5
Lê Khánh Vinh

Je suppose que vous savez créer et modifier un objet. Pour la partie exists manquante, vous pouvez utiliser quelque chose comme ceci:

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
}

Le nouveau moyen plus efficace de procéder consiste à utiliser 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
}
12
Jan

Un petit conseil, vous pouvez réécrire ce qui suit: 

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

comme:

let article = results.first as? Article ?? Article(context: context)
1
andrius3000