2012-06-27 32 views
6

He estado usando RestKit 0.10.0 desde hace un tiempo y hasta este punto, sólo publicado objetos serializados a mi servidor:RestKit de consulta GET Parámetros

[[RKObjectManager sharedManager] postObject:serializedObject 
           usingBlock:^(RKObjectLoader *loader) { 
            loader.delegate = self; 
            loader.objectMapping = responseMapping; 
            loader.serializationMIMEType = RKMIMETypeFormURLEncoded; 
            loader.targetObject = nil; 
           }]; 

Hasta ahora, todo bien. Pero ahora necesito hacer una solicitud GET al servidor con algunos parámetros de consulta. La primera cosa natural que se produjo en la mente era hacer lo mismo que hice para los objetos de publicación:

  • crear una asignación de serialización para el objeto que encapsula la consulta de parámetros
  • crear una asignación de respuesta para el objeto que está siendo recibida desde el servidor
  • definir y utilizar un router para RKRequestMethodGET (en lugar de RKRequestMethodPOST)
  • hacer la solicitud a través de getObject: usingBlock (en lugar de postObject: usingBlock)

pronto me di cuenta que esto no es la manera de hacerlo, por lo que después de buscar los recursos disponibles (RestKit Wiki, RestKit Google group) Ahora sé de dos soluciones consideradas como válidas:

  • Al añadir los parámetros de consulta a la ruta del recurso.

Esto funciona perfectamente.

NSDictionary *queryParams = [NSDictionary dictionaryWithObjectsAndKeys: 
              token, @"accessToken", 
              [NSNumber numberWithInt:level], @"level", 
              [NSNumber numberWithInt:count], @"count", 
              nil]; 

NSString* resourcePath = [PEER_SUGGESTIONS_CONTROLLER_PATH stringByAppendingQueryParameters:queryParams]; 

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:resourcePath 
               usingBlock:^(RKObjectLoader *loader) { 
                loader.delegate = self; 
                loader.objectMapping = responseMapping; 
               }]; 
  • Configuración de los parámetros de consulta en el bloque del cargador.

Esto no envía los parámetros de consulta.

RKParams *params = [RKParams params]; 
[params setValue:token forParam:@"accessToken"]; 
[params setValue:[NSNumber numberWithInt:level] forParam:@"level"]; 
[params setValue:[NSNumber numberWithInt:count] forParam:@"count"]; 

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:PEER_SUGGESTIONS_CONTROLLER_PATH 
               usingBlock:^(RKObjectLoader *loader) { 
                loader.delegate = self; 
                loader.objectMapping = responseMapping; 
                loader.params = params; 
               }]; 

Mis preguntas son:

  1. Por qué no funciona la segunda solución funcione?
  2. ¿Por qué funciona la primera solución sin tener que configurar loader.targetObject en nil, aunque no tengo ninguna ruta de clave de raíz en la respuesta JSON?
  3. ¿Cuáles son los casos en los que debería usar el método getObject: usingBlock? ¿Cuál es su propósito?
  4. ¿Para qué debo usar loader.params? El tutorial de asignación de objetos del wiki dice que esta propiedad se puede usar para encapsular parámetros POST, pero no veo el punto, ya que puedo ajustar los parámetros en el objeto serializado que se envía con el método postObject: usingBlock.

Gracias.

[editar más tarde]

En cuanto a la respuesta a la segunda pregunta: Me he estado fijando el targetObject a cero en el bloque del cargador al hacer peticiones POST pd lo contrario RestKit intentará utilizar el mapeo de objetos de envío de la respuesta (consulte este link para una discusión relacionada). Pero dado que estoy utilizando loadObjectsAtResourcePath: usingBlock :, no se envía ningún objeto, por lo tanto, la respuesta se asignará de forma natural en el mapeo de respuesta sin tener que establecer targetObject en nil.

Respuesta

4
  1. ¿Por qué no funciona la segunda solución?

params se utiliza para crear un cuerpo de HTTP, que no se utiliza en una petición GET/HEAD.

  1. ¿Por qué es la primera solución de trabajo sin tener que configurar el loader.targetObject a cero, aunque no tengo ninguna ruta de la clave raíz en la respuesta JSON?

Creo que targetObject es nulo por defecto. Normalmente no lo configura, la solicitud lo creará si es necesario. La única vez que lo uso es cuando solicito objetos sin claves primarias u otros problemas extraños.

  1. ¿Cuáles son los casos en los que debería utilizar el getObject: Método usingBlock? ¿Cuál es su propósito?

