文字列表記されているJSONをiOS SDK 5から使える NSJSONSerialization#JSONObjectWithData:options:error:
で NSArray/NSDictionary
に変換するとき、ちゃんと書かないとnilになっちゃう。
書くのが楽なのでRubyMotionで説明w
単純な値
error_ptr = Pointer.new(:object)
data = "true".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:false)
NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments, error: error_ptr)
=> true
単純な値の場合options
にNSJSONReadingAllowFragments
の指定を含めないとnilになっちゃう。
optionsについてはJSONObjectWithData:options:error: のオプションの意味 -- MD Blogが分かりやすいです。
配列
data = "[1,2,3]".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:false)
NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments, error: error_ptr)
=> [1, 2, 3]
配列は自然にこれで。
オブジェクト
ちょっとハマりました。
data = "{'a':1, 'b':2}".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:false)
NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments, error: error_ptr)
=> nil
orz
何がいけないのだろうと、StringからじゃなくNSDictionaryからJSONObjectを生成して文字列に変換すると
data = NSJSONSerialization.dataWithJSONObject({'a'=>1,'b'=>2}, options: 0, error: error_ptr)
NSString.alloc.initWithData(data, encoding:NSUTF8StringEncoding)
=> "{\"a\":1,\"b\":2}"
ダブルクォートで!JSONの仕様ってそうなんですかね?
了解しました。
data = '{"a":1, "b":2}'.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:false)
NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments, error: error_ptr)
=> {"a"=>1, "b"=>2}
できたヽ(´ー`)ノ
複合
どんとこい!
data = '[1,{"a":1,"b":2},[3,4,[5,6]]]'.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:false)
json_obj = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments, error: error_ptr)
=> [1, {"a"=>1, "b"=>2}, [3, 4, [5, 6]]]
json_obj[1]
=> {"a"=>1, "b"=>2}
json_obj[2][2]
=> [5, 6]
追記
RubyMotionに慣れてないと、コード見てもなんのこっちゃと思われるかも知れませんね(汗)
RubyMotion(おそらくMacRubyも同じだとおもう)ではNSArrayをRubyのArrayとして、NSDictionaryをRubyのHashとして同じように扱うことができるのですよ!
プログラム内で使用していない変数はREPLから呼べなかったのですがRubyMotion3.5から呼べるようになってました!(\( ⁰⊖⁰)/)