2013-12-09 46 views
0

我新的內部監督辦公室和RestKit並不能弄清楚如何做到以下幾點:RestKit做了一條信息對象和獲取物體響應

1. a simple POST to a webservice 
    A) with an object payload 
    B) Have RestKit Auto Serialize the obj c object into Json 

2. Receive the Response 
    A) Parse response and extract only certain fields and load into obj c object 

我的設置如下:

的Json從web服務響應:從web服務

{ 
    "user": { 
      "id":0, 
      "email":"String", 
    }, 
    "errorCode": 0 
} 

響應對象中的obj C:

@interface CreateAccountResponse : NSObject 

@property (nonatomic, copy) NSString *id; 
@property (nonatomic, copy) NSString *email; 
@property (nonatomic) NSInteger *errorCode; 

@end 

請求對象OBJ中的C:

@interface CreateAccountRequestModel : NSObject 

@property (nonatomic, copy) NSString *email; 
@property (nonatomic, copy) NSString *password; 
@property (nonatomic, copy) NSString *first_name; 
@property (nonatomic, copy) NSString *last_name; 

@end 

Webservice的預計此JSON的POST請求:

{ 
    "email":"String", 
    "password":"String", 
    "first_name":"String", 
    "last_name":"String" 
} 

網址是:www.hostname.com/api/AccountManager/createAccount,而且只接受POST請求。

我曾嘗試:

-(void)SendCreateAccountRequest:(CreateAccountRequestModel*)createActModel 
{ 
    NSString *createAccountUrl = @"www.hostname.com/api/AccountManager/createAccount"; 
    NSLog(@"SendCreateAccountRequest"); 
    RKObjectMapping* articleMapping = [RKObjectMapping mappingForClass: [CreateAccountResponse class]]; 
    [articleMapping addAttributeMappingsFromDictionary:@{ 
                 @"id": @"user.id", 
                 @"email": @"user.email", 
                 @"errorCode": @"errorCode" 
                 }]; 

    RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:articleMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"createAccount" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 

    NSURL *URL = [NSURL URLWithString:createAccountUrl]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 
    RKObjectRequestOperation *objectRequestOperation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[ responseDescriptor ]]; 

    [objectRequestOperation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) 
    { 
     RKLogInfo(@"Successful Response: %@", mappingResult.array); 
    } 
    failure:^(RKObjectRequestOperation *operation, NSError *error) 
    { 
     RKLogError(@"Operation failed with error: %@", error); 
    }]; 

    [objectRequestOperation start]; 

我知道我沒有正確映射從web服務對象的反應,我沒有正確創建POST請求。就像我說我是新的,所以你給更好:)

回答

1

用戶對象

@interface User : NSObject 

@property (nonatomic, copy) NSString *id; 
@property (nonatomic, copy) NSString *email; 
@property (nonatomic, copy) NSString *password; 
@property (nonatomic, copy) NSString *first_name; 
@property (nonatomic, copy) NSString *last_name; 

@end 

POST http://www.hostname.com/api/AccountManager/createAccount

響應JSON

{ 
    "id":0, 
    "email":"String", 
} 

創建服務器

- (void)createUserOnServer:(User *)user 
{ 
    RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[User class]]; 
    [responseMapping addAttributeMappingsFromArray:@[@"id",@"email"]]; 
    NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); 
    RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping method:RKRequestMethodAny pathPattern:@"/createAccount" keyPath:@"article" statusCodes:statusCodes]; 

    RKObjectMapping *requestMapping = [RKObjectMapping requestMapping]; // objectClass == NSMutableDictionary 
    [requestMapping addAttributeMappingsFromArray:@[@"email", @"password", @"first_name", @"last_name"]]; 

    RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[Article class] rootKeyPath:nil method:RKRequestMethodAny]; 

    RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://www.hostname.com/api/AccountManager"]; 
    [manager addRequestDescriptor:requestDescriptor]; 
    [manager addResponseDescriptor:articleDescriptor]; 
    [manager postObject:user path:@"/createAccount" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
       NSLog(@"Create User Success"); 
      } failure:^(RKObjectRequestOperation *operation, NSError *error) { 
       NSLog(@"Create User Error: %@", error); 
      }]; 
} 

PS:你最好閱讀Restkit的README完全!

PS2:通過HTTP的StatusCode錯誤代碼是更好

+0

我是很新的RESTKIT,並努力學習,謝謝爲您提供幫助。 – Aziz

1

這應該使一個職位的詳細信息,而無需第三方庫。一旦你得到這個工作,你可以把一個getter在同一類,並調用它的RestKit,或使用工作示例調試RestKit問題。 (我的偏好是前者)。

+ (void)postTo:(NSString *)urlString params:(NSDictionary *)params completion:(void (^)(id, NSError *))completion { 

    NSURL *url = [NSURL URLWithString:urlString]; 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 
    [request setHTTPMethod:@"POST"]; 

    if (params.count) { 
     NSMutableArray *paramArray = [NSMutableArray array]; 
     for (NSString *key in [params allKeys]) { 
      NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
      NSString *encodedValue = [params[key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
      NSString *encodedPair = [[encodedKey stringByAppendingString:@"="] stringByAppendingString:encodedValue]; 
      [paramArray addObject:encodedPair]; 
     } 

     NSString *paramString = [paramArray componentsJoinedByString:@"&"]; 

     NSData *data = [paramString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 
     [request setHTTPBody:data]; 
     [request setValue:[NSString stringWithFormat:@"%d", [data length]] forHTTPHeaderField:@"Content-Length"]; 
     [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
    } 

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 

     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; 

     if (!error && httpResponse.statusCode < 400) { 
      NSError *parseError; 
      id parse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError]; 
      if (!parseError) { 
       completion(parse, nil); 
      } else { 
       NSLog(@"parse error %@", parseError); 
       completion(nil, parseError); 
      } 
     } else { 
      NSLog(@"http status %d, error %@", httpResponse.statusCode, error); 
      completion(nil, error); 
     } 
    }]; 
} 

這樣稱呼它:

NSString *urlString = @"http://www.hostname.com/api/AccountManager/createAccount"; 
NSDictionary *params = @{ @"email": @"[email protected]" /* and so on */ }; 

// assume the method above is a class method in "ThePostingClass" 
[ThePostingClass postTo:urlString params:params completion:^(id result, NSError *error) { 
    if (!error) { 
     NSLog(@"%@", result); 
    } else { 
     NSLog(@"%@", error); 
    } 
}]; 

消氣比較容易,改變setHttpMethod到@ 「GET」,並任選通過追加中的paramString作爲查詢字符串移動PARAMS。

+0

這是一個良好的通話,使用內置的庫中實現它,然後轉移到使用restkit – Aziz

1

keyPath:@"createAccount"您的響應描述符似乎是錯誤的,因爲您的JSON不包含此密鑰(所以它應該是keyPath:nil)。這實際上應該設置爲路徑模式(pathPattern:@"createAccount")。

您應該真的使用RKObjectManager的實例來創建和發送請求 - 這將允許您輕鬆地序列化要發送的請求對象。爲了實現這個功能,您需要創建一個請求描述符,並在其中包含對象中的鍵映射(名稱不會更改,因此它只是一個簡單的映射)。

使用RKObjectManager時,您可以使用它註冊請求和響應描述符,然後只是GET/POST對象。該RKObjectManager將決定,從你的要求,應該用什麼請求和響應映射指定路徑。

當您創建RKObjectManager時,請使用基本URL www.hostname.com/api/AccountManager

最後,要發送JSON,您需要在RKObjectManager上設置requestSerializationMIMEType(因爲它不默認爲JSON)。