JSON и основные данные на iPhone

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

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

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

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

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


person Urizen    schedule 02.03.2010    source источник
comment
Для всех, кто интересуется этим для iOS5, теперь есть NSJSONSerialization developer.apple.com/library/mac/#documentation/Foundation/ stackoverflow.com/questions/6726899/nsjsonserialization-in-ios5   -  person nicerobot    schedule 03.12.2011
comment
Я знаю, что этот вопрос немного устарел, но я создал простую библиотеку под названием OSReflectionKit, которая позволяет сериализовать / десериализовать объекты в / из JSON, используя NSJSONSerialization или NSDictionary. Он также поддерживает объекты Core Data.   -  person Alexandre OS    schedule 06.08.2013


Ответы (8)


Во-первых, выберите для использования библиотеку 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];
}

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

person Marcus S. Zarra    schedule 02.03.2010
comment
Еще раз спасибо за еще один отличный ответ и за вашу очень полезную книгу! :) - person Urizen; 03.03.2010
comment
Привет, Маркус. Я только что попробовал приведенный выше код (с некоторыми незначительными поправками, чтобы он скомпилировался, и выполнение, кажется, продолжается бесконечно, пока приложение не выйдет из строя). Извините, что беспокою вас, но мне было любопытно, можете ли вы указать мне правильное направление для решения этой проблемы. Кажется, это происходит с рекурсией в методе datastructureFromManagedObject ... - person Urizen; 04.05.2010
comment
Зависит от вашей структуры данных. Если ваша модель создаст цикл, он будет работать вечно. Просмотрите свою модель данных и убедитесь, что это древовидная структура, или поместите логические остановки в рекурсивный код, чтобы предотвратить зацикливание. - person Marcus S. Zarra; 04.05.2010
comment
Спасибо за ваш ответ. Я думаю, что мне удалось решить проблему бесконечной рекурсии, но код теперь выдает исключение, которое, кажется, предполагает, что атрибуты NSDate не могут быть сериализованы (т.е. завершение приложения из-за неперехваченного исключения 'NSGenericException', причина: 'Невозможно сериализовать данные типа '__NSCFDate') Так ли это? Если да, то есть ли способ обойти это? - person Urizen; 04.05.2010
comment
Я обошел вышеупомянутую проблему, сохранив значение, возвращаемое [date timeIntervalSince1970], как NSNumber. - person Urizen; 05.05.2010
comment
Что убирать? Если вы новичок в Core Data, вам следует усвоить основы KVC / KVO, прежде чем пытаться заняться рекурсивным кодом, подобным этому. В этом коде нет ничего грязного, это чистый пример. Его главный недостаток в том, что он не обрабатывает крайние случаи; что сделало бы код труднее для чтения. - person Marcus S. Zarra; 26.10.2010
comment
for (NSString *relationshipName in [relationshipsByName allKeys]) можно записать как for (NSString *relationshipName in relationshipsByName) - person user102008; 19.01.2011
comment
Я пытаюсь следовать этому примеру, чтобы преобразовать ответ JSON в объекты основных данных, но я застрял с ошибкой: - [__ NSCFDictionary entity]: неопознанный селектор, отправленный экземпляру в методе setValuesForKeysWithDictionary. Может ли кто-нибудь указать мне, что я делаю не так? - person Vibhor Goyal; 03.01.2012
comment
@VibhorGoyal Установите точку останова в описанных выше методах и пройдитесь по коду по одной точке данных за раз и посмотрите, в чем проблема. Возможно, что-то не совпадает между JSON и вашей моделью, или вы конвертируете строку в число или число на сегодняшний день или что-то в этом роде. - person Marcus S. Zarra; 03.01.2012
comment
Спасибо за ваш ответ, Маркус, я установил точку останова, и, как уже говорилось ранее, она вылетает на setValuesForKeysWithDictionary. - person Vibhor Goyal; 03.01.2012
comment
Я дважды проверил, что все имена в моей модели точно такие же, как JSON, а также я не выполняю каких-либо странных преобразований. - person Vibhor Goyal; 03.01.2012
comment
@VibhorGoyal Что такое ключ и какова ценность? Соответствуют ли они ожиданиям вашей модели? Каков тип атрибута в вашей модели для ключа, на котором происходит сбой? - person Marcus S. Zarra; 03.01.2012
comment
Есть несколько ключей и значений, я не могу отладить, на каком ключе происходит сбой, есть ли способ узнать, на каком ключе происходит сбой? - person Vibhor Goyal; 03.01.2012
comment
@VibhorGoyal да, измените -setValuesForKeysWithDictionary: на цикл, который перебирает ключи в словаре и вызывает -setValue: forKey: для каждого ключа. Это позволит вам увидеть, в каком ключе проблема. - person Marcus S. Zarra; 03.01.2012
comment
Если я использую -setValue: forKey:, это не вызывает никаких ошибок. Я предполагаю, что он потерпел неудачу из-за отношений. Есть ли какой-нибудь рабочий пример кода, которому я могу следовать? - person Vibhor Goyal; 04.01.2012
comment
позвольте нам продолжить это обсуждение в чате - person Marcus S. Zarra; 04.01.2012
comment
Я получаю сообщение об ошибке ожидаемого выражения в строке [valuesDictionary setValue:[self dataStructureForManagedObject:]]; - я пытаюсь понять, что это должно быть, есть какие-то подсказки? Извините, если я толстый :( - person jowie; 26.06.2012
comment
Вы действительно пробовали запустить этот код? Так много ошибок. dataStructureForManagedObject даже не существует. Я подумал, что это может быть опечатка, но если вы измените его на dataStructureFromManagedObject, все это просто зациклится, бесконечно возвращаясь назад между парами отношений. Мне здесь не хватает дополнительного кода? - person Chris Mitchelmore; 09.11.2012
comment
Этот пример кода был написан в браузере два года назад. Он был призван вдохновлять, а не копировать и вставлять. Что касается бесконечного цикла, это означает, что у вас есть цикл в вашей модели, и вам нужно будет добавить логику конкретной модели в свое приложение, чтобы разорвать цикл. Есть несколько способов сделать это, которых нет в этом примере. - person Marcus S. Zarra; 09.11.2012
comment
Любое элегантное решение, позволяющее избежать исключения, возникающего, когда некоторые из атрибутов имеют тип Date? - person Jean-Denis Muys; 12.07.2013
comment
Некоторые, вы можете использовать переопределение KVC, чтобы принять строку и преобразовать дату, вы можете поймать ее в установленной логике и посмотреть на атрибут на стороне Core Data, чтобы попытаться проанализировать, я уверен, что есть много других способов, как хорошо. - person Marcus S. Zarra; 12.07.2013

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

- (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]; // This should be NSMutableArray

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

это все.

Спасибо

person creativeKoder    schedule 19.07.2010

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

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

person Christopher Pickslay    schedule 07.07.2010

Если у вас есть NSDate в вашем управляемом объекте, как упоминалось выше в одном из комментариев, у вас возникнут проблемы с сериализацией объекта, содержащего NSDate. Простое исправление - добавить метод JSONDataRepresentation в NSDate с использованием категорий objective-c.

Добавьте эти два файла в свой проект:

NSdate.h:

#import <Foundation/Foundation.h>

@interface NSDate (jsondatarepresentation) 

- (NSData*) JSONDataRepresentation;

@end

NSDate.m:

#import "NSDate.h"

@implementation NSDate (jsondatarepresentation)

- (NSData*) JSONDataRepresentation {
    return [[[NSNumber numberWithDouble:[self timeIntervalSince1970]] stringValue] dataUsingEncoding:NSUTF8StringEncoding];
}

@end
person joshaidan    schedule 11.03.2011

Просто подумал, что id опубликует быстрое обновление этого вопроса. Я следил за ответами Маркуса и Брэндона и придумал это для экспорта JSON (он все еще использует TouchJSON):

- (NSData*)jsonStructureFromManagedObjects:(NSArray*)managedObjects
{
    NSArray *objectsArray = [self dataStructuresFromManagedObjects:managedObjects];
    NSData *jsonData      = [[CJSONSerializer serializer] serializeArray:objectsArray error:nil];
    return jsonData;
}

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

- (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 userInfo] objectForKey:@"isExportable"] boolValue] == YES) {

            if (![description isToMany]) {
                NSManagedObject *relationshipObject = [managedObject valueForKey:relationshipName];
                if (relationshipObject) {
                    [valuesDictionary setObject:[self dataStructureFromManagedObject:relationshipObject] forKey:relationshipName];
                }

                continue;
            }

            NSSet *relationshipObjects        = [managedObject valueForKey:relationshipName];
            NSMutableArray *relationshipArray = [[NSMutableArray alloc] init];

            for (NSManagedObject *relationshipObject in relationshipObjects) {
                [relationshipArray addObject:[self dataStructureFromManagedObject:relationshipObject]];
            }

            [valuesDictionary setObject:relationshipArray forKey:relationshipName];

        }

    }
    return valuesDictionary;
}

