简体   繁体   中英

How to get only Array part inside of a json

Json: {"photos":{"page":1,"pages":20,"perpage":100,"total":"1941","photo":[{"id":"40270314685","owner":"24843974@N00","secret":"46f5a82bd3","server":"785","farm":1,"title":"Raleigh C Easter 2018-30","ispublic":1,"isfriend":0,"isfamily":0},{"id":"39355840240","owner":"24843974@N00","secret":"eb23dc2e68","server":"816","farm":1,"title":"Raleigh C Easter 2018-31","ispublic":1,"isfriend":0,"isfamily":0},{"id":"40270318535","owner":"24843974@N00","secret":"97c6280b2f","server":"811","farm":1,"title":"Raleigh C Easter 2018-32","ispublic":1,"isfriend":0,"isfamily":0}]},"stat":"ok"}

I only want to get "photo":[{"id":"402703146... part as an array. This is my code

struct GetPhotosOfUser:Decodable{

let id: String
let secret: String
let server: String
let farm: String

enum TopLevelCodingKeys: String, CodingKey {
    case photos
}

enum UserCodingKeys: String, CodingKey {
    case photo
}

enum SecondCodingKeys: String, CodingKey {
        case id
        case secret
        case server
        case farm
}

init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: TopLevelCodingKeys.self)
    let userContainer = try container.nestedContainer(keyedBy: UserCodingKeys.self, forKey: .photos)
    let userContainer1 = try userContainer.nestedContainer(keyedBy: SecondCodingKeys.self, forKey: .photo)
    id = try userContainer1.decode(String.self, forKey: .id)
    secret = try userContainer1.decode(String.self, forKey: .secret)
    server = try userContainer1.decode(String.self, forKey: .server)
    farm = try userContainer1.decode(String.self, forKey: .farm)
}

}

var getphotos = [GetPhotosOfUser]()

func downloadJSON(completed: @escaping () -> ()){
    let url = URL(string: "https://www.flickr.com/services/rest/?method=flickr.people.getPhotos&api_key=<api-key>&user_id=24843974@N00&format=json&nojsoncallback=1")
    URLSession.shared.dataTask(with: url!) { (data, response, error) in
        if error == nil{
            do{
                self.getphotos = try JSONDecoder().decode([GetPhotosOfUser].self, from: data!)
                DispatchQueue.main.async {
                    completed()
                    print("Json Baglandi")
                    print(self.getphotos.count)
                }
            }catch{
                print("JSON Error")
                print(error)
            }
        }
        }.resume()
}

But it says ""Expected to decode Array but found a dictionary instead."

Could you please help me ?

You need to decode from the top level so your structs should be like this

struct TopLevel : Decodable {
    let photos: SubLevel
}

struct SubLevel: Decodable {
    let photo: [GetPhotosOfUser]
}
struct GetPhotosOfUser: Decodable{

    let id: String
    let secret: String
    let server: String
    let farm: Int //Obs! I changed the type here
}

and then when decoding you need to change your code to

let result = try JSONDecoder().decode(TopLevel.self, from: data!)
self.getphotos = result.photos.photo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM