How do I ignore empty properties on posted objects using restkit

丶灬走出姿态 提交于 2019-12-24 12:14:38

问题


I am reviving an old project that originally used RestKit 0.10, and now am using RestKit 0.24. The old version still works, but unfortunately RestKit 0.10 is not 64-bit compatible and hence does not submit to the AppStore (and it is certainly time to update anyway).

I cannot get an object to post correctly. In RestKit 0.10, properties without values were not sent to the server, whereas it seems in RestKit 0.20 they are. I have tried explicitly setting assignsDefaultValueForMissingAttributes to NO, but it doesn't seem to make a difference.

The server expects the following format:

{"response": {"assessment_id":"1","time_taken":"60"},
 "answer": [
      {"question_number": 1, "answer_value": 3},
      {"question_number": 2, "answer_value": 2},
      {"question_number": 3, "answer_value": 1},
 ]
}

I have set up an object CompletedAssessment which contains a Response object and an array of Answer objects. (Note that when these objects are received from the server, many more properties need to be received than need to be sent).

@interface CompletedAssessment : NSObject {
    Response *response;
    NSArray *answers;
}

@interface Answer : NSObject {
    NSNumber *identifier;
    NSNumber *responseId;
    NSNumber *questionNumber;
    NSString *answerHistory;
    NSString *answerValue;
    NSString *answerText;
    NSNumber *timeTaken;
}

@interface Response : NSObject {
    NSNumber *identifier;
    NSNumber *assessmentId;
    NSNumber *timeTaken;
    NSNumber *clientId;
    NSString *assessmentShortName;
    NSString *score;
    NSString *interpretation;
    NSString *dateCreated;
    NSString *localTime;

}

I set the mapping up as follows:

RKObjectMapping *answerMapping = [RKObjectMapping mappingForClass:[Answer class]];
answerMapping.assignsDefaultValueForMissingAttributes = NO;

[answerMapping addAttributeMappingsFromDictionary:@{
                                                  @"id": @"identifier",
                                                  @"response_id": @"responseId",
                                                  @"question_number": @"questionNumber",
                                                  @"answer_history": @"answerHistory",
                                                  @"answer_value": @"answerValue",
                                                  @"answer_text": @"answerText",
                                                  @"time_taken": @"timeTaken"
                                                  }];

RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[Response class]];
responseMapping.assignsDefaultValueForMissingAttributes = NO;

[responseMapping addAttributeMappingsFromDictionary:@{
                                                   @"id": @"identifier",
                                                   @"client_id": @"clientId",
                                                   @"assessment_id": @"assessmentId",
                                                   @"time_taken": @"timeTaken",
                                                   @"score": @"score",
                                                   @"assessment_short_name": @"assessmentShortName",
                                                   @"interpretation": @"interpretation",
                                                   @"created": @"dateCreated",
                                                   @"local_time": @"localTime"
                                                   }];

RKObjectMapping *completedAssessmentMapping = [RKObjectMapping mappingForClass:[CompletedAssessment class]];
completedAssessmentMapping.assignsDefaultValueForMissingAttributes = NO;

[completedAssessmentMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"response" toKeyPath:@"response" withMapping:responseMapping]];
[completedAssessmentMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"answer" toKeyPath:@"answers" withMapping:answerMapping]];

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:completedAssessmentMapping method:RKRequestMethodGET pathPattern:nil keyPath:@"data.completedAssessment" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[RKObjectManager sharedManager] addResponseDescriptor:responseDescriptor];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[completedAssessmentMapping inverseMapping] objectClass:[CompletedAssessment class] rootKeyPath:nil method:RKRequestMethodPOST];
[[RKObjectManager sharedManager] addRequestDescriptor:requestDescriptor];

[objectManager.router.routeSet addRoute:[RKRoute
                                         routeWithClass:[CompletedAssessment class]
                                         pathPattern:@"clients/:response.clientId/responses"
                                         method:RKRequestMethodPOST]] ;

Logging reveals the end JSON appears in this format:

{"response":
    {"interpretation":null,"id":null,"score":null,"client_id":15,"local_time":"2015-8-6 13:8:34","time_taken":5,"assessment_short_name":null,"assessment_id":8,"created":null},
"answer":[
    {"answer_value":"0","id":null,"answer_text":null,"answer_history":null,"time_taken":null,"response_id":null,"question_number":1},
    {"answer_value":"1","id":null,"answer_text":null,"answer_history":null,"time_taken":null,"response_id":null,"question_number":2}
]}

And RestKit logging confirms the null mapping:

restkit.object_mapping:RKMappingOperation.m:873 Mapped relationship object from keyPath 'response' to 'response'. Value: {
"assessment_id" = 8;
"assessment_short_name" = "<null>";
"client_id" = 15;
created = "<null>";
id = "<null>";
interpretation = "<null>";
"local_time" = "2015-8-6 13:8:34";
score = "<null>";
"time_taken" = 5;
}

restkit.object_mapping:RKMappingOperation.m:715 Mapped attribute value from keyPath 'identifier' to 'id'. Value: (null)
...

Please help!


回答1:


You are creating a new mapping calling [selfCompletedAssessmentMapping inverseMapping] in this line:

RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[selfCompletedAssessmentMapping inverseMapping] objectClass:[CompletedAssessment class] rootKeyPath:nil method:RKRequestMethodPOST];

Save it to a variable and assign assignsDefaultValueForMissingAttributes to NO before creating the descriptor:

RKObjectMapping *requestMapping = [selfCompletedAssessmentMapping inverseMapping];
requestMapping.assignsDefaultValueForMissingAttributes = NO;
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[CompletedAssessment class] rootKeyPath:nil method:RKRequestMethodPOST];


来源:https://stackoverflow.com/questions/31846262/how-do-i-ignore-empty-properties-on-posted-objects-using-restkit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!