2016-03-28 20 views
3

EVReflection ile kullanım için hızlı bir JSON yapısını temsil etmeye çalışıyorum. dize şöyle görünür:EVReflection için iç içe dizi türleri nasıl temsil edilir

{ 
    "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" 
} 

Ben iç "sonuçlar" bir dize ile anahtarlı ve her zaman var, her biri iki elemanlı bir dizi olan değerleri, vardır sözlük, modellemek için çeşitli yaklaşımlar denedim üç çift (yani, denedim bir model [String: [[Double]]]). Hayır yaparsam yapayım, ben bu satırlar boyunca bir hata alıyorum:

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

herkes nasıl bu kadar EVReflection mutlu modellemek için bir fikir var mı? Could not happen unless there will be a new type in Swift deyiminden başka bir yöntem veya farklı altyazılar içeren farklı altyazılar olduğunu anladım. Bu, gereksinim duyduğum şeyi ekleyebildi, ancak dokümanlardan ne yapacağımı bilmiyorum.

cevap

1

Swift'de bir Double bir yapıdır. Yapılar ile yansımalar yapmak bazı sınırlamalara sahiptir. Bunun yerine NSNumber kullanmayı tercih ederim.

ilk düşüncem böyle bir nesne modeli olacaktır:

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

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

Ama nesne iç içe geçmiş bir değere sahiptir. Şimdiye kadar EVReflection'ı böyle bir yapıyla test etmedim. Bir an için bir birim testi eklemeyi deneyeceğim. İç dizi bir nesne olsaydı çok kolay olurdu

Güncelleme (bir x, y ve z değerine sahip bir nesne gibi bir şey?): Bu iş gibi görünüyor.

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()) 
} 

Ve myObject çıkışı oldu: Ben şu UnitTest ile bu test

{ 
    "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" 
} 

Güncelleme 2: gezegen 'tuşları' Aşağıda açıklandığı gibi sabit bir noktası değildir. Yani aslında bu bir sözlük olarak ele alınmalıdır. Böyle bir şey yapmak için, bir sözlüğü doldurmak için setValue forKey özelliğini kullanarak bir "hack" kullanabilirsiniz. Sen farkında olmak zorunda

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.") 
    } 
} 

o size gezegenler için hiyerarşinizdeki fazladan seviyesine sahip olacağı, bunun için json oluşturmak istiyorsanız: Bunu yaparken için böyle bir veri modelini gerekir. Bunu istemezseniz, sonuç özelliğini String olarak değiştirerek bir geçici çözüm vardır: [[NSNumber]] Daha sonra EVCustomDictionaryConverter uygulamasını da uygulamanız gerekir. Bunun nasıl işe yaradığını görmek için geçici çözüm testlerine bakınız.

+0

Maalesef, 'sonuçlarda' döndürülen kesin anahtarlar değişkendir ve önerdiğiniz gibi iç içe geçmiş sonuç yapıları oluşturamıyorum - Belirsiz bir [string: [[value] değerine sahip olmasına ihtiyacım var ]] sözlük elemanları. Hepsini isteğe bağlı olarak listelemem için tek umudum mu? – Feldur

+0

Sanırım bunu burada yaptığım hile ile çözebilirsiniz: https://github.com/evermeer/EVWordPressAPI/blob/master/EVWordPressAPI/EVWordpressData.swift#L332 Yakalamak mümkün olacak şekilde setValue forUndefinedKey kullanın tüm 'mülkler' onlar olmadan gerçek bir mülktür ve sonra verileri yerel bir sözlükte ayarlar. Senin için sonra çalışacağım ... –

+0

Promising. Bundan sonra, bir oyun parkı ile çalıştığınız herşeyin olduğunu söyleyeceğim ve ben (ithalatı yapamayan) sizi selamlayacak! – Feldur