2013-08-09 2 views
2

Итак, я пользуюсь RestKit версии 0.20 и i m успешно отправляет запрос POST как JSON. Мой серверный сервер (Java REST WS (Джерси)) отображает все правильно, а также Restkit.RestKit - Отправка ответа POST и получения ответа

Моя проблема в том, что я отправляю другой объект обратно, поскольку у меня есть сообщение. У меня после установки отображения в RestKit:

- (void)createUserAccount:(DeviceDTO *)devDTO :(UserDTO *)userDTO block:(void (^)(id))block{ 
    id errorCode __block; 
    // Configure a request mapping for our Article class. We want to send back title, body, and publicationDate 
    RKObjectMapping* deviceRequestMapping = [RKObjectMapping requestMapping]; 
    [deviceRequestMapping addAttributeMappingsFromArray:@[ @"model", @"name", @"systemName", @"systemVersion", @"devToken" ]]; 

    RKObjectMapping* msRequestMapping = [RKObjectMapping requestMapping]; 
    [msRequestMapping addAttributeMappingsFromArray:@[ @"validSince", @"validTill" ]]; 

    RKObjectMapping* countryRequestMapping = [RKObjectMapping requestMapping]; 
    [countryRequestMapping addAttributeMappingsFromArray:@[ @"idNumberDTO", @"iso2DTO", @"short_nameDTO", @"calling_codeDTO" ]]; 

    RKObjectMapping* contactsRequestMapping = [RKObjectMapping requestMapping]; 
    [contactsRequestMapping addAttributeMappingsFromArray:@[ @"fullName", @"phoneNumber"]]; 

    RKObjectMapping* userRequestMapping = [RKObjectMapping requestMapping]; 
    [userRequestMapping addAttributeMappingsFromArray:@[ @"displayName", @"phoneNumber", @"status", @"userID", @"realName" ]]; 

    [userRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"deviceInfo" toKeyPath:@"device" withMapping:deviceRequestMapping]]; 
    [userRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"memberShipDetails" toKeyPath:@"memberShip" withMapping:msRequestMapping]]; 
    [userRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"country" toKeyPath:@"country" withMapping:countryRequestMapping]]; 
    [userRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"contacts" toKeyPath:@"contacts" withMapping:contactsRequestMapping]]; 

    RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userRequestMapping objectClass:[UserDTO class] rootKeyPath:nil]; 


    //Create Objects 
    UserDTO *user = [[UserDTO alloc]init]; 
    .......... 

    DeviceDTO *device = [[DeviceDTO alloc]init]; 
    .......... 

    user.deviceInfo = device; 

    MemberShipDTO *ms = [[MemberShipDTO alloc]init]; 
    ....... 

    user.memberShipDetails = ms; 



    RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[ErrorMapping class]]; 
    [errorMapping addAttributeMappingsFromArray:@[ @"errorCode", @"errorMessage" ]]; 

    RKObjectMapping* deviceRespMapping = [RKObjectMapping mappingForClass:[DeviceDTO class]]; 
    [deviceRespMapping addAttributeMappingsFromArray:@[ @"model", @"name", @"systemName", @"systemVersion", @"devToken" ]]; 

    RKObjectMapping* msRespMapping = [RKObjectMapping mappingForClass:[MemberShipDTO class]]; 
    [msRespMapping addAttributeMappingsFromArray:@[ @"validSince", @"validTill" ]]; 

    RKObjectMapping* contactsRespMapping = [RKObjectMapping mappingForClass:[ContactDTO class]]; 
    [contactsRespMapping addAttributeMappingsFromArray:@[ @"fullName", @"phoneNumber"]]; 

    RKObjectMapping* userRespMapping = [RKObjectMapping mappingForClass:[UserDTO class]]; 
    [userRespMapping addAttributeMappingsFromArray:@[ @"displayName", @"phoneNumber", @"status", @"userID", @"realName" ]]; 

    [userRespMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"deviceInfo" toKeyPath:@"device" withMapping:deviceRespMapping]]; 
    [userRespMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"memberShipDetails" toKeyPath:@"memberShip" withMapping:msRespMapping]]; 
    [userRespMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"country" toKeyPath:@"country" withMapping:countryRequestMapping]]; 
    [userRespMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"contacts" toKeyPath:@"contacts" withMapping:contactsRespMapping]]; 

    [errorMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"user" toKeyPath:@"user" withMapping:userRespMapping]]; 

    RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping pathPattern:nil keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; 

    [RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"application/json"]; 

    [[RKObjectManager sharedManager] setRequestSerializationMIMEType:RKMIMETypeJSON]; 
    [[RKObjectManager sharedManager] setAcceptHeaderWithMIMEType:RKMIMETypeJSON]; 
    [[RKObjectManager sharedManager] addRequestDescriptor:requestDescriptor]; 
    [[RKObjectManager sharedManager] addResponseDescriptor:errorDescriptor]; 
    [[RKObjectManager sharedManager] postObject:user path:@"user/integrate" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult){ 
     NSArray* statuses = [mappingResult array]; 
     NSLog(@"Loaded statuses: %@", statuses); 
     errorCode = [statuses objectAtIndex:0]; 
     NSLog(@"errorCode == %@", errorCode); 
     block(errorCode); 
     RKLogInfo(@"Load collection of Articles: %@", mappingResult.array); 
    }failure:^(RKObjectRequestOperation *operation, NSError *error) { 
     block(nil); 
     RKLogError(@"Operation failed with error: %@", error); 
    }]; 

} 

