2016-03-28 2 views
3

Я пытаюсь представить структуру JSON в swift для использования с EVReflection. Строка выглядит следующим образом:Как представить типы вложенных массивов для EVReflection

{ 
    "date": 2457389.3333330001, 
    "results": 
     { 
      "sun": [[559285.95145709824, 202871.33591198301, 61656.198554897906], [127.6163120820332, 948.44727756795123, 406.68471093096883]], 
      ... etc ... 
      "geomoon": [[-401458.60657087743, -43744.769596474769, -11058.709613333322], [8433.3114508170656, -78837.790870237863, -26279.67592282737]] 
     }, 
    "unit": "km" 
} 

Я попробовал несколько подходов для моделирования внутренних «результатов» словарь, который отпирается строками и всегда имеет значение, массив из двух элементов, каждый из которых имеет три удвоения (т. е. [String: [[Double]]] - это одна модель, которую я пробовал). Независимо от того, что я делаю, я получаю сообщение об ошибке по этим линиям:

ERROR: valueForAny unkown type , type _NativeDictionaryStorage<String, Array<Array<Double>>>. Could not happen unless there will be a new type in Swift.

Кто-нибудь есть идея, как эта модель так EVReflection счастлив? У меня также есть смысл от фразы Could not happen unless there will be a new type in Swift, что есть другой метод или другое моделирование с явными подтипами, которые я могу добавить, которые дадут ему то, что ему нужно, но я не могу понять, что делать с документами.

ответ

1

В Swift a double - это структура. Выполнение рефлексов с помощью структур имеет некоторые ограничения. Вместо этого я предпочитаю использовать NSNumber.

Моя первая мысль была бы объектная модель, как это:

class MyObject: EVObject { 
    var date: NSNumber? 
    var results: Result? 
    var unit: String? 
} 

class Result: EVObject { 
    var sun: [[NSNumber]]? 
    var geomoon: [[NSNumber]]? 
} 

Но ваш объект имеет вложенную значение. До сих пор я никогда не тестировал EVReflection со структурой вроде этого. Я попробую добавить единичный тест для этого в одно мгновение. Было бы проще, если внутренний массив был объектом

Update (что-то вроде объекта с х, у и г значения?): Это похоже на работу. Я проверил это с помощью следующего UnitTest:

func testNestedArry() { 
    let json = "{\"date\": 2457389.3333330001,\"results\": { \"sun\": [[559285.95145709824, 202871.33591198301, 61656.198554897906], [127.6163120820332, 948.44727756795123, 406.68471093096883]], \"geomoon\": [[-401458.60657087743, -43744.769596474769, -11058.709613333322], [8433.3114508170656, -78837.790870237863, -26279.67592282737]] }, \"unit\": \"km\" }" 
    let myObject = MyObject(json: json) 
    print(myObject.toJsonString()) 
} 

И выход был MyObject:

{ 
    "date" : 2457389.333333, 
    "results" : { 
    "sun" : [ 
     [ 
     559285.9514570982, 
     202871.335911983, 
     61656.19855489791 
     ], 
     [ 
     127.6163120820332, 
     948.4472775679512, 
     406.6847109309688 
     ] 
], 
    "geomoon" : [ 
     [ 
     -401458.6065708774, 
     -43744.76959647477, 
     -11058.70961333332 
     ], 
     [ 
     8433.311450817066, 
     -78837.79087023786, 
     -26279.67592282737 
     ] 
    ] 
    }, 
    "unit" : "km" 
} 

Обновление 2: Как обсуждается ниже «» клавиш планеты не фиксированный набор. Так что на самом деле это должно обрабатываться как словарь. Чтобы сделать что-то подобное, вы можете использовать «взломать», используя setValue forKey для заполнения словаря. Для делать это вам потребуется модель данных, как это:

class MyObject: EVObject { 
    var date: NSNumber? 
    var results: Result? 
    var unit: String? 
} 

class Result: EVObject { 
    var planets = [String: [[NSNumber]]]() 

    // This way we can solve that the JSON has arbitrary keys 
    internal override func setValue(value: AnyObject!, forUndefinedKey key: String) { 
     if let a = value as? [[NSNumber]] { 
      planets[key] = a 
      return 
     } 
     NSLog("---> setValue for key '\(key)' should be handled.") 
    } 
} 

Вы должны знать, что если вы хотите создать JSON для этого, что вы будете иметь дополнительный уровень в иерархии для планет. Если вы этого не хотите, тогда есть возможность обхода путем изменения свойства результатов в String: [[NSNumber]] Затем вам также понадобится реализовать EVCustomDictionaryConverter. См. Обходные тесты для проверки того, как это будет работать.

+0

К сожалению, точные ключи, которые будут возвращены в «результатах», являются переменными, поэтому я не могу построить вложенную структуру результатов, как вы предлагаете, - мне нужно, чтобы это был неопределенный набор из [string: [[value ]] словарных элементов. Моя единственная надежда перечислить их все как необязательные? – Feldur

+0

Я думаю, вы могли бы решить это с помощью трюка, который я здесь сделал: https://github.com/evermeer/EVWordPressAPI/blob/master/EVWordPressAPI/EVWordpressData.swift#L332 Используйте setValue forUndefinedKey, чтобы вы могли захватить все «свойства» без их реального свойства, а затем задают данные в локальном словаре. Я буду работать для вас позже ... –

+0

Перспективные. Затем я ожидаю, что вы скажете мне, что у вас есть все, что работает через детскую площадку, и я (кто не может заставить импорт работать) приветствует вас! – Feldur

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