2016-02-16 2 views
1

Мне нужно сохранить некоторые данные, поступающие из вызова API, как JSON локально, используя CoreData.Как создать CoreData для хранения Сложные данные

Проблема в том, что JSON слишком сложна для обработки в CoreData. Я получаю JSON как Dictionary с 4 ключами, и эти 4 ключа снова удерживают Dictionary, а те Dictionary имеют Array и Dictionary.

Теперь я не знаю, как я должен проектировать объекты и атрибуты для этого требования, но я попытался это сделать, и что я сделал, я создал объект (например, XYZ), и этот объект имеет 4 отношения (один к одному) до 4 других объектов, и эти четыре объекта - это всего лишь четыре Dictionary, которые я получил в файле JSON. И я сохраняю эти Array и Dictionary как преобразуемые типы. Это немного запутывает, не так ли? Поэтому позвольте мне разместить данные JSON здесь

{ 
     outerKey1 =   { 
      someKey = “Some String"; 
      disableAutoFill = 1; 
      disableABC = 1; 
      disableXYZ = 1; 
      disableThis = 1; 
      disableThat = 1; 
      disableBla = 1; 
      disableBlaBla= 1; 
      disableBlaBlaBlaBla = 1; 
      disableBlaBlaBlaBlaBlaBla= 1; 
     }; 
     outerKey2 =   { 
      someKey =    (
           { 
        markPath = 0; 
        title = "Some Name"; 
        url = "http://www.BlaBla.com"; 
       }, 
           { 
        markPath = 0; 
        title = "Some Name"; 
        url = "http://www.something.com"; 
       }, 
           { 
        markPath = 0; 
        title = Yahoo; 
        url = "http://www.yahoo.com"; 
       }, 
           { 
        Path = 0; 
        title = “title"; 
        url = "http://www.title.com"; 
       } 
      ); 
      enabled = 1; 
     }; 
     outerKey3 =   { 
      enabled = 1; 
      gatewayIP = "192.172.169.10"; 
      gatewayPort = 8080; 
      gatewayRoutingUrls =    (
       "www.kuchbhi.com", 
       "www.oh-teri.com" 
      ); 
     }; 
     outerKey4 =   { 
      SomeCategories =    (
       SomeCategories, 
     someOtherCategories 
      ); 
      defaultUrl = "www.meriapniwebsite.com"; 
      enabled = 1; 
      exceptionUrls =    (
       "www.kuchbhihojay.com" 
      ); 
      filterUrls =    (
       "www.kuchtobhi.com", 
       "www.kyaaapjhandhai.com" 
      ); 
      filteringFlag = 1; 
     }; 
    } 

Подходит ли мой подход или его необходимо исправить? Или мне нужно реализовать его совершенно по-другому. Пожалуйста, помогите мне, спасибо

+0

