Données de base, NSPredicate et plusieurs clés

J’ai un modèle de données de base dans lequel une entité de tâche inclut une relation facultative to-many exclueOccurrences. Une des propriétés de excludedOccurrences est start, qui est un object NSDate. L’entité ExcludedOccurrence a une relation inverse obligatoire vers une entité vers l’entité Task.

Afin de récupérer des tâches pour un jour spécifié, je dois m’assurer que le jour spécifié n’apparaît pas comme la propriété de démarrage d’une entité ExcludedOccurrence. L’un des sous-prédicats que j’essaie d’utiliser est donc

NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(ALL excludedOccurrences.start != %@))", today]; 

où aujourd’hui est un object NSDate pour aujourd’hui incluant seulement les composants jour, mois et année. Toutes les propriétés de départ des occurrences exclues incluent également les composants jour, mois et année.

Bien que cela soit correct, au moins en lisant la documentation de Core Data et NSPredicate, je reçois le message d’erreur suivant:

Application de terminaison due à une exception non capturée ‘NSInvalidArgumentException’, raison: ‘Prédicat non pris en charge

Si j’utilise le prédicat équivalent

 NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"!(ANY excludedOccurrences.start == %@))", today]; 

aucune exception n’est levée, mais le code ne fonctionne pas comme prévu: l’occurrence pour aujourd’hui, qui ne doit pas être exclue, est exclue.

Je ne sais pas trop comment tester le cas excluOccurrences == nil: le prédicat suivant

 NSPredicate *nilPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences == nil)"]; 

provoque à l’exécution l’exception

la clé à plusieurs n’est pas autorisée ici

Cependant, comme la relation excludedOccurrences est facultative, je dois également vérifier si elle est nulle.

Comment puis-je gérer cela? Merci d’avance.

    Pour tester une relation vide, vous devez comparer le nombre de clés à plusieurs à zéro.

     [NSPredicate predicateWithFormat:@"excludedOccurrences.@count == 0"]; 

    En ce qui concerne vos sous-prédicats, sachez que vous ne pouvez avoir que l’un des modificateurs ALL ou ANY dans votre prédicat final, bien que vous puissiez utiliser ce modificateur plusieurs fois dans le prédicat.

    Pas OK : ANY foo.bar = 1 AND ALL foo.baz = 2
    OK: ANY foo.bar = 1 AND !(ANY foo.baz != 2)

    Avec l’aide de vous tous, j’ai finalement réussi à déterminer le prédicat correct pour mon scénario. On dirait qu’un object NSDate est géré comme un double, cependant, le double n’est jamais quelque chose comme 3.7, il est toujours comme 3.0. Par conséquent, le prédicat suivant fonctionne correctement dans mes tests:

     NSPredicate *occurrenceIsNotExcludedPredicate = [NSPredicate predicateWithFormat: @"(excludedOccurrences.@count == 0 || (excludedOccurrences.@count > 0 && NONE excludedOccurrences.start == %@))",thisDate]; 

    où thisDate est un object NSDate contenant uniquement les composants day, month et year (comme dans le cas de la propriété start de l’entité ExcludedOccurrence).

    Le test d’une relation vide se fait essentiellement à l’aide de l’opérateur d’agrégat @count, comme suggéré par certaines personnes chez Apple.

    Encore une fois, merci beaucoup pour votre aide. Je constate toujours que la documentation est imparfaite en plusieurs parties (en particulier là où il est dit que TOUT fonctionne bien alors qu’il ne fonctionne pas du tout).

    Donc, pour tester une relation non vide, cela fonctionne:

     [NSPredicate predicateWithFormat:@"relationship.@count != 0"] 

    La solution donnée par Ashley Clark se bloque pour que je donne “à plusieurs clés non autorisées ici”

    Et dans swift 2, quelque chose comme:

     request.predicate = NSPredicate(format: " relationship.@count != 0")