# fetchRequest avec predicate sur attribut NSDate...



## Mkdisco (17 Juillet 2011)

Bonjour,

Je dispose d'une entité _MonEntite_ qui a un attribut de type NSdate _creationDate_.
J'ai besoin d'aller chercher dans ma BDD l'instance de l'entité dont la _creationDate_ est égale à _newDate_.

Je procède donc de la sorte :

```
NSFetchRequest *request= [[NSFetchRequest alloc] init];
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"MonEntite" inManagedObjectContext:managedObjectContext];
	NSPredicate *predicate =[NSPredicate predicateWithFormat:@"%creationDate==%@", newDate];
	[request setEntity:entity];
	[request setPredicate:predicate];
	
        MonEntite * instanceRecherchee = [[managedObjectContext executeFetchRequest:request error:&error2] lastObject];
```

Et ça ne fonctionne pas. La requête ne trouve jamais rien alors qu'elle le devrait.
Si j'utilise un autre attribut que l'objet NSDate creationDate, comme un nom par exemple, cela marche d'ailleurs parfaitement.
Il semble qu'il y ait un problème avec la condition d'égalité entre deux dates... quelqu'un aurait-il une idée ? 

Merci beaucoup !


----------



## ntx (17 Juillet 2011)

Mkdisco a dit:


> ```
> NSPredicate *predicate =[NSPredicate predicateWithFormat:@"[B]%[/B]creationDate==%@", newDate];
> ```


Pourquoi le "%" au début de ton prédicate ?
De quel type est ta variable "newDate" ? NSDate ?


----------



## Rez2a (17 Juillet 2011)

Salut, je ne comprends pas le %creationDate non plus ?

Sinon, je ne crois pas avoir déjà fait un predicate sur une NSDate, par contre si tu dis que tu n'as pas de problème à avec des NSString, alors c'est certes bourrin mais :


```
[COLOR="Blue"]NSDateFormatter *dateF = [[NSDateFormatter alloc] init];
[dateF setDateFormat:@"yyyy-MM-dd"];[/COLOR]

NSFetchRequest *request= [[NSFetchRequest alloc] init];
	NSEntityDescription *entity = [NSEntityDescription entityForName:@"MonEntite" inManagedObjectContext:managedObjectContext];
[COLOR="blue"]	NSPredicate *predicate =[NSPredicate predicateWithFormat:@"'%@' == '%@'", [dateF stringFromDate:creationDate], [dateF stringFromDate:newDate]];
[/COLOR]	[request setEntity:entity];
	[request setPredicate:predicate];

[COLOR="blue"][dateF release];
[/COLOR]
```

Regarde déjà si ça te donne quelque chose.
Je verrai à l'occase si il y a un "truc" pour comparer les dates dans un NSPredicate ou si il y a juste un souci au niveau de ton code et je reviendrai poster au cas où.


----------



## Nyx0uf (17 Juillet 2011)

Le % n'a rien à faire ici.

Un predicate sur NSDate fonctionne bien normalement.


----------



## Mkdisco (17 Juillet 2011)

Merci de vos réponses...

Alors en effet, le "%" du début de predicate est une erreur de copier-coller, il n'est pas dans mon code original.
La ligne est donc bien :


	NSPredicate *predicate =[NSPredicate predicateWithFormat"creationDate==%@", newDate];

La variable newDate étant de type NSDate.

Le problème est donc que la requête ne renvoie rien (alors qu'elle le devrait), et je me demandais s'il n'y avait pas une syntaxe particulière ou un truc dans le cas de l'égalité de deux objets NSDate.

Je vais essayer de manipuler un peu l'objet façon Rez2a...


----------



## Rez2a (17 Juillet 2011)

Mkdisco a dit:


> Je vais essayer de manipuler un peu l'objet façon Rez2a...



Ma "façon" n'a aucun sens, j'ai posté en vitesse et je crois que je suis à côté de la plaque.
Par contre il y a un doc d'Apple qui montre un NSPredicate avec un NSDate :
http://developer.apple.com/library/...oa/Conceptual/Predicates/Articles/pUsing.html


```
NSDate *referenceDate = [NSDate dateWithTimeIntervalSince1970:0];
 
predicate = [NSPredicate predicateWithFormat:@"birthday > %@", referenceDate];
filteredArray = [array filteredArrayUsingPredicate:predicate];
```

J'avais remarqué qu'en générant les headers des classes de CoreData avec des attributs scalar, les NSDate devenaient des NSTimeInterval, peut-être que cela joue dans le traitement des NSPredicate où les NSDate doivent être d'abord converties avec dateWithTimeIntervalSince1970:.


----------



## Mkdisco (18 Juillet 2011)

Ok, le problème semble résolu 

D'abord, je dois préciser que mon appli sauvegarde des données dans CoreData (monEntité dont un des attributs est creationDate). Mais l'attribut creationDate est également sauvé dans une pList. Et cette version de la pList me sert plus tard à retourner chercher l'objet entier qui est dans CoreData.

Avec un "navigateur de BDD", j'ai remarqué que les dates sont stockées dans CoreData sous forme scalaire de timeInterval et de manière exacte et précise : ex: "332666478.613781"

La même date dans la plist est sauvée sous forme de date et j'ai remarqué en transformant sa version récupérée là en timeInterval que durant le processus sauvegarde/récupération dans la pList, elle avait *perdu sa partie décimale*.

Donc mes deux dates sensée être identiques ne l'étaient plus et la requête ne donnait rien.

J'ai donc décidé de procéder par encadrement entre ma "creationDatePlist" et une nouvelle creationDatePlistPlusUn = [creationDate dateByAddingTimeInterval:1].

La première tentative avec l'opérateur BETWEEN dans le predicate provoque une "[__NSDate constantValue]: unrecognized selector sent to instance"

La seconde :

```
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(creationDate <= %@) AND (creationDate >= %@)", creationDatePlistPlusUn, creationDatePlist];
```

semble fonctionner... Hallelujah !

Merci de votre attention


----------

