Note that there are some explanatory texts on larger screens.

plurals
  1. PORestKit: How does one post an array of objects?
    primarykey
    data
    text
    <p><strong>Question summary:</strong></p> <p>Consider a class <code>SyncObject</code> that is KVC-compliant with properties such as: <code>time</code>, <code>someValue</code>, <code>lastChange</code>, <code>uuid</code>.</p> <p>Consider an <code>NSArray</code> containing exclusively instances of <code>SyncObject</code>.</p> <p>I need to submit the array to the server as a JSON array.</p> <p>How would one submit this array to the server using HTTP POST using RestKit?</p> <p>Example array:</p> <pre><code>[ { "time": "14:45 10/21/2011", "someValue": "15", "lastChange": "14:45 10/21/2011", "uuid": "0b07c510-f4c8-11e0-be50-0800200c9a66" }, { "time": "14:50 10/21/2011", "someValue": "62", "lastChange": "14:51 10/21/2011", "uuid": "1a6d4480-f4c8-11e0-be50-0800200c9a66" } ] </code></pre> <hr> <p><strong>Details</strong></p> <p>I have an array of objects that I need to the server as JSON. It seems to me that RestKit is the easiest way to do this: I'm trying to avoid converting objects into a set of <code>NSDictionary</code> objects, and then using some JSON encoder to get JSON which I can <code>POST</code> to the server.</p> <p>So, having created the array, and having set up the mapping for the class of objects stored in the array, I naturally try to <code>POST</code> to the server.</p> <pre><code>RKObjectManager* mgr = [RKObjectManager objectManagerWithBaseURL:@"http://localhost/someweb/api/"]; mgr.serializationMIMEType = RKMIMETypeFormURLEncoded; mgr.client.username = @"username"; mgr.client.password = @"password"; RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]]; [mapping mapKeyPath: @"time" toAttribute:@"time" ]; [mapping mapKeyPath: @"someValue" toAttribute:@"someValue" ]; [mapping mapKeyPath: @"lastChange" toAttribute:@"lastChange" ]; [mapping mapKeyPath: @"uuid" toAttribute:@"uuid" ]; RKObjectMapping* mappingForSerialization = [mapping inverseMapping]; [mgr.mappingProvider setSerializationMapping:mappingForSerialization forClass:[NSManagedObject class]]; [mgr.router routeClass:[NSManagedObject class] toResourcePath:@"/sync" forMethod:RKRequestMethodPOST]; [mgr postObject:array delegate:nil/*self*/]; </code></pre> <p>However, this is what I get out:</p> <pre> 2011-10-11 14:57:51.769 AppConnect[1974:6e0b] *** Terminating app due to uncaught exception '(null)', reason: 'Unable to find a routable path for object of type '__NSArrayI' for HTTP Method 'POST'' </pre> <p>Apparently, RestKit does not know how to handle <code>NSArray</code>s. </p> <p><strong>How does one post an array of objects using RestKit?</strong></p> <hr> <p>I've tried something different: I replaced the last line with a manual send through <code>RKObjectLoader</code>.</p> <pre><code>//[mgr postObject:[NSMutableDictionary dictionaryWithObject:array forKey:@"data"] delegate:nil/*self*/]; NSString* syncPath = @"/sync"; RKObjectLoader * objectLoader = [mgr objectLoaderWithResourcePath:syncPath delegate:self]; objectLoader.serializationMIMEType = RKMIMETypeJSON; objectLoader.method = RKRequestMethodPOST; //objectLoader.objectClass = [NSManagedObject class]; //objectLoader.managedObjectStore = mgr.objectStore; objectLoader.params = [NSDictionary dictionaryWithObject:array forKey:@"MyData"]; [objectLoader send]; </code></pre> <p>Unfortunately, this does not apply mapping of any sort, and instead transmits an array of objects' descriptions. Setting <code>serializationMIMEType</code> also does not affect the structure of transmitted contents, and <code>params</code> are always transmitted as <code>application/x-www-form-urlencoded</code>. </p> <p>I also tried assigning serialization mapping and passing the object as <code>targetObject</code> and <code>sourceObject</code> (this seems to be what RestKit does internally in <code>-[RKObjectManager postObject:delegate:]</code>).</p> <pre><code>RKObjectLoader * objectLoader = [mgr objectLoaderWithResourcePath:syncPath delegate:self]; objectLoader.method = RKRequestMethodPOST; //objectLoader.objectClass = [NSManagedObject class]; //objectLoader.managedObjectStore = mgr.objectStore; objectLoader.params = [NSMutableDictionary dictionaryWithObject:array forKey:@"MyData"]; objectLoader.serializationMapping = mapping; objectLoader.serializationMIMEType = RKMIMETypeJSON; objectLoader.sourceObject = objectLoader.params; objectLoader.targetObject = objectLoader.params; [objectLoader send]; </code></pre> <p>Unfortunately, no mapping occurs this way:</p> <pre><code>2011-10-12 12:36:48.143 MyProject[5119:207] D restkit.network:RKObjectLoader.m:290 POST or PUT request for source object { MyData = ( "&lt;NSManagedObject: 0x5935430&gt; (entity: SomeRecord; id: 0x5934da0 &lt;x-coredata://64DF9977-DA50-4FCD-8C20-4132E58439BF/SomeRecord/p1&gt; ; data: &lt;fault&gt;)", "&lt;NSManagedObject: 0x5935730&gt; (entity: SomeRecord; id: 0x5934db0 &lt;x-coredata://64DF9977-DA50-4FCD-8C20-4132E58439BF/SomeRecord/p2&gt; ; data: &lt;fault&gt;)" ); }, serializing to MIME Type application/json for transport... 2011-10-12 12:36:48.143 MyProject[5119:207] D restkit.object_mapping:RKObjectMappingOperation.m:428 Starting mapping operation... 2011-10-12 12:36:48.145 MyProject[5119:207] T restkit.object_mapping:RKObjectMappingOperation.m:291 Did not find mappable attribute value keyPath 'time' 2011-10-12 12:36:48.145 MyProject[5119:207] T restkit.object_mapping:RKObjectMappingOperation.m:291 Did not find mappable attribute value keyPath 'someValue' 2011-10-12 12:36:48.145 MyProject[5119:207] T restkit.object_mapping:RKObjectMappingOperation.m:291 Did not find mappable attribute value keyPath 'lastChange' 2011-10-12 12:36:48.145 MyProject[5119:207] T restkit.object_mapping:RKObjectMappingOperation.m:291 Did not find mappable attribute value keyPath 'uuid' 2011-10-12 12:36:48.145 MyProject[5119:207] D restkit.object_mapping:RKObjectMappingOperation.m:448 Mapping operation did not find any mappable content 2011-10-12 12:36:48.146 MyProject[5119:207] T restkit.network:RKRequest.m:211 Prepared POST URLRequest '&lt;NSMutableURLRequest http://someurl/api/sync?request=provide_key&gt;'. HTTP Headers: { Accept = "application/json"; "Content-Length" = 0; }. HTTP Body: . </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload