Posting JSON array of strings with RestKit

2019-09-04 03:44发布

问题:

I have the following object

@interface MyObject : NSObject

@property(nonatomic, copy) NSNumber *objectId;
@property(nonatomic, copy) NSArray *tags; // array of strings, e.g. @[@"one", @"two"]

@end

I would like to POST a request using RestKit (version 0.23) to URL

<base_url>/do_something/:objectId

The request body should be just a JSON array of strings according to the tags property, i.e.

["one", "two"]

I have a route defined.

RKRoute *route = [RKRoute routeWithClass: [MyObject class] pathPattern: do_something/:objectId method: RKRequestMethodPOST];
[objectManager.router.routeSet addRoute: route];

Now, I would like to create a request

[objectManager requestWithObject: instanceOfMyObject method: RKRequestMethodPOST path: nil parameters: nil];

How should I configure a [RKObjectMapping requestMapping] and how should I define a RKRequestDescriptor to get the mapping above (JSON array of strings)?

I have tried the following:

RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addPropertyMapping: [RKAttributeMapping attributeMappingFromKeyPath: @"tags" toKeyPath: nil]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping: requestMapping objectClass: [MyObject class] rootKeyPath: nil method: RKRequestMethodAny];

However, using nil as key path in RKAttributeMapping crashes. Using any not-nil value results in request its body is a JSON dictionary

{"someKeyPath": ["one", "two"]}

回答1:

I believe RestKit was designed with the mentality you should be posting an object instead, eg. {"tags": [ "tag1", "tag2" ]}. Same with responses; if the body is not an object (and just a raw string or array), RestKit isn't going to handle it well.

That being said, you can serialize the request yourself and post it to the body. For example:

NSMutableURLRequest *request = [[objectManager requestWithObject:nil method:RKRequestMethodPOST path:@"do_something/objectId" parameters:nil] mutableCopy];

[request setHTTPBody:[NSJSONSerialization dataWithJSONObject:doableIds options:0 error:nil]];

RKObjectRequestOperation *operation = [objectManager objectRequestOperationWithRequest:request success:nil failure:nil];
[objectManager enqueueObjectRequestOperation:operation];