iOS swift Codable无法与Alamofire一起使用JSON嵌套数据



我是Alamofire和Codable概念的新手。在iOS中,有人能告诉我如何使用它来访问我的json数据吗。

这是我的json响应。

{"subscriptions": [
{
"batch_user_id": 23,
"batch_name": "demo batch",
"course_name": "IELTS",
"start_date": "Nov 01 2019",
"end_date": "Nov 30 2019",
"no_of_days": 21,
"total_no_of_days": 30,
"extended_date": "Nov 30 2019",
"extended": false,
"course_extensions": [
{
"id": 31,
"amount": "3500.0",
"course_id": 1,
"is_active": true,
"number_of_days": 5
},

这是可编码的代码:

struct course_extensions: Codable {
let id: String
let amount: String
let course_id: String
private enum CodingKeys: String, CodingKey {
case id = "id"
case amount = "amount"
case course_id = "course_id"
}
}
struct subscriptions: Codable {
let batch_user_id: String
let batch_name: String
let course_extensions: course_extensions
private enum CodingKeys: String, CodingKey {
case batch_user_id
case batch_name
case course_extensions = "course_extensions"
}
}
struct User: Codable {
let status: String
let message: String
let subscriptions: subscriptions
}

这是我与alamofire:的服务电话

// MARK: - Service call
func fetchUserData() {
AF.request(SMAConstants.my_subscriptions, method: .get, parameters: nil, headers: nil)
.responseJSON { (response) in
switch response.result {
case .success(let value):
let swiftyJsonVar = JSON(value)
print(swiftyJsonVar)
case .failure(let error):
print(error)
}
}
}

有人能帮我用codable访问嵌套数组数据吗。提前谢谢。

您缺少JSON最外层的结构:

struct ResponseObject: Codable {
let subscriptions: [Subscription]
}

并且,您可以使用正常的camelCase属性:

struct Subscription: Codable {
let batchUserId: Int
let batchName: String
let courseExtensions: [CourseExtension]
}
struct CourseExtension: Codable {
let id: Int
let amount: String
let courseId: Int
let isActive: Bool
}

一些观察:

根据惯例,struct类型名称应以大写字母开头
  • 在这种情况下,这些CodingKeys是不必要的
  • 小心你的类型。其中一些是IntBool。如果值位于引号中,则仅使用String类型
  • 显然,为了简洁起见,我从上面的struct类型中排除了一些属性,但添加了任何缺失的属性,但坚持使用camelCase约定
  • 无论如何,您可以告诉解码器使用:将snake_case JSON密钥转换为camelCase属性名称

    do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let object = try decoder.decode(ResponseObject.self, from: data)
    print(object.subscriptions)
    } catch {
    print(error)
    }
    

    因此,例如,如果使用Alamofire5:

    let decoder: JSONDecoder = {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    return decoder
    }()
    func fetchUserData() {
    AF.request(SMAConstants.mySubscriptions))
    .responseDecodable(of: ResponseObject.self, decoder: decoder) { response in
    guard let value = response.value else {
    print(response.error ?? "Unknown error")
    return
    }
    print(value.subscriptions)
    }
    }
    

    产生:

    [Subscription(batchUserId: 23, batchName: "demo batch", courseExtensions: [CourseExtension(id: 31, amount: "3500.0", courseId: 1, isActive: true)])]
    
    顺便说一下,我注意到你的日期是MMM d yyyy格式的。是否要将这些对象转换为Date对象?如果是这样的话,你可以使用一个解码器来指定一个日期格式化程序,比如:
    let decoder: JSONDecoder = {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "MMM d yyyy"
    decoder.dateDecodingStrategy = .formatted(formatter)
    return decoder
    }()
    

    然后可以将startDateendDate定义为Date对象。然后,当您在UI中显示这些日期时,您可以使用DateFormatter来显示一个很好的本地化日期格式,而不仅仅是固定的、丑陋的MMM d yyyy格式。

    要在UI中显示日期,您需要执行以下操作:

    let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    return formatter
    }()
    

    然后:

    label.text = dateFormatter.string(from: date)
    

    在美国讲英语的人会看到:

    2019年4月15日

    一位美国西班牙语使用者将看到:

    abr。2019年9月15日

    在西班牙讲西班牙语的人将看到:

    2019年1月15日

    最重要的是,用户将以他们期望的格式看到日期,而不是以某种特定的美国英语格式硬编码。您还可以选择在空间允许的情况下使用.long格式(例如"2019年4月15日"(,或者在空间非常紧张的情况下(例如"04/15/19"(使用.short格式。只需选择适合您特定需求的dateStyle即可。

    相关内容

    • 没有找到相关文章

    最新更新