2017-01-12 12 views
-1

私はInstagram APIからJSON応答を解析しています。最上位のオブジェクトにはメタデータがいくつか含まれており、興味のあるエントリは「データ」という配列オブジェクトに含まれています。Swift 3のJSONを解析するAppleのSwift 2の例のように

Appleの投稿hereは、Swift 2を使用し、Swift 3がリリースされる前の日に公開されました(私は信じています)。このポストは非常に役に立ち、私が辞書として興味を持っているアイテムを手に入れるために使っているのと同じパターンを持っています。 JSONも非常に似ています。

let session = URLSession.shared 
let task = session.dataTask(with: mediaURL(), completionHandler: { (data, response, error) in 
    if let data = data, 
     let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { 
     for case let items in json["data"] { 
      // parse each item 
     } 
    } 

コンパイラはエラー「タイプスロー:ここ

はコードである '[文字列:任意]を?'行にはfor case let items in json["data"] {の下付き文字のメンバーはありません。 if letチェーンの変数jsonには、タイプ[String: Any]?が与えられます。これを避けて、バインディングを構造化して、json変数に辞書[String: Any]を入力することができますか?

JSONを解析する方法についてはお尋ねしていません。という事は承知しています。 Appleのポストは、この記事で私は、コードを更新する方法を理解したいと思い、私が使用したい正確なパターンであるスウィフト3に

UPDATE:以下のコメントからの入力に

おかげで、I私が使っていたタイプを詳しく調べました。私はフレームワークを使用することができ

let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], 
let items = json["data"] as? [[String: Any]] { 
    for item in items { 
     if let mediaType = item["type"] as? String, 
      let mediaID = item["id"] as? String, 
      let images = item["images"] as? [String: Any], 
      let standardImg = images["standard_resolution"] as? [String: Any], 
      let standardImgURL = standardImg["url"] as? String { 
      // Create instances with JSON data… 

が、これは私が解析について少し詳細を学ぶ助けになるJSONを返しました:私のJSONは、辞書の配列の辞書の配列がたくさんあったので、私はそれを解析するために、このコードを使用しましたシンプルなフラット値だけでなく、重く入れ子になっています。 (try?で)今

let json: [String: Any] = try? JSONSerialization.jsonObject(...) as? [String: Any] { 
    for case let items in json["data"] { 
     // parse each item 
    } 
} 

エラーです:あなたは、明示的なjsonの所望のタイプを作る代わりに、どのような型推論を通じてウェーディングすることで、より有用なエラーメッセージを取得することができます

+0

'' json ["data"] 'の期待値の型が何であるかをコンパイラに伝えなければなりません。 – vadian

+0

'try?'のためにオプションになっていますので、このようにしてください 'let json = (JSONSerialization.jsonObject(with:data、options:[])) [String:Any] {'また、' json ["data"] ' –

+0

のタイプを指定する必要があります。私はコンパイラがSwift 2の型を推論できる理由を理解していません。(Appleの例にはその型の 'json [" data "]の型は含まれておらず、正しく型が推測されています。私は思った。 – aaronfalls

答えて

1

は思い付く

Error: value of optional type '[String : Any]??' not unwrapped; did you mean to use 'try!' or chain with '?' ?

これにより、どのように処理するかについての明確な指示が得られます。基本的には、オプションをアンパックするのではなく、別のレイヤーを追加していました! try! + as?try? + as!、またはtry + as(後者は、キャストが失敗した場合にエラーが発生した場合に処理する必要があります)のいずれかを使用すると、必要なものが得られます。

json["data"]を反復処理することはできません。Any¹は反復不可能であることに注意してください。あなたは、アクセスされたデータは、有用なタイプを持っているように、そのような場合のために、それを作る必要があります:

switch json["data"] { 
    case let items as Array<String>: 
     for item in items { 
      // parse 
     } 
    default: throw "can't parse these data" 
} 

私はあなたがそこにAny以外のものを使用しrecommentだろう。おそらくこの目的のためにプロトコルJsonDataを作成し、それを予想どおりに拡張してください。for後のあなたが持っている


  1. それ余分caseも、それがAny?を入力します!
+0

返信いただきありがとうございます。タイプ情報が参考になります。 'let json'にタイプアノテーションを追加すると助けになります。あなたが言及したスイッチの例は、私は結果を得ていない、おそらくJSONの構造。 JSONの 'data'要素(返された' Data'インスタンスからオブジェクトに変換する前に、 'jsonObject'を使って各要素を変換する方法)を解析する必要があると思います。私が本当に興味を持っている配列を平坦化しています。 – aaronfalls

+0

@aaronfalls私はいくつかの助けになることができてうれしいです!私は助けることができないことは明らかですあなたは特定のJSONを持っています。SwiftyJSONや、醜い標準ライブラリの周りにもっと良いラッパーを提供する別のライブラリをチェックしたいかもしれません。 – Raphael