Мне не удалось заставить импорт работать, возможно, это как-то связано с тем, что я использую Magical Record, я не уверен, поэтому я просто перебираю входящий поток JSON и создаю объекты вручную ...

person Carl Taylor    schedule 14.06.2014

Существует библиотека, которая выполняет синхронизацию JSON за вас: https://github.com/sixdegrees/lidenbrock

person François Téchené    schedule 17.05.2011
comment
По состоянию на 30 июля 2012 г. проекта больше нет по этой ссылке. - person Nick; 31.07.2012

Я наткнулся на этот пост, который работает очень хорошо.

http://touchalicious.com/blog/2009/10/25/turn-core-data-models-into-json.html

Поскольку это рекурсивно, отношения «многие ко многим» будут продолжать зацикливаться. Чтобы избежать этого, я добавил ключ isExportable в пользовательский информационный словарь отношений в моей модели Core Data. Затем вы можете проверить наличие этого ключа и отказаться от цикла отношений без него.

введите описание изображения здесь

if ([property isKindOfClass:[NSRelationshipDescription class]])
    {
        NSRelationshipDescription *relationshipDescription = (NSRelationshipDescription *)property;

        if ([[[relationshipDescription userInfo] objectForKey:@"isExportable"] boolValue] == YES)
        {
            NSString *name = [relationshipDescription name];

            if ([relationshipDescription isToMany])
            {
                NSMutableArray *arr = [properties valueForKey:name];
                if (!arr)
                {
                    arr = [[NSMutableArray alloc] init];
                    [properties setValue:arr forKey:name];
                }

                for (NSManagedObject *o in [self mutableSetValueForKey:name])
                {
                    [arr addObject:[o propertiesDictionary]];
                }
            }
            else
            {
                NSManagedObject *o = [self valueForKey:name];
                [properties setValue:[o propertiesDictionary] forKey:name];
            }
        }
    }
}
person Brandon Schlenker    schedule 25.11.2012

