

グーグルのAPIを使って書籍情報を取得したのですが、

[code]

    {"totalItems": int,
     "items":[ {"kind": "books#volume",
                "volumeInfo" : {"title": "hoge",
                                "authors":["name"],
                                "publishedDate": "2014-06-20"}}]}
    
[/code]

このようなjsonをパースする際に`authors`の中身を文字列として取り出すにはどうしたらいいのかわかりません。

[code]

    let authors = volumeInfo?["authors"] as! String
    print(authors)
    
[/code]

と書くと、

[code]

    Could not cast value of type
    'NSSingleObjectArrayI' (0x3b5244d0) to 'NSString' (0x3b52d0ac)
    
[/code]

というように表示されました。  
どのように記述すれば、authorsの中身を取り出し、扱うことができるようになるでしょうか。  
ご教示いただけたら幸いです。


CC BY-SA 4.0
2019-01-16T12:01:56.890
52029
2019-01-16T13:58:20.713
2019-01-16T12:41:24.057
3060
31810
question
swift json
APIで得たJSONデータのパースについて


ご掲載のJSON、`int`の部分には何らかの整数値が入るはずですね。そのままではJSONとしてパースすることが出来ません。

またこのようなご質問を書かれる場合、どの「グーグルのAPI」なのか、`volumeInfo`はどのような型で同宣言されていて、API呼び出しの後どうやって値がセットされているのか、等と言った関連情報をお示しいただいた方が、より良い回答をより早く得ることにつながるかと思います。

ただ今回はエラーメッセージをしっかり載せていただいているので、「とりあえず」の解決策は多少不明なところがあっても、ご提示できそうです。

* * *

一番肝心なのは、元のJSONデータのこの部分:

[code]

                "authors": ["name"],
    
[/code]

`"authors"`の値は`"name"`ではなく、`["name"]`なのにお気付きでしょうか。

`[ ]`は、JSONでは配列を表しますから、値の`["name"]`と言うのは、文字列が1個入った配列です。文字列ではありません。

エラーメッセージの`Could not cast value of type 'NSSingleObjectArrayI' (0x3b5244d0) to
'NSString' (0x3b52d0ac)`において、`NSSingleObjectArrayI`と言うのは配列の一種ですから、要は

**配列から文字列へのキャストはできませんよ**

と言われてるわけです。

少しの勘違いでアプリがクラッシュしてしまう`as!`を避けると、こんな感じでアクセスすれば良いはずです。

[code]

    if let authors = volumeInfo?["authors"] as? [String] { //<- `String`でなく`[String]`
        print(authors)
    } else {
        print("authors cannot be an Array of String")
    }
    
[/code]

* * *

近頃のSwiftでは、このようなJSONのパースには`Codable`を使うのが普通です。学習用に書かれているコードでしたら、今からでも`Codable`を使うように書き直してみることをお勧めします。


CC BY-SA 4.0
2019-01-16T13:58:20.713
52033
2019-01-16T13:58:20.713
13972
52029
answer