2012-06-27 35 views
6

Tôi đã sử dụng RestKit 0.10.0 một thời bây giờ và cho đến thời điểm này, tôi chỉ gửi đối tượng serialized đến máy chủ của tôi:RestKit truy vấn tham số GET

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

Cho đến nay, như vậy tốt. Nhưng bây giờ tôi cần thực hiện một yêu cầu GET tới máy chủ với một vài tham số truy vấn. Điều tự nhiên đầu tiên đến trong tâm trí là để làm tương tự như tôi đã làm cho các đối tượng đăng:

  • tạo một ánh xạ serialization cho đối tượng đóng gói các truy vấn tham số
  • tạo một ánh xạ đáp ứng cho đối tượng được nhận từ server
  • xác định và sử dụng một router cho RKRequestMethodGET (thay vì RKRequestMethodPOST)
  • thực hiện yêu cầu sử dụng getObject: usingBlock (thay vì postObject: usingBlock)

Tôi sớm nhận ra đây không phải là cách để làm điều đó, vì vậy sau khi tìm kiếm các nguồn lực sẵn có (RestKit Wiki, RestKit Google group) bây giờ tôi biết về hai giải pháp được coi là hợp lệ:

  • Phụ thêm tham số truy vấn với các đường dẫn tài nguyên.

Điều này hoạt động hoàn hảo.

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; 
               }]; 
  • Thiết lập tham số truy vấn trong khối bộ nạp.

Điều này không gửi các tham số truy vấn.

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

Câu hỏi của tôi là:

  1. Tại sao không phải là công việc giải pháp thứ hai?
  2. Tại sao giải pháp đầu tiên hoạt động mà không phải đặt loader.targetObject thành nil, mặc dù tôi không có bất kỳ đường dẫn khóa gốc nào trong phản hồi JSON?
  3. Những trường hợp nào tôi nên sử dụng phương thức getObject: usingBlock? Mục đích dự định của nó là gì?
  4. Tôi nên sử dụng loader.params để làm gì? Hướng dẫn ánh xạ đối tượng từ wiki cho biết thuộc tính này có thể được sử dụng để đóng gói các tham số POST, nhưng tôi không thấy điểm vì tôi có thể bọc các tham số trong đối tượng tuần tự được gửi với phương thức postObject: usingBlock.

Cảm ơn.

[SAU EDIT]

Về câu trả lời cho câu hỏi thứ hai của tôi: Tôi đã thiết lập các targetObject để nil trong khối bộ nạp khi thực hiện yêu cầu POST + Nhà cách khác RestKit sẽ cố gắng sử dụng các bản đồ gửi đối tượng cho các phản ứng (hãy xem điều này link để biết một cuộc thảo luận liên quan). Nhưng kể từ khi tôi đang sử dụng loadObjectsAtResourcePath: usingBlock :, không có đối tượng được gửi, do đó phản ứng sẽ tự nhiên ánh xạ trên ánh xạ phản hồi mà không cần phải đặt targetObject thành nil.

Trả lời

4
  1. Tại sao giải pháp thứ hai không hoạt động?

thông số được sử dụng để tạo thân HTTP, không được sử dụng trong yêu cầu GET/HEAD.

  1. Tại sao các giải pháp đầu tiên làm việc mà không cần phải thiết lập các loader.targetObject để nil, mặc dù tôi không có bất kỳ gốc chính con đường trong phản ứng JSON?

Tôi nghĩ targetObject là không theo mặc định. Bạn thường không đặt nó, yêu cầu sẽ tạo nó nếu cần. Thời gian duy nhất tôi sử dụng nó là khi yêu cầu các đối tượng không có khóa chính hoặc các vấn đề lạ khác.

  1. Trường hợp tôi nên sử dụng phương thức getObject: usingBlock? Mục đích dự định của nó là gì?

Đây là phương pháp tiện lợi để bạn không phải nhớ tất cả cú pháp chính xác. Bên trong nó chỉ gửi một yêu cầu tải đối tượng bằng GET.

EDIT:

Sử dụng tùy chọn này nếu bạn có đối tượng bạn muốn cập nhật.

  1. Tôi nên sử dụng loader.params để làm gì? Hướng dẫn lập bản đồ đối tượng từ wiki nói thuộc tính này có thể được sử dụng để đóng gói các tham số POST , nhưng tôi không thấy điểm vì tôi có thể bao bọc các tham số trong đối tượng được tuần tự đang được gửi với phương thức postObject: usingBlock.

Bất kỳ nội dung nào bạn đưa vào thông số sẽ được tuần tự hóa thành phần thân HTTP (hoặc luồng nội dung). Một lần nữa, postObject: usingBlock: chỉ là một phương thức tiện lợi để bạn không phải nhớ mọi thứ.

RestKit là mã nguồn mở. Nếu bạn không chắc chắn nó hoạt động như thế nào, bạn có thể tự do theo các tham số bên trong. Nếu ứng dụng và dịch vụ web của bạn được thiết kế tốt, bạn sẽ có thể sử dụng các phương pháp tiện lợi. Đôi khi bạn không thể, và sau đó bạn có thể sử dụng các hình thức thô như bạn đã làm.

EDIT: Q Hrm, trích dẫn các dấu đầu dòng của bạn đã làm sai lệch các con số ...

+0

Cảm ơn bạn. Lời giải thích về yêu cầu GET/HEAD rất hữu ích. –

+0

Cảm ơn bạn, điều này làm rõ tất cả những hiểu lầm của tôi, ngoại trừ một. Bạn đã nói getObject: usingBlock: chỉ là một phương thức tiện lợi mà chỉ gửi một yêu cầu tải đối tượng bằng GET. Điều này nghe có vẻ giống như một định nghĩa cho loadObjectsAtResourcePath: usingBlock :. Trong trường hợp getObject: usingBlock:, phải chỉ định một đối tượng làm tham số đầu tiên và tôi không hiểu người dùng đó là gì, vì tôi chỉ tạo GET, không phải là PUT hoặc POST. –

+0

Ví dụ, nếu bạn đã có một đối tượng, bạn có thể GET dữ liệu mới nhất (cập nhật), hoặc bạn có thể truy cập đường dẫn tài nguyên - cả hai đều làm điều tương tự. Cho dù bạn thích cách nào/dễ dàng hơn. –

3

tôi giải quyết thêm một loại để RKObjectLoader, đó là:

cho phương pháp

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

tôi đã thêm vào loại một phương pháp chỉnh sửa:

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

Dưới đây là danh sách tệp 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 

Dưới đây là danh sách cho tập tin "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 

Thêm một bước là thêm #import "RKObjectManager+QueryParameters.h" trong tập tin thực thi của bạn. Trong phương pháp mới này, giả định rằng thuộc tính router của RKObjectManager đã được xác định trước khi thực hiện cuộc gọi đến nó.

Các vấn đề liên quan