мог смотреть в использовании [Realm] (https://realm.io) для вашей базы данных, очень проста в использовании – Fonix

+1

@Fonix, но это не решает вопрос о том, как моделировать данные –

+0

@TomHarrington, следовательно, это был не ответ – Fonix

ответ

5

Проблема в том, что вы пытаетесь создать свои объекты CoreData на основе структуры вашего JSON. Вы должны создавать свои объекты на основе объектов, которые представляет ваш JSON, и отношений между ними.

Ваш вопрос не дает достаточной информации о намерениях вашей модели данных, чтобы я дал вам точный ответ, но, скорее всего, сохранение этих данных в виде группы трансформируемых словарей - не лучший ответ. Использование трансформируемых свойств означает, что ни одно из этих значений не может быть запрошено, и у вас нет явного списка свойств, которые должны быть в этих словарях. Это означает, что вы будете иметь тонну if let операторов, проверяющих строковые буквы внутри ваших словарей всякий раз, когда вы получаете доступ к своим данным. Вместо этого каждое из этих значений должно отображаться в свойствах объектов CoreData.

Первое, что я хотел бы задать, это если эти outerKey словари представляют свойства и значения на моем базовом объекте или если каждый outerKey действительно представляет свой собственный объект модели с отношением к корневому объекту. Если они являются свойствами на одном объекте, просто прочитайте JSON и сопоставьте значения свойствам на вашем объекте. Если нет, то вы должны создавать несколько объектов и создавать такие отношения, как в настоящее время, но вы должны создавать свойства для каждого из значений этих объектов.

Для вложенных массивов и словарей, вероятно, вы хотите создать и другие объекты с отношениями.

Просто помните, что ваша модель CoreData должна отражать объекты и то, как они соотносятся друг с другом. Это не должно просто отражать структуру вашего JSON, если только ваш JSON также не представляет правильную структуру.

Пример

Потому что я не знаю, что ваши данные на самом деле представляет собой, это не может быть совершенной структуры для вашего приложения, но, сделав несколько предположений о том, что ваш JSON означает, что это сущности, которые я придумал бы.

- RootEntity 
    - outerKey1: OuterKey1 // one to one 
    - outerKey2: OuterKey2 // one to one 
    - outerKey3: OuterKey3 // one to one 
    - outerKey4: OuterKey4 // one to one 

- OuterKey1 
    - someKey: String 
    - disableAutoFill: Bool 
    - disableABC: Bool 
    - disableXYZ: Bool 
    - disableThis: Bool 
    - disableThat: Bool 
    - disableBla: Bool 
    - disableBlaBla: Bool 
    - disableBlaBlaBlaBla: Bool 
    - disableBlaBlaBlaBlaBlaBla: Bool 

- OuterKey2 
    - someKey: [SomeKeyEntity] // one to many 
    - enabled: Bool 

- SomeKeyEntity 
    - markPath: Bool 
    - title: String 
    - urlString: String 

- OuterKey3 
    - gatewayIP: String 
    - gatewayPort: Int 
    - gatewayRoutingURLs: [String] // This can be a transformable `Array`, unless you think you will need to query based on this property later 
    - enabled: Bool 

- OuterKey4 
    - someCategories: [SomeCategoriesEntity] // one to many 
    - defaultURL: String 
    - enabled: Bool 
    - exceptionURLs: [String] // This can be a transformable `Array`, unless you think you will need to query based on this property later 
    - filterURLs: [String] // This can be a transformable `Array`, unless you think you will need to query based on this property later 
    - filteringFlag: Bool 

Надеюсь, что это поможет!

+1

Позвольте мне рассказать вам одну хорошую вещь о требовании, я никогда не буду запрашивать что-либо в пределах модели, всякий раз, когда я получаю доступ к этим данным, мне нужны целые данные, а не часть, а во-вторых, этот JSON фактически отражает объект. Спасибо. – Suryakant

+2

, если вы только когда-либо используете его в блоке - тогда это один фрагмент данных, а не много. Вы могли бы просто сохранить его как блок текста JSON с 'someKey' как идентификатор – Russell

+0

Итак, я бы все еще использовал структуру объектов сверху, но я бы просто сделал все дочерние сущности трансформируемыми объектами, которые соответствуют' NSCoding' а не просто использовать обычные словари. – AnthonyM

0

Я действительно не знаю, что это поможет вам или нет, но для хранения таких сложных данных. Я предпочитаю экономить на основе XML, используя KISS XML API (он прост в использовании) и анализирует его, когда вам это нужно.

Ваш файл XML может выглядеть

<RootEntity>  
    <OuterKey1> 
      <someKey> String </someKey> 
      <disableAutoFill> Bool</disableAutoFill> //and so on 
    </OuterKey1> 
    <OuterKey2> 
      <someKey> String </someKey> 
      <disableAutoFill> Bool</disableAutoFill> //and so on 
    </OuterKey2> 
</RootEntity> 
+0

благодарит Асада, но мне нужно сделать это, используя только CoreData. Есть идеи? – Suryakant

+0

Почему вы не храните весь JSON в массиве и этот массив в данных ядра как Transformable, может быть, этот ответ поможет вам http://stackoverflow.com/a/25514277/4916161 –

1

Да вы не хотите, чтобы сделать это так, как вы делаете, совершенно не попадает в точку. Вы можете либо переварить все это, либо построить подходящую модель , либо просто сохранить JSON в файловой системе, а затем просто перезагрузить и получить нужные вам данные, когда вам это нужно. Есть множество основанного JSON анализаторов, которые позволят вам делать такие вещи, как:

BOOL autofillDisabled = [jsonFile boolFor:@"outerkey.disableAutoFill"]; 

Это было бы с помощью JSON непосредственно в качестве хранилища данных. Если вам действительно нужно построить объектную модель на основе этих данных, удачи.

Hah, j/k. Один из способов я решил эту точную проблему (хотя никогда с таким случайным образом не сформированным json. После того, как вы получите корень словаря, а также некоторое понимание данных и как вы хотите его использовать, постройте простую каскадную систему объекта, чтобы развернуть . данные

Например, начните здесь:

@interface ParseOperation : NSObject 
+ (void) updateObject:(id)object fromDictionary:(NSDictionary *)aDict; 
@end 

Затем перейдем к созданию мяса каждого из ваших объектов что-то вроде этого:

@implementation SomeOperation // Which is a subclass of ParseOperation 

+ (void) updateObject:(SomeObject *)object fromDictionary:(NSDictionary *)aDict 
{ 
    object.caption = [ParseObject stringForTag:@"caption" in:aDict]; 
    object.status = [ParseObject stringForTag:@"status" in:aDict]; 
    object.event = [ParseObject stringForTag:@"event" in:aDict]; 
} 

Тогда просто создать механизм драйвера :

identifier = [ParseOperation stringForTag:@"SomeObject" in:dict]; 
    SomeObject * object = (SomeObject *)[self object:NSStringFromClass([SomeObject class]) withIdentifier:identifier]; 
    object.identifier = identifier; 
    [SomeOperation updateObject:object fromDictionary:dict]; 

Полезность делать это таким образом, что вы можете легко обрабатывать сложность JSON, как и в этом случае:

id check = [aDict objectForKey:@"subArray"]; 
// This is a mapping file you create, replacing "subArray" with your object's key 
NSString * objectKey = [mapping objectForKey:@"object"]; 
if([check isKindOfClass:[NSMutableArray class]]) 
{ 
    NSArray * array = (NSArray *)check; 
    for(NSDictionary * dict in array) 
    { 
     NSString * identifier = [ParseOperation stringForTag:identifierKey in:dict]; 
     ManagedObject * object = [self object:objectKey withIdentifier:identifier]; 

     NSString * operation = [NSString stringWithFormat:@"%@Operation", objectKey]; 
     Class operationClass = NSClassFromString(operation); 
     [operationClass updateObject:object fromDictionary:dict]; 
    } 
} 
+0

Это также способ пойти и поверить я делаю это так же. – Suryakant

Смежные вопросы