2010-11-07 7 views
2

Existe-t-il un moyen d'inspecter un objet NSPredicate dans le but de le sérialiser dans une URL? J'essaie de récupérer les données à distance et j'ai besoin de traduire l'objet prédicat dans une URL avec des paramètres de chaîne querys que le serveur comprend. Ceci a été inspiré par une conférence donnée dans la WWDC 2010 intitulée «Construire une expérience utilisateur pilotée par le serveur» où les intervenants parlent de l'utilisation de Core-Data et d'un backend de serveur. J'ai suivi la vidéo de la session et les diapositives, mais je suis coincé sur le point de sérialisation. Par exemple, il y a un objet Person, et j'essaye d'aller chercher toutes les personnes dont le prénom est "John". J'utilise une sous-classe de NSManagedObjectContext appelée RemoteManagedObjectContext, qui remplace la méthode executeFetchRequest, et est censée envoyer l'appel au serveur à la place. La demande de récupération est créé (ellipsed parties non essentielles):Comment sérialiser un objet NSPredicate?

@implementation PeopleViewController 

- (NSArray *)getPeople { 
    RemoteFetchRequest *fetchRequest = [[RemoteFetchRequest alloc] init]; 
    NSEntityDescription *entity = ... 
    NSPredicate *template = [NSPredicate predicateWithFormat: 
           @"name == $NAME AND endpoint = $ENDPOINT"]; 
    NSPredicate *predicate = [template predicateWithSubstitutionVariables:...]; 

    [fetchRequest setEntity:entity]; 
    [fetchRequest setPredicate:predicate]; 

    NSError *error = nil; 
    // the custom subclass of NSManagedObjectContext executes this 
    return [remoteMOC executeFetchRequest:fetchRequest error:&error]; 
} 

@end 

maintenant dans la sous-classe personnalisée de NSManagedObjectContext, comment puis-je sérialiser la demande d'extraction dans les paramètres de querystring appropriés pour le serveur. Ainsi, compte tenu de la demande d'extraction ci-dessus, l'URL correspondante serait:

http://example.com/people?name=John 

Il est possible d'obtenir une représentation de chaîne du prédicat qui retourne,

name == "John" AND endpoint == "people" 

que je peux analyser pour obtenir les paramètres name et endpoint. Cependant, est-il possible de le faire sans analyser la chaîne? Voici une implémentation partielle de la classe RemoteManagedObjectContext.

@implementation RemoteManagedObjectContext 

- (NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error { 
    // this gives name == "John" AND endpoint == "people" 
    // don't know how else to retrieve the predicate data 
    NSLog(@"%@", [[request predicate] predicateFormat]); 

    ... 
} 

@end 

Répondre

4

Encore mieux qu'une représentation sous forme de chaîne est une représentation orientée objet! Et c'est fait automatiquement! Pour commencer, vérifiez la classe NSPredicate. Ce sera un NSCompoundPredicate. Cast le à une variable appropriée.

Vous verrez alors que c'est compoundPredicateType est , comme vous vous y attendez.

Vous pouvez également voir que le tableau renvoyé par -subpredicates indique 2 NSComparisonPredicates.

Le premier sous-prédicat a une expression gauche de type NSKeyPathExpressionType et un -keyPath de @"name", l'opérateur est NSEqualToPredicateOperatorType. L'expression correcte sera un NSExpression de type NSConstantValueExpressionType et -constantValue sera @"John".

Le deuxième subpredicate sera similaire, sauf que l'expression de keyPath gauche sera @"endpoint", et l'expression de constantValue droit sera @"people".

Si vous voulez plus d'informations approfondies sur comment transformer NSPredicates en une demande HTTP Get, consultez mon StackOverflow framework, "StackKit", qui fait exactement cela. Il s'agit essentiellement d'un framework qui se comporte de la même manière que CoreData, mais utilise StackOverflow.com (ou tout autre site d'échange de pile) pour récupérer des informations. En dessous, il fait un lot pour convertir les objets NSPredicate en URL. Vous êtes également invités à m'envoyer des questions spécifiques.

Questions connexes