Маркус С. Зарра вдохновил меня довести рекурсивную идею до рабочей версии. В этой версии вам не нужно устанавливать ключ в CoreData, и вы можете вырезать и вставить его в свой проект :-)

// MARK: - encoding and decoding CoreData entity to dictionary

func dataStructureFromManagedObject( managedObject:NSManagedObject?, parentEntity: NSEntityDescription? = nil) -> NSMutableDictionary {
    if (managedObject != nil) {
        var attributesByName: NSDictionary = managedObject!.entity.attributesByName
        var relationshipsByName: NSDictionary  = managedObject!.entity.relationshipsByName
        var valuesImmutableDictionary: NSDictionary = managedObject!.dictionaryWithValuesForKeys( attributesByName.allKeys)
        var valuesDictionary: NSMutableDictionary = valuesImmutableDictionary.mutableCopy() as NSMutableDictionary
        valuesDictionary.setObject( managedObject!.entity.name!, forKey: "ManagedObjectName")
        for relationshipNameObject in relationshipsByName.allKeys {
            var relationshipName: NSString = relationshipNameObject as  NSString
            var relationshipDescription: NSRelationshipDescription? = relationshipsByName.objectForKey( relationshipName) as? NSRelationshipDescription
            if !relationshipDescription!.toMany {
                // ono to one
                if parentEntity == nil || (relationshipDescription! as NSRelationshipDescription).destinationEntity != parentEntity! {
                    // no parent or relationship is "downward" -> object for relationship must be added
                    var relationshipObject: NSManagedObject? = managedObject!.valueForKey( relationshipName) as? NSManagedObject
                    var relationshipObjectDictionary: NSMutableDictionary = self.dataStructureFromManagedObject( relationshipObject, parentEntity: managedObject?.entity)
                    valuesDictionary.setObject( relationshipObjectDictionary, forKey: relationshipName)
                } else {
                    // relationship is "upward" -> nothing to do
                }
            } else {
                // one to many -> all objects must be added
                var relationshipObjects: NSSet = managedObject!.mutableSetValueForKey( relationshipName)
                var relationshipArray:NSMutableArray = []
                for relationshipObjectRaw in relationshipObjects {
                    var relationshipObject:NSManagedObject? = relationshipObjectRaw as? NSManagedObject
                    if relationshipObject != nil && !relationshipObject!.entity.isKindOfEntity( managedObject!.entity) {
                        relationshipArray.addObject(self.dataStructureFromManagedObject( relationshipObject, parentEntity: managedObject?.entity))
                    }
                }
                valuesDictionary.setObject( relationshipArray, forKey: relationshipName)
            }
        }
        return valuesDictionary
    } else {
        return NSMutableDictionary()
    }
}

