2016-05-02 11 views
0

Xcode 6.4を使用し、迅速にプログラミングする。Swift - JSONファイルで読む

URLからJSONで読み込むプログラムを入力しています。 JSONのサンプルはこのURL(https://itunes.apple.com/us/rss/topmovies/limit=2/json)にあります。このサイトを使用してJSONを解析し、よりよく読むために使用しています(http://json.parser.online.fr/)。

に実際のムービー名とイメージURLを取得するには、JSONのレベルまで作業する必要がありますが、どのような種類の変数であるのかは分かりません.Dictionaryは必須です。私はそれが辞書の配列でなければならないと思っていましたが、これはコンパイルされますが、コンソールのentryDictionaryの出力はOptionlで始まり​​ます(エントリではありません)。エラーエントリがタイプANYOBJECTの添字を持っていないと言って

だから私は、私はイム取得方法を求めています:。名前フィールドとイムを:JSONから画像

func downloadDataFromURLString(urlString: String) { 

    //Downloaded data and is now stored in data. Took code out because 
    //irrelevant to my problem at this point. Data variable has correct 
    //JSON, now I am trying to parse it. 

      } else { //download suceeded, time to parse 
       var error: NSError? = nil 
       var names = [String]() 

       if let rootDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) as? [String: AnyObject] { 

        let feedDictionary = rootDictionary["feed"] as! [String: AnyObject] 

        let entryDictionary: AnyObject? = feedDictionary["entry"] 

        println(entryDictionary) //For debugging 

        //for entry in entryDictionary as! NSArray { 
         // let name = entryDictionary["name"] 
         // let image = entryDictionary["image"] 
         // let movie = Movie(name: name!, image: image!) 
         // weakSelf!.movies.append(movie) 
        //} 

ここでの青写真でありますJSON

"feed":{ 
    "author":{}, 
    "entry":[ 
    { 
     "im:name":{ 
      "label":"Deadpool" 
     }, 
     "im:image":[], 
     "summary":{}, 
     "im:price":{}, 
     "im:contentType":{}, 
     "rights":{}, 
     "title":{}, 
     "link":[], 
     "id":{}, 
     "im:artist":{}, 
     "category":{}, 
     "im:releaseDate":{} 

答えて

1

AnyObjectは実際にはサブcriptable(型がAnyObjectの変数をサブスクリプトしようとしていますか? ["feed"])。あなたはできるだけNSArrayやNSDictionaryのようなCocoaコンテナ型へのキャストも避けるべきです。ここでは、エントリの配列の名前の配列のうちのラベルを取得する方法の例です:

import Foundation 

func labels(feedDictionary:[String:AnyObject]) -> [String] { 
    guard let entries = feedDictionary["entry"] as? [String:AnyObject] else { 
     return [] 
    } 

    return entries.flatMap { (key:String, value:AnyObject) -> String? in 
     guard key == "im:name" else { 
      return nil 
     } 

     guard let name = value as? [String:String] else { 
      return nil 
     } 

     return name["label"] 
    } 
} 

あなたはキャストを終わると、私はしかし、最も単純なケースが、何のためにスウィフトで独自にNSJSONSerializationを使用しないことをお勧めします牛が家に帰るまで選択肢をラップします。

FreddySwiftyJSONのような優れたJSON(de)シリアライズ体験を達成するためのSwift言語機能を適用したライブラリがあります。

フレディと例えば次のようなスタイルであなたの問題を表現することができます:

let json = try JSON(data: data) 
json.decode("feed", type:Feed.self) 

struct Feed: JSONDecodable { 
    let entries:[Entry] 
    init(json: JSON) throws { 
     self.entries = try json.arrayOf("entry", type:Entry.self) 
    } 
} 

struct Entry:JSONDecodable { 
    let name:IMName 
    init(json: JSON) throws { 
     self.name = try json.decode("im:name", type:IMName.self) 
    } 
} 

struct IMName:JSONDecodable { 
    let label:String 
    init(json: JSON) throws { 
     self.label = try json.string("label") 
    } 
} 
+0

JAL、それが公正です。 Freddyを例に、完全なソリューションを入力するだけです。 – mz2

+0

ありがとうございます。私は実際には第三者図書館の使用が許可されていることを確認するために二重チェックを行っています。これは学校の課題です。第三者図書館なしで解析することは、不可能でぎこちないコードの次にあるでしょうか?私は、この種のコーディングの問題は数週間で私の最終決定になると信じています。私たちはサードパーティライブラリを持っていません。 –

+0

ああ、まったく不可能ではないが、例えば、面倒で反復的で、むしろバグの傾向があるような「本当の」商業環境で。 – mz2