2017-12-19 24 views
0

の第一層を無視:解析JSON私はこのようなJSONを持ってコード可能な使用とJSON

{ 
"success": true, 
"message": "", 
"result": { 
    "buy": [ 
     { 
      "Quantity": 0.0056, 
      "Rate": 18527 
     }, 
     { 
      "Quantity": 0.11431426, 
      "Rate": 18526 
     } 
    ], 
    "sell":[ 
     { 
      "Quantity": 8.20604116, 
      "Rate": 18540 
     }, 
     { 
      "Quantity": 0.95600491, 
      "Rate": 18574.99999998 
     } 
    ] 
    } 
} 

と、このようなJSONの別のセット:

{ 
     "lastUpdateId": 1027024, 
     "bids": [ 
     [ 
      "4.00000000",  // PRICE 
      "431.00000000", // QTY 
      []    // Can be ignored 
     ] 
     ], 
     "asks": [ 
     [ 
      "4.00000200", 
      "12.00000000", 
      [] 
     ] 
     ] 
    } 

これら二つを解析するための最良の方法は何ですかコード可能なものを使った応答。それらは、同じ構造体を使用して解析する必要があるか、同じ構造体に変換する必要があります。 "success""message"のようなキーを使用しないので、最初のレスポンス全体の構造体を作成したくありません。私は基本的にそれらを無視して直接"result"キーに行きたいですが、2番目の応答では、私はTotalOrderBookと呼ばれる構造体を作成したので、私はすべてのデータを使用しています。これを行う最善の方法は何ですか?

最初のJSONレスポンスでキーと"message"を無視し、キー"result"の値にまっすぐになってしまいました。追加の構造体を作成せずにこれを行うことは可能ですか?

これは私が今持っているものです。私は本当に必要なのは、バイ/ビッドと売り/売りの下の値なので、別の構造体を追加することは避けたい。

let decoder = JSONDecoder() 
let data = try! JSONSerialization.data(withJSONObject: value) //value is the response from Alamofire 

var theWholeOrderBook:UniversalOrder! 
do { 
    theWholeOrderBook = try decoder.decode(UniversalOrder.self, from: data) 
} catch let error { 
    //print ("error is \(e) ** \(value)") 

} 
+0

スウィフトはタイプ推論言語の 'return bid ??買う? [] 'と' catch let error'は重複して 'catch ' –

答えて

0

が直接あなたの質問に答えるために、はい、successmessageキーと値のペアを無視してresultsにまっすぐに向かうことは非常に簡単です:

struct TotalOrderBook:Codable{ 
    var buy:[UniversalOrder]? 
    var sell:[UniversalOrder]? 

    var bid:[UniversalOrder]? 
    var ask:[UniversalOrder]? 

    var buyOrderBook: [UniversalOrder] { 
     return bid ?? buy ?? [UniversalOrder]() 
    } 
    var sellOrderBook: [UniversalOrder] { 
     return ask ?? sell ?? [UniversalOrder]() 
    } 

    var updatedTime:Date 
} 


struct UniversalOrder:Codable{ 
    var price : Double { 
     return Double(rate ?? binPrice ?? 0) 
    } 

    var size : Double { 
     return Double(quantity ?? binQuantity ?? 0) 
    } 
    //let numOrders : Int 

    var quantity:Double? 
    var rate:Double? 

    var binPrice:Double? 
    var binQuantity:Double? 

    private enum CodingKeys: String, CodingKey { 
     case rate = "Rate" 
     case quantity = "Quantity" 
     //case numOrders, binPrice, 
    } 

    init(from decoder: Decoder) throws { 
     var container = try decoder.unkeyedContainer() 
     binPrice = Double(try container.decode(String.self)) ?? nil 
     binQuantity = Double(try container.decode(String.self)) ?? nil 
     quantity = nil 
     rate = nil 
    } 
} 

これは私が解読しています方法です。

これにもかかわらず、これらのJSON応答の両方を解析する単一の構造体を持つことは少し複雑になります。 どちらも構造が非常に異なるため、2つの異なる構造体を使用してエンコードを使用する方が簡単です。

  1. buysellresultsの中にネストされています。いくつかの違いを強調するために。 bidsasksはありません。
  2. キーは全く異なります。
  3. buy,sellにはキーと値のペアの配列があり、bids,asksには値の配列があります。

コーディング可能な構造体はシンプルで明瞭でなければなりません。それぞれの対応に対応する2つを持つ方がよいでしょう。

+0

が完璧です。私はそれらの2つを取得すると、私はそれらを1つに変換する必要がありますか?成功とメッセージのKey-Valueペアを無視するにはどうすればよいですか? –

+0

私はそれらをエンコードするために異なる構造体を持つことをお勧めします。キーを "無視"する必要はありません。単にあなたが望むキーを解析し、残りのことを気にしないでください。 – NSAdi

+0

しかし、私は 'result'値だけの構造体を持つことは望ましくありません。それほど無意味ではない? 'result'キーの値にまっすぐに入る方法はありません –