首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Decodable解码JSON数组?

如何使用Decodable解码JSON数组?
EN

Stack Overflow用户
提问于 2017-12-12 20:34:02
回答 1查看 6.8K关注 0票数 5

我正在请求API发送一些数据给我,我可以成功检索,但我被困在它的解码过程中。下面是我收到的JSON:

代码语言:javascript
复制
[  
   {  
      "challenge_id":1,
      "challenge_title":"newchallenge1",
      "challenge_pts_earned":1000,
      "challenge_description":"description1",
      "start_date":"2017-09-24T00:00:00.000Z",
      "end_date":"2017-09-24T00:00:00.000Z",
      "challenge_category_id":1,
      "status_id":2,
      "createdAt":"2017-09-24T17:21:47.000Z",
      "updatedAt":"2017-09-24T09:40:34.000Z"
   },
   {  
      "challenge_id":2,
      "challenge_title":"challenge1",
      "challenge_pts_earned":100,
      "challenge_description":"description1",
      "start_date":"2017-09-24T00:00:00.000Z",
      "end_date":"2017-09-24T00:00:00.000Z",
      "challenge_category_id":1,
      "status_id":0,
      "createdAt":"2017-09-24T17:22:12.000Z",
      "updatedAt":"2017-09-24T09:22:12.000Z"
   },
   {  
      "challenge_id":3,
      "challenge_title":"new eat title",
      "challenge_pts_earned":600000,
      "challenge_description":"haha",
      "start_date":"2017-01-09T00:00:00.000Z",
      "end_date":"2017-01-10T00:00:00.000Z",
      "challenge_category_id":2,
      "status_id":0,
      "createdAt":"2017-09-27T17:12:10.000Z",
      "updatedAt":"2017-09-27T09:15:19.000Z"
   }
]

我正在尝试创建以下结构来解码它:

代码语言:javascript
复制
   struct challenge : Codable {
    let  id : String?
    let  title : String?
    let  pointsEarned : String?
    let  description : String?
    let  dayStarted : String?
    let  dayEnded : String?
    let  categoryID : String?
    let  statusID : Int?
    let createdAt : Date?
    let updatedAt : Date?

    enum CodingKeys: String, CodingKey {
        case id = "challenge_id"
        case title = "challenge_title"
        case pointsEarned = "challenge_pts_earned"
        case description = "challenge_description"
        case dayStarted = "start_date"
        case dayEnded = "end_date"
        case categoryID = "challenge_category_id"
        case statusID = "status_id"
        case createdAt, updatedAt
    }

}

下面是我的实现代码:

代码语言:javascript
复制
 var All_challenges : [challenge]?
 let url = URL(string: API.all_challenges.rawValue)!
        var request = URLRequest(url: url)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "GET"
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                print("error=\(String(describing: error))")
                return
            }
            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("\(String(describing: response))")
            }
            let responseString = String(data: data, encoding: .utf8)
            guard let result = responseString else { return }
            print(result)
           if let json = try? JSONDecoder().decode([challenge].self , from : data ) {
                self.All_challenges = json

           }

         }
        task.resume()

然而,当我尝试调试它时,我永远不能输入if语句

代码语言:javascript
复制
if let json = try? JSONDecoder().decode([challenge].self,from:data ) {
self.All_challenges = json

 }

请给我一些描述我的错误在哪里,我是JSON解析的新手

EN

回答 1

Stack Overflow用户

发布于 2017-12-12 21:12:18

您的代码中有几个错误。首先,你的一些变量类型是错误的。所有id%s和challenge_pts_earned都需要是Int类型。您可以很容易地发现这一点,因为在JSON中,字符串需要用引号分隔。在对Date进行解码时,还需要指定要使用的日期格式。

startDateendDate也是dates,所以即使可以将它们解码为Strings,我也建议您将它们存储为实际的Date对象。

还请遵守Swift命名约定,即类型为upperCamelCase,变量和函数名称为lowerCamelCase。您可以使用符合CodingKey的自定义类型将您的自定义变量名映射到它们的JSON表示。

代码语言:javascript
复制
struct Challenge : Decodable {
    let id: Int?
    let title: String?
    let pointsEarned: Int?
    let description: String?
    let startDate: String?
    let endDate: String?
    let categoryId: Int?
    let statusId: Int?
    let createdAt: Date?
    let updatedAt: Date?

    private enum CodingKeys: String, CodingKey {
        case id = "challenge_id"
        case title = "challenge_title"
        case pointsEarned = "challenge_pts_earned"
        case description = "challenge_description"
        case startDate = "start_date"
        case endDate = "end_date"
        case categoryId = "challenge_category_id"
        case statusId = "status_id"
        case createdAt
        case updatedAt
    }

    static var dateFormatter: DateFormatter {
        let df = DateFormatter()
        df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
        df.locale = Locale(identifier: "en_US_POSIX")
        return df
    }
}

do {
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .formatted(Challenge.dateFormatter)
    let decoded = try decoder.decode([Challenge].self, from: jsonArrayResponse.data(using: .utf8)!)
} catch {
    print(error)
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47772779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档