Este es un método de conveniencia por lo que no tiene que recordar toda la sintaxis correcta. Internamente, solo envía una solicitud de carga de objetos usando GET.

EDIT:

Usar esta opción si tiene un objeto que desea actualizar.

  1. ¿Qué debo usar para loader.params? El tutorial de mapeo de objetos del wiki dice que esta propiedad se puede usar para encapsular los parámetros POST , pero no veo el punto ya que puedo ajustar los parámetros en el objeto serializado que se envía con el método postObject: usingBlock.

Lo que pones en params se serializa en un cuerpo de HTTP (o flujo corporal). Nuevamente, postObject: usingBlock: es solo un método de conveniencia para que no tenga que recordar todo.

RestKit es de código abierto. Si no está seguro de cómo funciona, es libre de seguir los parámetros internamente. Si su aplicación y servicio web están bien diseñados, debe poder utilizar los métodos de conveniencia. Algunas veces no puedes, y luego puedes usar las formas crudas como lo has hecho.

EDIT: Q Hrm, citando sus viñetas confundió los números ...

+0

Gracias. La explicación sobre la solicitud GET/HEAD es muy útil. –

+0

Gracias, esto aclara todos mis malentendidos, excepto uno. Dijiste getObject: usingBlock: es solo un método de conveniencia que simplemente envía una solicitud de carga de objetos usando GET. Esto suena más como una definición de loadObjectsAtResourcePath: usingBlock :. En el getObject: usingBlock: case, tengo que especificar un objeto como primer parámetro y no entiendo para qué sirve, ya que solo estoy haciendo un GET, no un PUT o un POST. –

+0

Por ejemplo, si ya tiene un objeto, puede OBTENER los datos más recientes (actualización), o puede acceder a la ruta del recurso; ambos hacen lo mismo. De cualquier manera que prefiera/es más fácil. –

3

He resuelto añadiendo una categoría a RKObjectLoader, es decir:

para el método

-(void)getObject:(id<NSObject>)object usingBlock:(RKObjectLoaderBlock)block; 

he añadido en la categoría de un método modificado:

-(void)getObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters usingBlock:(void(^)(RKObjectLoader *))block; 

Aquí está la lista Archivo fpr "RKObjectManager + QueryParameters":

// 
// RKObjectManager+QueryParameters.h 
// AlphaClient 
// 
// Created by Antonio Rossi on 14/07/12. 
// 

#import <RestKit/RestKit.h> 

@interface RKObjectManager (QueryParameters) 

- (void)getObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters usingBlock:(void(^)(RKObjectLoader *))block; 
- (void)sendObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters method:(RKRequestMethod)method usingBlock:(void(^)(RKObjectLoader *))block; 

@end 

Aquí está el listado para archivo "RKObjectManager + QueryParameters.m":

// 
// RKObjectManager+QueryParameters.m 
// AlphaClient 
// 
// Created by Antonio Rossi on 14/07/12. 
// 

#import "RKObjectManager+QueryParameters.h" 

@implementation RKObjectManager (QueryParameters) 

- (void)getObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters usingBlock:(void(^)(RKObjectLoader *loader))block { 
    [self sendObject:object queryParameters:queryParameters method:RKRequestMethodGET usingBlock:block]; 
} 

- (void)sendObject:(id<NSObject>)object queryParameters:(NSDictionary*)queryParameters method:(RKRequestMethod)method usingBlock:(void(^)(RKObjectLoader *))block { 
    NSString *resourcePath = [self.router resourcePathForObject:object method:method]; 
    [self sendObject:object toResourcePath:resourcePath usingBlock:^(RKObjectLoader *loader) { 
     loader.method = method; 

     // need to transform the original URL because when method is GET the additional paramentes don't get added 
     RKURL *originalBaseURL = [RKURL URLWithBaseURL:[loader.URL baseURL]]; 
     NSString *resourcePath = [self.router resourcePathForObject:object method:RKRequestMethodGET]; 
     RKURL *authTokenURL = [originalBaseURL URLByAppendingResourcePath:resourcePath queryParameters:queryParameters]; 
     [loader setURL:authTokenURL]; 

     block(loader); 
    }]; 
} 

@end 

Un paso más es añadir #import "RKObjectManager+QueryParameters.h" en su archivo de aplicación. En este nuevo método, se supone que la propiedad router de RKObjectManager se ha definido antes de realizar una llamada.

Cuestiones relacionadas