[英]Unable to GET from JSON API
我已尝试遵循各种教程,但无法从该 API 获取数据。 我确实设法在更简单的 JSON 上取得了成功,但是这个正在占用我的时间。 首先,JSON:
{
"object": {
"array": [
{
"id": 48,
"name": "Job No.# 48",
"description": "blah",
"start_at": "2021-03-05T13:15:00.000+11:00",
"end_at": "2021-03-05T14:15:00.000+11:00",
"map_address": "blah road"
},
{
"id": 56,
"name": "Job No.# 56",
"description": "Do it",
"start_at": "2021-06-22T11:30:00.000+10:00",
"end_at": "2021-06-22T13:30:00.000+10:00",
"map_address": " blah"
}
],
"person": {
"id": 52,
"first_name": "Bob",
"last_name": "Newby",
"mobile": "0401111111",
"email": "bob@mail.com"
}
}
}
现在我尝试解码它:
struct api_data: Codable {
let object : Object
}
struct Object: Codable {
let array : [array]
let person : Person
}
struct array: Codable, Identifiable {
let id : Int?
let start_at, end_at : Date?
let duration : Float?
let cancellation_type : String?
let name, description, address, city, postcode, state : String?
}
struct Person: Codable, Identifiable {
let id : Int?
let first_name, last_name, mobile, email : String?
}
class FetchShifts: ObservableObject {
@Published var shifts = [Shifts]()
init() {
let url = URL(string: "realURLhiddenForPrivacy")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("myToken", forHTTPHeaderField: "Authorization")
URLSession.shared.dataTask(with: request) {(data, response, error) in
do {
if let array_data = data {
let array_data = try JSONDecoder().decode([array].self, from: array_data)
DispatchQueue.main.async {
self.array = array_data
}
} else {
print("No data")
}
} catch {
print(error)
}
}.resume()
}
}
以及我如何尝试呈现它:
@ObservedObject var fetch = FetchArray()
var body: some View {
VStack {
List(array.shifts) { shft in
VStack(alignment: .leading) {
Text(shft.name!)
}
}
}
}
}
}
任何帮助表示赞赏,不知道我在这里哪里出错了,在教程中花了 5-7 个小时。
如果您不熟悉它,我总是建议使用 app.quicktype.io 从 JSON 生成模型。 这是它产生的结果:
// MARK: - Welcome
struct Welcome: Codable {
let status: String
let payload: Payload
}
// MARK: - Payload
struct Payload: Codable {
let shifts: [Shift]
let worker: Worker
}
// MARK: - Shift
struct Shift: Codable, Identifiable {
let id: Int
let name, shiftDescription, startAt, endAt: String
let mapAddress: String
enum CodingKeys: String, CodingKey {
case id, name
case shiftDescription = "description"
case startAt = "start_at"
case endAt = "end_at"
case mapAddress = "map_address"
}
}
// MARK: - Worker
struct Worker: Codable {
let id: Int
let firstName, lastName, mobile, email: String
enum CodingKeys: String, CodingKey {
case id
case firstName = "first_name"
case lastName = "last_name"
case mobile, email
}
}
然后,要解码,您可以执行以下操作:
do {
let decoded = try JSONDecoder().decode(Welcome.self, from: shift_data)
let shifts = decoded.payload.shifts
} catch {
print(error)
}
请注意,在 Swift 中,通常的做法是使用驼峰命名,而不是蛇命名,因此您会看到CodingKeys
一些转换(也有自动执行此操作的方法)。
您的代码将是:
if let shiftData = data { do { let decoded = try JSONDecoder().decode(Welcome.self, from: shiftData) DispatchQueue.main.async { self.shifts = decoded.payload.shifts } } catch { print(error) } }
您可以为 JSON 解码器自动使用keyDecodingStrategy = .convertFromSnakeCase
,而不是定义自定义键,并且可以指定自定义日期格式,甚至在解码器实现中抛出自定义错误。
struct Worker: Codable {
let id: Int
let firstName: String?
let lastName: String?
let mobile: String?
let email: String?
}
struct Shift: Codable, Identifiable {
let id: Int
let name: String?
let description: String?
let startAt: Date?
let endAt: Date?
let mapAddress: String?
}
struct Payload: Codable {
let shifts: [Shift]?
let worker: Worker?
}
struct Response: Codable {
let status: String
let payload: Payload?
}
class MyCustomDecoder: JSONDecoder {
override init() {
super.init()
self.keyDecodingStrategy = .convertFromSnakeCase
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
self.dateDecodingStrategy = .formatted(dateFormatter)
}
}
// Usage
if let data = json.data(using: .utf8) {
let response = try MyCustomDecoder().decode(Response.self, from: data)
print(response)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.