JSONをパースして情報を取得するときのお話。
パースにはNSJSONSerialization
を使う
JSONのパースには、下記のようにFoundationFrameworkのNSJSONSerialization
を使用します。
NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments, error: nil)
Appleのドキュメントには下記のようなことが書いてあります。
- 最上位の型は
NSArray
(配列)またはNSDictionary
(辞書) - 各プロパティの型は、
NSString
(NSMutableString
)、NSNumber
、NSArray
、NSDictionary
、NSNull
のどれか -
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);