1. Qiita
  2. 投稿
  3. iOS

Swiftを使ってJSONを解析する

  • 42
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

JSONをパースして情報を取得するときのお話。

パースにはNSJSONSerializationを使う

JSONのパースには、下記のようにFoundationFrameworkのNSJSONSerializationを使用します。

NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments, error: nil)

Appleのドキュメントには下記のようなことが書いてあります。

  • 最上位の型はNSArray(配列)またはNSDictionary(辞書)
  • 各プロパティの型は、NSString(NSMutableString)、NSNumberNSArrayNSDictionaryNSNullのどれか
  • NSDictionaryのキーはNSString
  • 数値はNaNと無限大は指定されない

これを踏まえたうえで、整理しました。

ちなみに、Streamから扱うこともあろうかと思いますが、ここではStreamは扱いません。
(できそうなことが書いてあるのですが、そこまでやれていないので、対象外とします。)

パースの方法

最上位が配列になっている場合

下記のようなJSONを想定しています。

[
    { "title": "Sample Title1", "data": "Sample Data1" },
    { "title": "Sample Title2", "data": "Sample Data2" }
]    

パースするときはこんな感じ。

let list:NSArray = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray

配列なので、受ける側listも配列(NSArray)で受ける。

最上位が辞書(Key-Valueの形)になっている場合

下記のようなJSONを想定しています。

{
    "title": "Sample Title", 
    "data": "Sample Data"
}    

パースするときはこんな感じ。

let list:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

受ける側listも辞書(NSDictionary)で受ける。

NSJSONReadingOptionsの指定

パースするときのオプションとしてNSJSONReadingOptionsを指定しますが、指定できるのは下記の3つ。
用途の応じて設定する必要があります。

  • NSJSONReadingOptions.MutableContainers : 返ってくる全てのObjectがMutable
  • NSJSONReadingOptions.MutableLeaves : 返ってくるObjectのうち、String属性のものがMutableなNSMutableStringとなる
  • NSJSONReadingOptions.AllowFragments : 返ってくる全てのObjectがImutable

特に変更とかしなければNSJSONReadingOptions.AllowFragmentsでいいと思うんですが、どうなんでしょうね。
(ドキュメントを読んだ程度なので間違っているかも。。。)

おまけ:HTTP経由でのJSONを取得方法

付属のファイルを読ませる、固定で書いてしまうなどいろいろ想定できますが、
ここではREST APIからHTTP経由でデータを取得した形を書きました。

私は、取得は下記の形でやりました。

let URL = "http://example.com" as NSString
let req = NSURLRequest(URL: URL)
let connection: NSURLConnection = NSURLConnection(request: req, delegate: self, startImmediately: false) as NSURLConnection!

var res: NSURLResponse? = nil;
var error: NSError? = nil;

var data: NSData? = NSURLConnection.sendSynchronousRequest(req, returningResponse:&res, error:&error);