JSON и Базовые Данные по iPhone

У меня есть базовый график объекта данных (состоящий из двух объектов, связанных к - многие отношения).

Мне было любопытно как относительно неопытный разработчик iPhone, мог ли кто-либо рекомендовать подход и подходящую реализацию JSON для iPhone, который позволит мне:

  1. преобразуйте базовые записи данных в строку JSON (при поддерживании отношений между объектами); и

  2. преобразуйте строку JSON назад в базовые объекты данных (снова сохраняющий отношения между объектами).

Я искал, неудачно, для учебного руководства/примера кода по этому вопросу, таким образом, любая помощь была бы с благодарностью получена.

93
задан pkamb 8 December 2017 в 22:12
поделиться

3 ответа

Во-первых, выберите для использования библиотеку JSON. Лично мне нравится TouchJSON, но есть и другие неплохие. Сложная часть, хотя и не очень сложная, заключается в преобразовании ваших управляемых объектов в подходящие структуры для преобразования. Я написал это очень быстро, поэтому в нем может быть одна или две ошибки :)

Вы вызываете следующие методы:

- (NSString*)jsonStructureFromManagedObjects:(NSArray*)managedObjects;
- (NSArray*)managedObjectsFromJSONStructure:(NSString*)json withManagedObjectContext:(NSManagedObjectContext*)moc;

И реализация выглядит следующим образом:

- (NSDictionary*)dataStructureFromManagedObject:(NSManagedObject*)managedObject
{
  NSDictionary *attributesByName = [[managedObject entity] attributesByName];
  NSDictionary *relationshipsByName = [[managedObject entity] relationshipsByName];
  NSMutableDictionary *valuesDictionary = [[managedObject dictionaryWithValuesForKeys:[attributesByName allKeys]] mutableCopy];
  [valuesDictionary setObject:[[managedObject entity] name] forKey:@"ManagedObjectName"];
  for (NSString *relationshipName in [relationshipsByName allKeys]) {
    NSRelationshipDescription *description = [[[managedObject entity] relationshipsByName] objectForKey:relationshipName];
    if (![description isToMany]) {
      NSManagedObject *relationshipObject = [managedObject valueForKey:relationshipName];
      [valuesDictionary setObject:[self dataStructureForManagedObject:relationshipObject] forKey:relationshipName];
      continue;
    }
    NSSet *relationshipObjects = [managedObject objectForKey:relationshipName];
    NSMutableArray *relationshipArray = [[NSMutableArray alloc] init];
    for (NSManagedObject *relationshipObject in relationshipObjects) {
      [relationshipArray addObject:[self dataStructureForManagedObject:relationshipObject]];
    }
    [valuesDictionary setObject:relationshipArray forKey:relationshipName];
  }
  return [valuesDictionary autorelease];
}

- (NSArray*)dataStructuresFromManagedObjects:(NSArray*)managedObjects
{
  NSMutableArray *dataArray = [[NSMutableArray alloc] init];
  for (NSManagedObject *managedObject in managedObjects) {
    [dataArray addObject:[self dataStructureForManagedObject:managedObject]];
  }
  return [dataArray autorelease];
}

- (NSString*)jsonStructureFromManagedObjects:(NSArray*)managedObjects
{
  NSArray *objectsArray = [self dataStructuresFromManagedObjects:managedObjects];
  NSString *jsonString = [[CJSONSerializer serializer] serializeArray:objectsArray];
  return jsonString;
}

- (NSManagedObject*)managedObjectFromStructure:(NSDictionary*)structureDictionary withManagedObjectContext:(NSManagedObjectContext*)moc
{
  NSString *objectName = [structureDictionary objectForKey:@"ManagedObjectName"];
  NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:objectName inManagedObjectContext:moc];
  [managedObject setValuesForKeysWithDictionary:structureDictionary];

  for (NSString *relationshipName in [[[managedObject entity] relationshipsByName] allKeys]) {
    NSRelationshipDescription *description = [relationshipsByName objectForKey:relationshipName];
    if (![description isToMany]) {
      NSDictionary *childStructureDictionary = [structureDictionary objectForKey:relationshipName];
      NSManagedObject *childObject = [self managedObjectFromStructure:childStructureDictionary withManagedObjectContext:moc];
      [managedObject setObject:childObject forKey:relationshipName];
      continue;
    }
    NSMutableSet *relationshipSet = [managedObject mutableSetForKey:relationshipName];
    NSArray *relationshipArray = [structureDictionary objectForKey:relationshipName];
    for (NSDictionary *childStructureDictionary in relationshipArray) {
      NSManagedObject *childObject = [self managedObjectFromStructure:childStructureDictionary withManagedObjectContext:moc];
      [relationshipSet addObject:childObject];
    }
  }
  return managedObject;
}

- (NSArray*)managedObjectsFromJSONStructure:(NSString*)json withManagedObjectContext:(NSManagedObjectContext*)moc
{
  NSError *error = nil;
  NSArray *structureArray = [[CJSONDeserializer deserializer] deserializeAsArray:json error:&error];
  NSAssert2(error == nil, @"Failed to deserialize\n%@\n%@", [error localizedDescription], json);
  NSMutableArray *objectArray = [[NSMutableArray alloc] init];
  for (NSDictionary *structureDictionary in structureArray) {
    [objectArray addObject:[self managedObjectFromStructure:structureDictionary withManagedObjectContext:moc]];
  }
  return [objectArray autorelease];
}

Теперь это рекурсивно, так что вы можете легко в конечном итоге перевести весь свой постоянный магазин, если вы не будете осторожны. Следите за своими отношениями и убедитесь, что они идут только «вниз» по дереву объектов, чтобы вы получали только те объекты, которые хотите перевести.

103
ответ дан 24 November 2019 в 06:19
поделиться

Синхронизация основных данных с Rails — это подробное представление, включающее пример кода для сериализации/десериализации объектов Core Data в JSON/из него (пропустите до слайда 55 для части Core Data). Его пример кода предполагает довольно простую модель без связей, хотя я думаю, что ее было бы довольно легко расширить.

В презентации также подробно рассказывается о синхронизации модели основных данных с веб-приложением на основе REST с указателями на некоторые полезные библиотеки, включая ObjectiveResource и ASIHTTPRequest. Не уверен, что это то, что вы пытаетесь сделать, но стоит посмотреть даже на код Core Data.

10
ответ дан 24 November 2019 в 06:19
поделиться

Я просто хотел указать на небольшую опечатку, которая привела к сбою кода, и, надеюсь, это сэкономит вам несколько минут.

- (NSArray*)dataStructuresFromManagedObjects:(NSArray*)managedObjects {

    NSMutableArray *dataArray = [[NSArray alloc] init];
    for (NSManagedObject *managedObject in managedObjects) {
        [dataArray addObject:[self dataStructureFromManagedObject:managedObject]];
    }
    return [dataArray autorelease];
}

NSMutableArray * dataArray = [[NSArray alloc] init]; // Это должно быть NSMutableArray

на самом деле должно быть NSMutableArray * dataArray = [[NSMutableArray alloc] init];

вот и все.

спасибо

12
ответ дан 24 November 2019 в 06:19
поделиться