Моя JSON по моей просьбе отлично & ответ тоже хорошо:

{ 
    "errorMessage": null, 
    "errorCode": 190, 
    "user": { 
     "displayName": "Saif", 
     "phoneNumber": "+xxx", 
     "userID": "xxx", 
     "country": { 
      "idNumberDTO": 83, 
      "short_nameDTO": "Germany", 
      "calling_codeDTO": "+49", 
      "iso2DTO": "DE" 
     }, 
     "device": { 
      "devToken": "xxx", 
      "model": "iPhone", 
      "name": "Saifs iPhone", 
      "systemName": "iPhone OS", 
      "systemVersion": "6.1.4", 
      "id": null 
     }, 
     "memberShip": { 
      "validSince": 1376047810000, 
      "validTill": 1407583810000, 
      "id": null 
     }, 
     "contacts": [ 
      { 
       "fullName": "xxx", 
       "phoneNumber": "xxx" 
      }, 
      { 
       "fullName": "xxx", 
       "phoneNumber": "xxx" 
      }, 
      ...., 
      ...., 
      .... 
     ], 
     "id": null 
    } 
} 

На моем Methode RK я получаю на этой линии:

errorCode = [statuses objectAtIndex:0]; 

это ошибка:

2013-08-09 13:30:12.246 xxx![19310:440f] W restkit.object_mapping:RKMapperOperation.m:99 Adding mapping error: Expected an object mapping for class of type 'UserDTO', provider returned one for 'ErrorMapping' 
2013-08-09 13:30:12.247 xxx![19310:440f] I restkit.network:RKObjectRequestOperation.m:250 POST 'http://192.168.2.115:8080/WAZZUUPWS/rest/service/user/integrate' (200 OK/0 objects) [request=1.3406s mapping=0.0047s total=1.3461s] 
2013-08-09 13:30:12.249 xxx![19310:907] Loaded statuses: (
) 
2013-08-09 13:30:12.250 xxx![19310:907] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array' 

Похоже, что ответ не может быть отображен, и поэтому Resultarray пуст. Любая идея, как я могу отобразить сложный объект из ответа?

ответ

9

Restkit documentation Из:

По умолчанию, когда postObject или putObject используются, RestKit автоматически будет пытаться отобразить результат JSON в SourceObject, который был размещен.

В вашем коде вы отправляете экземпляр UserDTO и получаете ответ JSON, который должен отображаться в ErrorMapping. Следовательно, вы получаете RKMappingErrorTypeMismatch из Restkit.

Как объяснено в documentation, вместо использования сообщения вы можете самостоятельно создать RKRequestOperation и nil целевой объект переопределить значения по умолчанию.

RKObjectRequestOperation *operation = [[RKObjectManager sharedManager] appropriateObjectRequestOperationWithObject:user 
                              method:RKRequestMethodPOST 
                               path:@"user/integrate" 
                             parameters:nil]; 
operation.targetObject = nil; 

[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) { 
    DLog(@"integrated user: %@", mappingResult.firstObject); 
} failure:^(RKObjectRequestOperation *operation, NSError *error) { 
    DLog(@"error integrating user: %@", user); 
}]; 

Однако, если вы можете изменить бэкэнд, я бы предпочел изменить возвращенный JSON. Вместо того, чтобы включать коды ошибок в ответ JSON, используйте соответствующие коды состояния ответа HTTP (HTTP) и включайте в свои ответы только объекты, зависящие от модели домена.

+0

Mhh. Не могли бы вы попытаться привести пример для RKRequestOperation? – SaifDeen

+0

Обновлено, чтобы включить образец кода. – serrrgi

+0

-.- пытался все это время как [[RKObjectManager sharedManager] enqueueObjectRequestOperation: operation]; – SaifDeen

Смежные вопросы