iOS swift Codable 不能与 Alamofire 一起使用 JSON 嵌套数据?
Posted
技术标签:
【中文标题】iOS swift Codable 不能与 Alamofire 一起使用 JSON 嵌套数据?【英文标题】:iOS swift Codable not working with Alamofire for JSON nested data? 【发布时间】:2019-11-09 03:14:44 【问题描述】:我是 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响应 【参考方案1】:您缺少 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
不是必需的。
小心你的类型。其中一些是Int
和Bool
。如果值在引号中,请仅使用 String
类型。
显然,为了简洁起见,我已从上述 struct
类型中排除了一些属性,但添加了所有缺失的属性,但仍坚持使用驼峰式命名法。
无论如何,您可以使用以下命令告诉解码器将 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)
因此,例如,如果使用 Alamofire 5:
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
()
然后您可以将startDate
和endDate
定义为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 年 1 月 15 日
在西班牙讲西班牙语的人会看到:
2019 年 1 月 15 日
最重要的是,用户将看到他们期望的格式的日期,而不是硬编码为某些特定的美国英语格式。您还可以选择在空间允许的情况下使用.long
格式(例如“2019 年 4 月 15 日”)或在空间非常紧张的情况下使用.short
(例如“04/15/19”)。只需选择适合您特定需求的dateStyle
。
【讨论】:
@Rob 很好的解释逐点感谢您的时间.. 如何将此数据分配给 tableview 标签。 "amount" 如何获取此键的值以及我应该在哪里调用 tableview.reload() 如何在table中赋值..例如:let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath as IndexPath) as! SMAIeltsTableViewCell cell.titleLbl.text = (subscriptions.first?.courseExtensions.first?.amount ?? "未找到") 我必须在我的表格视图中显示课程扩展。我们在 api 中只有一个 course_extensions。以上是关于iOS swift Codable 不能与 Alamofire 一起使用 JSON 嵌套数据?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 iOS Swift Codable 中的 API 响应通知或打印模型类上缺少的密钥?