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);