2017-03-16 7 views
-3

Swift 3のiOSアプリケーションで作業していて、サーバーを呼び出してjsonを取得してシリアル化しています。Swift 3でJSONを解析する際のエラー

私はそれを解析しようとすると、私はこのエラーを取得:

"Could not cast value of type '__NSArrayI' (0x1a779acc8) to 'NSDictionary' (0x1a779b128). 2017-03-16 09:53:00.710776 AutoBuddy[3164:706970] Could not cast value of type '__NSArrayI' (0x1a779acc8) to 'NSDictionary' (0x1a779b128)."

私はこの質問のカップルの他のバージョンを見てきましたが、私はまだ混乱しています。 JSONはキー値のペア[String:Any]を持つ辞書として戻ってきます。

私は辞書を取得しているように見えるので、 "as?Dictionary < String、Any>という呼び出し結果を明示的にキャストしようとしましたが、動作しません現在、私のparseJSON関数の最初の行でプログラムがクラッシュしています。私は、以前と同様の解析メソッドを使用していたため、どのようにjsonを戻しているのか、それは常に働いていたか、それは構文解析の問題であれば、誰かが私はコードとそれがシリアライズというJSONの例を掲載します私にこれを解析する適切な方法を説明できる

JSON:。?。

["id": 745, "year": 1995, "styles": <__NSArrayI 0x170e68f00>(
{ 
    id = 7654; 
    name = "2dr Coupe"; 
    submodel =  { 
     body = Coupe; 
     modelName = "Mustang Coupe"; 
     niceName = coupe; 
    }; 
    trim = Base; 
}, 
{ 
    id = 7653; 
    name = "2dr Convertible"; 
    submodel =  { 
     body = Convertible; 
     modelName = "Mustang Convertible"; 
     niceName = convertible; 
    }; 
    trim = Base; 
}, 
{ 
    id = 7648; 
    name = "GT 2dr Coupe"; 
    submodel =  { 
     body = Coupe; 
     modelName = "Mustang Coupe"; 
     niceName = coupe; 
    }; 
    trim = GT; 
}, 
{ 
    id = 7647; 
    name = "GT 2dr Convertible"; 
    submodel =  { 
     body = Convertible; 
     modelName = "Mustang Convertible"; 
     niceName = convertible; 
    }; 
    trim = GT; 
}, 
{ 
    id = 7650; 
    name = "GTS 2dr Coupe"; 
    submodel =  { 
     body = Coupe; 
     modelName = "Mustang Coupe"; 
     niceName = coupe; 
    }; 
    trim = GTS; 
} 
) 
] 

スウィフトコード:

func getJSONData(path: String) 
{ 
let config = URLSessionConfiguration.default 
    let session = URLSession(configuration: config) 
    let url = URL(string: path + "API key")! 

    let task = session.dataTask(with: url, completionHandler: 
     { 
      (data, response, error) in 
      if error != nil 
      { 
       print(error!.localizedDescription) 
      } 
      else 
      { 
       do { 
        if let resultJSON = try JSONSerialization.jsonObject(with: data!) as? [String: Any] 
        { 
         print(resultJSON) 
         self.parseJSON(json: resultJSON) 
        } 
       } 
       catch 
       { 
        print("\(error)") 
       } 
      } 
    }) 
    task.resume() 
} 
func parseJSON(json: [String: Any]) 
{ 
    let styles = json["styles"] as! [String:Any] // Crashes Here 
    print(styles) 
    let names = styles["name"] as! String 
    print(names) 
} 
+0

より理にかなっている[スウィフト3で正しく解析JSON](http://stackoverflow.com/questions/39423367/correctly-parsing-json-in-swift-3) – JAL

答えて

0

私は最終的にこの問題を解決しました。

func getJSONData(path: String) 
{ 
    let config = URLSessionConfiguration.default // Session Configuration 
    let session = URLSession(configuration: config) // Load configuration into Session 
    let url = URL(string: path + API_Key)! 

    let task = session.dataTask(with: url, completionHandler: 
     { 
      (data, response, error) in 
      if error != nil 
      { 
       print(error!.localizedDescription) 
      } 
      else 
      { 
       do { 
        let resultJSON = try JSONSerialization.jsonObject(with: data!) as! [String: Any] 
        let styles = resultJSON["styles"] as! NSArray 
        for i in 0..<styles.count 
        { 
         let name = styles[i] as! Dictionary<String, Any> 
         self.trims.append(name["name"] as! String) 
        } 
        DispatchQueue.main.async() { 
         self.tableView.reloadData() 
         self.tableView.isHidden = false 
         return 
        } 
       } 
       catch 
       { 
        print("Error: \(error)") 
       } 
      } 
    }) 
    task.resume() 
} 
3

、それは非常に簡単です、JSONをよくお読みください。

  • []はスウィフト[[String:Any]]の配列、または時々[Any]
  • {}がで、辞書を表しSwift [String:Any]

stylesの値が明確に配列です(でもクリアテキストで示されている:"スタイル":< __NSArrayI 0x170e68f00>

let styles = json["styles"] as! [[String:Any]] 

、あなたが取得するために、繰り返しループを必要とします名前

for style in styles { 
    let name = style["name"] as! String 
    print(name) 
} 

またはあなたが使用できるflatMap

let names = styles.flatMap { $0["name"] as? String } 
print(names) 

PS:あなたが

if let resultJSON = try JSONSerialization.jsonObject(with: data!) as? [[String: Any]] 

をキャストする必要があります。そして、あなたはまた、

func parseJSON(json: [[String: Any]]) { 
    let styles = json[0]["styles"] as! [[String:Any]] 

を変更する必要がある場合はJSONのルートオブジェクトは、配列であることもそうです

回避するには角かっこの混乱タイプエイリアスを使用することをお勧めします:

typealias JSONDictionary = [String:Any] 

辞書はJSONDictionary、辞書の配列は[JSONDictionary]、区別が容易です。

+0

ああの可能性のある重複。私は物事の二重ブレースの部分に混乱していた。私は変更を行い、行に "let styles = json [" styles "]![[String:Any]]"というエラーを表示します "[[String:Any]] ' 'String'型のインデックスを持つ これは、これがキー/値のペアの配列である場合、1次元の「スタイル」を渡しているからです。このエラーを修正する方法はありますか? – Jordan

+0

私は答えを更新しました – vadian

+0

これを編集するのは無礼ですが、それは '[Any]'ではないはずですか? – Desdenova