質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.58%

swift:apiのレスポンスJSONをCodableで読み取りたい

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,008

kei3

score 7

 前提・実現したいこと

SwifのCodableを使ってFlickrAPIのレスポンス(JSON)を読み込みたい

 発生している問題・エラーメッセージ

typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "photos", intValue: nil)], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))

 該当のソースコード

//: Playground - noun: a place where people can play

import UIKit
import Foundation

struct Photo: Codable {
    let id: String
    let owner: String
    let secret: String
    let server: String
    let farm: Int
    let title: String
    let ispublic: Int
    let isfriend: Int
    let isfamily: Int
    let url_z: String
    let height_z: String
    let width_z: String
}

struct Photos: Codable {
    let page: Int
    let pages: Int
    let perpage: Int
    let total: String
    let photo: [Photo]
}

struct FlickrJson: Codable {
    let photos: [Photos]
    let stat: String
}

let url: URL = URL(string: "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=b92e39e1e3032c52368b9dde00a366b6&text=apple&sort=interestingness-desc&extras=url_z&per_page=5&format=json&nojsoncallback=1&api_sig=c1373de25250f8592ce893d622ef99e8")!
let task: URLSessionTask  = URLSession.shared.dataTask(with: url, completionHandler: {data, response, error in
    do {
        let jsonData = try JSONDecoder().decode(FlickrJson.self, from: data!)        
    }
    catch {
        print(error)
    }
})
task.resume()
{"photos":{"page":1,"pages":454311,"perpage":5,"total":"2271555","photo":[{"id":"13823027375","owner":"27263572@N05","secret":"2faf0ff3e1","server":"2932","farm":3,"title":"apple trees","ispublic":1,"isfriend":0,"isfamily":0,"url_z":"https:\/\/farm3.staticflickr.com\/2932\/13823027375_2faf0ff3e1_z.jpg","height_z":"427","width_z":"640"},{"id":"14923643380","owner":"56393389@N05","secret":"16107e4234","server":"3862","farm":4,"title":"Apple time","ispublic":1,"isfriend":0,"isfamily":0,"url_z":"https:\/\/farm4.staticflickr.com\/3862\/14923643380_16107e4234_z.jpg","height_z":"499","width_z":"632"},{"id":"3005896202","owner":"11142308@N07","secret":"95e2e72bd2","server":"3152","farm":4,"title":"Apple... Greek Moonshine","ispublic":1,"isfriend":0,"isfamily":0,"url_z":"https:\/\/farm4.staticflickr.com\/3152\/3005896202_95e2e72bd2_z.jpg","height_z":398,"width_z":"640"},{"id":"15210936448","owner":"65068817@N05","secret":"b26fb882b1","server":"3907","farm":4,"title":"Apples...","ispublic":1,"isfriend":0,"isfamily":0,"url_z":"https:\/\/farm4.staticflickr.com\/3907\/15210936448_b26fb882b1_z.jpg","height_z":"425","width_z":"640"},{"id":"43537647531","owner":"128091419@N08","secret":"b43be4df8d","server":"849","farm":1,"title":"Apple rain","ispublic":1,"isfriend":0,"isfamily":0,"url_z":"https:\/\/farm1.staticflickr.com\/849\/43537647531_b43be4df8d_z.jpg","height_z":"640","width_z":"480"}]},"stat":"ok"}

 試したこと

エラーメッセージに"Expected to decode Array<Any> but found a dictionary instead."とあるのでCodableの書き方が違うのかと思って見直したのですが解決できませんでした。

 補足情報(FW/ツールのバージョンなど)

Xcode10.0, Swift4, Codable, playground

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

Expected to decode Array<Any> but found a dictionary instead.

Google翻訳より

配列<Any>のデコードが予想されますが、代わりに辞書が見つかりました。

辞書なのに配列を指定しているということです。
ということで、

let photos: [Photos] → let photos: Photos


あと、質問内のJSONは一箇所だけheight_zがIntになっているので、今のままだと別のエラーが出ます。

"height_z": 398

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る