Help us understand the problem. What is going on with this article?

Swiftを使ってJSONを解析する

More than 5 years have passed since last update.

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);
yosi-q
インド資本の入った米国クラウドコンサルティングファームの東京オフィスに所属し、山形県鶴岡市からリモートワークしながら、ちょっとしたwonder探ししてます。 Qiitaは記録も含めてやったことをちょこちょこ残しています。 ここで記載した記事は私感や私自身の実施した内容の記録として記載しており、所属する組織とは関係ありません。
http://yosi-q.me
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away