Сведения: как разместить массив объектов?
вопрос резюме:
рассмотрим класс SyncObject
это KVC-совместимый со свойствами, такими как:time
, someValue
, lastChange
, uuid
.
рассмотрим NSArray
содержащие исключительно экземпляра SyncObject
.
мне нужно отправить массив на сервер в виде JSON-массива.
как отправить этот массив на сервер с помощью HTTP POST с помощью RestKit?
пример массив:
[
{
"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"
}
]
подробности
у меня есть массив объектов, которые мне нужны на сервере как JSON. Мне кажется, что сведения это самый простой способ сделать это: я пытаюсь избежать преобразования объектов в набор NSDictionary
объекты, а затем с помощью некоторого кодера JSON, чтобы получить JSON, который я могу POST
на сервер.
Итак, создав массив, и настройки отображения для класса объектов, хранящихся в массиве, я естественно попробуйте POST
на сервер.
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*/];
однако, это то, что я получаю:
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''
по-видимому, RestKit не знает, как обращаться NSArray
s.
как разместить массив объектов с помощью RestKit?
я пробовал что-то другое: Я заменил последнюю строку руководством send through RKObjectLoader
.
//[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];
к сожалению, это не относится к отображению любого рода, и вместо этого передает массив описаний объектов. Настройка serializationMIMEType
также не влияет на структуру передаваемого содержимого, и params
всегда передается как application/x-www-form-urlencoded
.
я также попытался назначить сопоставление сериализации и передать объект как targetObject
и sourceObject
(кажется, это то, что RestKit делает внутренне в -[RKObjectManager postObject:delegate:]
).
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];
к сожалению, отображение не происходит таким образом:
2011-10-12 12:36:48.143 MyProject[5119:207] D restkit.network:RKObjectLoader.m:290 POST or PUT request for source object {
MyData = (
"<NSManagedObject: 0x5935430> (entity: SomeRecord; id: 0x5934da0 <x-coredata://64DF9977-DA50-4FCD-8C20-4132E58439BF/SomeRecord/p1> ; data: <fault>)",
"<NSManagedObject: 0x5935730> (entity: SomeRecord; id: 0x5934db0 <x-coredata://64DF9977-DA50-4FCD-8C20-4132E58439BF/SomeRecord/p2> ; data: <fault>)"
);
}, 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 '<NSMutableURLRequest http://someurl/api/sync?request=provide_key>'. HTTP Headers: {
Accept = "application/json";
"Content-Length" = 0;
}. HTTP Body: .
2 ответов
restkit не финансирует маршрутизируемый путь для NSArray, потому что вы определили свой маршрут для NSManagedObject
класса. Вероятно, вы хотите создать пользовательский класс, скажем MySyncEntity
что держит Иварс вы указали в вашем сопоставлении. Затем вы создаете свое отображение следующим образом:
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[MySyncEntity class]];
....
[myManager setSerializationMIMEType:RKMIMETypeJSON];
[[myManager router] routeClass:[MySyncEntity class] toResourcePath:@"/sync"];
тогда вы должны иметь возможность опубликовать свой объект в бэкэнд API как объект JSON.
уточнения:
в этом случае, мы хотим разместить массив NSManagedObject
экземпляры в API на основе JSON. Для этого нам нужно создать объект синхронизации, который содержит объекты в массив:
@interface MySyncEntity : NSObject {}
@property (nonatomic, retain) NSArray* mySyncArray;
...
@end
на mySyncArray
будет содержать полезную нагрузку, которую мы хотели бы представить в остальной бэкэнд. Затем, мы создаем соответствующее отображение для обоих NSManagedObject
это будет отправлено в mySyncArray
и сущности.
RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:kBaseUrl];
...
RKObjectMapping *mngObjMapping = [RKObjectMapping mappingForClass:[NSManagedObject class]];
[mngObjMapping mapKeyPath: @"time" toAttribute:@"time"];
[mngObjMapping mapKeyPath: @"recordLevel" toAttribute:@"recordLevel"];
.... //map as many properties as you wish
[[manager mappingProvider] setSerializationMapping:[mngObjMapping inverseMapping]
forClass:[NSManagedObject class]];
//now, we create mapping for the MySyncEntity
RKObjectMapping *syncEntityMapping = [RKObjectMapping mappingForClass:[MySyncEntity class]];
[syncEntityMapping mapKeyPath:@"mySyncArray" toRelationship:@"mySyncArray" withMapping:mngObjMapping];
[[manager mappingProvider] setSerializationMapping:[syncEntityMapping inverseMapping]
forClass:[MySyncEntity class]];
теперь с определенными сопоставлениями мы можем опубликовать объект на сервере
[manager postObject:mySyncInstance delegate:nil];
содержание mySyncInstance
массив будет отображаться в соответствии с mngObjMapping
и отправлено в определенную конечную точку rest.
в качестве дальнейшего разъяснения я хотел бы отметить, что в ответ мья главное
[syncEntityMapping mapKeyPath:@"mySyncArray" toRelationship:@"mySyncArray" withMapping:mngObjMapping];
Это говорит:"mySyncArray
keypath-это массив, содержащий объекты, которые должны быть сопоставлены в соответствии с mngObjMapping
".