func managedObjectFromStructure( structureDictionary: NSDictionary, moc: NSManagedObjectContext, parentObject: NSManagedObject? = nil) -> NSManagedObject {
    if structureDictionary.count > 0 {
        var objectName:NSString = structureDictionary.objectForKey( "ManagedObjectName") as NSString
        var managedObject:NSManagedObject = NSEntityDescription.insertNewObjectForEntityForName( objectName, inManagedObjectContext: moc) as NSManagedObject
        var relationshipsByName: NSDictionary  = managedObject.entity.relationshipsByName
        var realObjectStructure:NSMutableDictionary = structureDictionary.mutableCopy() as NSMutableDictionary
        realObjectStructure.removeObjectForKey( "ManagedObjectName")
        for key in realObjectStructure.allKeys {
            // search for "ManagedObjectName" relationship entrys and delete them before filling the managedObject from this structure
            for relationshipName in relationshipsByName.allKeys {
                if relationshipName as NSString == key as NSString {
                    realObjectStructure.removeObjectForKey( key)
                }
            }
        }
        managedObject.setValuesForKeysWithDictionary( realObjectStructure)
        // the main object with attributes is created. Now care about the relationships
        for relationshipName in managedObject.entity.relationshipsByName.keys {
            var description:NSRelationshipDescription = relationshipsByName.objectForKey( relationshipName) as NSRelationshipDescription
            if !description.toMany {
                // to one relationship
                if parentObject == nil || description.destinationEntity != parentObject!.entity {
                    // no parent or relationship is "downward" -> recurse structure to add
                    var childStructureDictionary:NSDictionary = structureDictionary.objectForKey( relationshipName) as NSDictionary
                    if childStructureDictionary.count > 0 {
                        // dictionary not empty -> object must be created and added
                        var childObject:NSManagedObject? = self.managedObjectFromStructure( childStructureDictionary, moc: moc, parentObject: managedObject)
                        // validateForUpdate
                        var error:NSError?
                        if !managedObject.validateForUpdate( &error) {
                            println("Error: Object not in valid state for update!!! -> \(error)")
                        } else {
                            managedObject.setValue( childObject, forKey: relationshipName as NSString)
                        }
                    } else {
                        // relationship is "upward" -> nothing to do
                    }
                }
            } else {
                // to many relationship
                var relationshipSet:NSMutableSet = managedObject.mutableSetValueForKey( relationshipName as NSString)
                var relationshipArray:NSArray = structureDictionary.objectForKey( relationshipName as NSString) as NSArray
                for childStructureDictionary in relationshipArray {
                    if childStructureDictionary.count > 0 {
                        // dictionary not empty -> object must be created and added
                        var childObject:NSManagedObject = self.managedObjectFromStructure( childStructureDictionary as NSDictionary, moc: moc, parentObject: managedObject)
                        // validateForUpdate
                        var error:NSError?
                        if !managedObject.validateForUpdate( &error) {
                            println( "Error: Object not in valid state for update!!! -> \(error)")
                        } else {
                            relationshipSet.addObject( childObject)
                        }
                    } else {
                        // no object was behind the relationship -> nothing to do
                    }
                }
                // save set
                managedObject.setValue( relationshipSet, forKey: relationshipName as NSString)
            }
        }
        // final check validateForUpdate
        var error:NSError?
        if !managedObject.validateForUpdate( &error) {
            println( "Error: Object not in valid state for update although all previous check are passed!!! -> \(error)")
        }
        return managedObject
    } else {
        println( "Error: structure for object was empty. this should not happen at this point")
        var objectName:NSString = structureDictionary.objectForKey( "ManagedObjectName") as NSString
        var managedObject:NSManagedObject = NSEntityDescription.insertNewObjectForEntityForName( objectName, inManagedObjectContext: moc) as NSManagedObject
        return managedObject
    }
}

func dataStructuresFromManagedObjects( managedObjects: NSArray) -> NSArray {
    var dataArray:NSMutableArray = []
    for managedObject in managedObjects {
        dataArray.addObject( self.dataStructureFromManagedObject(managedObject as? NSManagedObject))
    }
    return dataArray
}

Ключевым моментом здесь является передача родительской сущности в качестве аргумента рекурсии, чтобы мы могли решить, какие отношения мы должны заполнить данными. Таким образом, обе функции: dataStructureFromManagedObject и managedObjectFromStructure могут кодировать и декодировать любой объект сущности из CoreData в словарь и обратно в объект.

person MPajak    schedule 10.04.2015