2012-06-27 19 views
6

Sto usando RestKit 0.10.0 per un po 'di tempo e fino a questo punto, ho postato solo oggetti serializzati al mio server:RestKit interrogazione ottenere i parametri

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

Fin qui, tutto bene. Ma ora ho bisogno di fare una richiesta GET al server con alcuni parametri di query. La prima cosa naturale che è venuto in mente è stato quello di fare lo stesso come ho fatto per gli oggetti della pubblicazione:

  • creare una mappatura di serializzazione per l'oggetto incapsulare query parametri
  • creare una mappatura di risposta per l'oggetto che viene ricevuta da il server
  • definire e utilizzare un router per RKRequestMethodGET (invece di RKRequestMethodPOST)
  • fare la richiesta utilizzando getObject: usingBlock (invece di postObject: usingBlock)

ho scoperto presto questo non è il modo per farlo, quindi dopo aver cercato le risorse disponibili (RestKit Wiki, RestKit Google group) ora so di due soluzioni considerata valida:

  • Aggiungendo i parametri di query al percorso risorsa.

Questo funziona perfettamente.

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; 
               }]; 
  • impostazione dei parametri di ricerca nel blocco caricatore.

Questo non invia i parametri di query.

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; 
               }]; 

Le mie domande sono:

  1. Perché non fa il secondo lavoro soluzione?
  2. Perché la prima soluzione funziona senza dover impostare loader.targetObject su zero, sebbene non abbia alcun percorso della chiave radice nella risposta JSON?
  3. Quali sono i casi in cui dovrei usare il metodo getObject: usingBlock? Qual è lo scopo previsto?
  4. Per cosa dovrei usare loader.params? Il tutorial di mappatura degli oggetti del wiki dice che questa proprietà può essere utilizzata per incapsulare i parametri POST, ma non vedo il punto poiché posso avvolgere i parametri nell'oggetto serializzato che viene inviato con il metodo postObject: usingBlock.

Grazie.

[DOPO EDIT]

Per quanto riguarda la risposta alla mia seconda domanda: Sto impostando il targetObject a zero nel blocco del caricatore quando si effettuano le richieste POST beacause altrimenti RestKit tenterà di utilizzare la mappatura oggetto di invio per la risposta (controllare questo link per una discussione correlata). Ma dal momento che sto usando loadObjectsAtResourcePath: usingBlock :, non è stato inviato alcun oggetto, quindi la risposta sarà naturalmente mappata sul mapping delle risposte senza dover impostare il targetObject su zero.

risposta

4
  1. Perché la seconda soluzione non funziona?

params viene utilizzato per creare un corpo HTTP, che non viene utilizzato in una richiesta GET/HEAD.

  1. Perché è la prima soluzione di lavoro senza dover impostare il loader.targetObject a zero, anche se non ho nessuna radice percorso chiave nella risposta JSON?

Penso che targetObject è zero per impostazione predefinita. Normalmente non lo imposti, la richiesta lo creerà se necessario. L'unica volta che lo uso è quando richiedi oggetti senza chiavi primarie o altri problemi strani.

  1. Quali sono i casi in cui devo usare il getObject: metodo di usingBlock? Qual è lo scopo previsto?

Questo è un metodo comodo in modo da non dover ricordare tutti la sintassi corretta. Internamente invia semplicemente una richiesta di caricamento dell'oggetto tramite GET.

EDIT:

Utilizzare questo se si dispone di un oggetto che si desidera aggiornare.

  1. Per cosa utilizzare loader.params? Il tutorial di mappatura degli oggetti del wiki dice che questa proprietà può essere usata per incapsulare i parametri POST , ma non vedo il punto dato che posso avvolgere i parametri nell'oggetto serializzato che viene inviato con il metodo postObject: usingBlock.

Qualunque cosa si mette in params verrà serializzato a un corpo HTTP (o flusso del corpo). Anche in questo caso, postObject: usingBlock: è solo un metodo di convenienza in modo da non dover ricordare tutto.

RestKit è open source. Se non sei sicuro di come funziona, sei libero di seguire i parametri internamente. Se l'app e il servizio web sono ben progettati, dovresti essere in grado di utilizzare i metodi di convenienza. A volte non puoi, e quindi puoi usare le forme grezze come hai fatto tu.

MODIFICA: Q Hrm, citando i punti elenco ha incasinato i numeri ...

+0

Grazie. La spiegazione sulla richiesta GET/HEAD è molto utile. –

+0

Grazie, questo chiarisce tutti i miei equivoci, tranne uno. Hai detto getObject: usingBlock: è solo un metodo di convenienza che invia semplicemente una richiesta di caricamento dell'oggetto utilizzando GET. Questo suona più come una definizione per loadObjectsAtResourcePath: usingBlock :. Nel getObject: usingBlock: case, è necessario specificare un oggetto come primo parametro e non capisco a cosa serve, poiché sto facendo solo un GET, non un PUT o un POST. –

+0

Ad esempio, se si dispone già di un oggetto, è possibile ottenere i dati più recenti (aggiornamento) oppure è possibile accedere al percorso della risorsa - entrambi fanno la stessa cosa. Qualunque modo tu preferisca/è più facile. –

3

ho risolto aggiungendo una categoria per RKObjectLoader, vale a dire:

per il metodo

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

ho aggiunto nella categoria un metodo modificato:

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

Ecco la lista file 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 

Ecco l'elenco per il file "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 altro passo è quello di aggiungere #import "RKObjectManager+QueryParameters.h" nel file di implementazione. In questo nuovo metodo si presuppone che la proprietà router di RKObjectManager sia stata definita prima di effettuare una chiamata.