Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
451 views
in Technique[技术] by (71.8m points)

ios - How do I parse this nested JSON using Codable with Swift?

I am trying to parse this JSON using Codable:

{
  "users": [
    {
      "id": 1,
      "name": "Allen Carslake",
      "userName": "acarslake0",
      "profileImage": "https://source.unsplash.com/random/400x400",
      "createdDate": "2019-07-08T00:00:00.000+0000"
    },
    {
      "id": 2,
      "name": "Revkah Antuk",
      "userName": "rantuk1",
      "profileImage": "https://source.unsplash.com/random/400x400",
      "createdDate": "2019-07-05T00:00:00.000+0000"
    },
    {
      "id": 3,
      "name": "Mirna Saffrin",
      "userName": "msaffrin2",
      "profileImage": "https://source.unsplash.com/random/400x400",
      "createdDate": "2019-05-19T00:00:00.000+0000"
    },
    {
      "id": 4,
      "name": "Haily Eilers",
      "userName": "heilers3",
      "profileImage": "https://source.unsplash.com/random/400x400",
      "createdDate": "2019-06-28T00:00:00.000+0000"
    },
    {
      "id": 5,
      "name": "Oralie Polkinhorn",
      "userName": "opolkinhorn4",
      "profileImage": "https://source.unsplash.com/random/400x400",
      "createdDate": "2019-06-04T00:00:00.000+0000"
    }
]
}

I am keeping the URL private on here but it is returning JSON above. So far this is my code:

import UIKit

struct User: Codable {
    let id: Int
    let name: String
    let userName: String
    let profileImage: String
    let createdDate: String
}

struct Users: Codable {
    let users: String
}

let url = URL(string: "")!

URLSession.shared.dataTask(with: url) { data, _, _ in

    if let data = data {

        let users = try? JSONDecoder().decode([User].self, from: data)
        print(users)
    }

    }.resume()

I need to be able to access the User properties but I think the nesting is making it difficult for me. Any help is awesome!! Thank you!!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First of all: Catch always the DecodingError and print it. It tells you exactly what's wrong.

The error occurs because you are ignoring the root object Users. Your code works if you decode(Users.self.

My suggestions:

  • Decode createdDate as Date adding a appropriate date decoding strategy.
  • Decode profileImage as URL (for free).
  • Handle all errors.

struct Root : Decodable { // `Users` and `User` is too confusing
    let users: [User]
}

struct User : Decodable {
    let id: Int
    let name: String
    let userName: String
    let profileImage: URL
    let createdDate: Date
}

URLSession.shared.dataTask(with: url) { data, _, error in

    if let error = error { print(error); return }
    do {
        let decoder = JSONDecoder()
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "en_US_POSIX")
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
        decoder.dateDecodingStrategy = .formatted(dateFormatter)
        let result = try decoder.decode(Root.self, from: data!)
        for user in result.users {
           print(user.userName, user.id, user.createdDate)
        }
    } catch {
        print(error)
    }

}.resume()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...