質問: try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! NSDictionary } catch {} } }) task.resume() ```
回答: `JSONObjectWithData(_:options:)`のリファレンスを参照すると、返り値が`AnyObject`であることが分かると思います。その詳細については次のように説明されています。 > > **Return Value** > > A Foundation object from the JSON data in data, or nil if an error occurs. > > > NSJSONSerialization Class Reference > > > 「JSONに応じて、Foundationのオブジェクトを返す」、とあります。実際的には、 * ルート要素が辞書の場合、`NSDictionary` * ルート要素が配列の場合、`NSArray` が返却されます。 ここでは`AnyObject`から`NSDictionary`へダウンキャスト(基底型から派生型への型変換、Obj-Cクラスは全て`AnyObject`派生として扱われる)をしています。 ダウンキャストは安全ではないので、型が一致しない場合に実行時エラーとする`as!`と、`nil`として扱う`as?`のいずれかを用いる必要があります。ここでは前者を利用しているため実行時エラーとなります。 対応法はいろいろありますが、多分型チェックを行うのが一番確実です。 1. 変換結果に対して型チェックを行い、配列であれば`Array`、辞書であれば`Dictionary`に変換する。 2. JSONとして必ず辞書が来る想定であれば、`as!`でクラッシュするのは正当な動作です。または`as?`演算子を用いてダウンキャストして、`nil`チェックを行うこともできます。 3. キー値コーディングを利用して、キーパスで要素にアクセスすれば、トップレベルオブジェクトの型は意識しなくても良いですが、型の考えに厳密なSwiftにおいては、あまり推奨されないと思います(ただ`NSJSONSerialization`そのものはこの利用法を想定しているような...)。