【发布时间】:2020-07-04 09:14:28
【问题描述】:
我正在尝试构建一个从 API 端点接收 JSON 对象的应用程序,然后我想在视图中列出该对象。我看过很多关于这个主题的视频,但是在每个视频中,他们都使用非常简单的 JSON 对象作为示例,因此他们编写的代码似乎并没有真正转移,无论我如何尝试格式化它都会给我错误.代码如下
import SwiftUI
import Combine
import Foundation
public struct ActivityModel: Codable, Identifiable {
public let id: Int
public let name: String
public let activity_desc: String?
}
public struct ActivitiesModel2: Codable {
public let location: String
public let popular: [String:ActivityModel]
}
public struct ActivitiesModel: Codable {
public let activities: ActivitiesModel2
}
public class ActivityFetcher: ObservableObject {
var activities: ActivitiesModel?
init(){
guard let url = URL(string: "https://mywebsite.com/api/loadapi") else { return }
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
do {
if let d = data {
let decodedLists = try JSONDecoder().decode(ActivitiesModel.self, from: d)
DispatchQueue.main.async {
self.activities = decodedLists
}
} else {
print("No Data")
}
} catch {
print("Error")
}
}.resume()
}
}
struct ActivityGuestView: View {
let networkingServiceGeneral = NetworkingServiceGeneral()
@ObservedObject var viewRouter: ViewRouter
@ObservedObject var fetcher = ActivityFetcher()
var body: some View {
// This is where my issues start
List(fetcher.activities?.activities.popular) { result in
VStack {
Text(result.name)
Text(result.activity_desc)
.font(.system(size: 11))
.foregroundColor(Color.gray)
}
}
}
}
正如我所说,这段代码给了我 5 个错误。它们是:
- Initializer 'init(_:rowContent:)' requires that '(key: String, value: ActivityModel)' conform to Identifiable
- Initializer 'init(_:rowContent:)' requires that '[String : ActivityModel]' conform to 'RandomAccessCollection'
-Value of optional type '[String : ActivityModel]?' must be unwrapped to a value of type '[String : ActivityModel]'
- Coalesce using '??' to provide a default when the optional value contains 'nil'
- Force-unwrap using '!' to abort execution if the optional value contains 'nil'
其中一些错误有修复它的选项,但是当我按下修复它会添加代码但实际上并没有修复错误,所以我想还是只包含它们。我对 Swift 还是很陌生,但我知道其中的一些要求,特别是符合 Identifiable 的要求,但它说当我尝试添加标签时 struct ActivitiesModel 不符合 identifiable 并且 JSON 对象没有没有该部分的 ID,所以我不能要求 ID 使其可识别。
任何帮助将不胜感激,这已经是一堵墙了。
这是 JSON
"activities": {
"location": "Dallas",
"popular": {
"10": {
"id": 38,
"name": "Adventure Landing Dallas",
"activity_desc": "Aquatic complex chain with additional land attractions including mini-golf, laser tag & go-karts.",
},
"12": {
"id": 40,
"name": "Jumpstreet",
"activity_desc": "None provided.",
},
}
}
}
【问题讨论】:
-
好的,这里发生了一些事情。首先,带有可变键的 JSON 非常糟糕。如果可以的话,改变它;
popular应该只是一系列活动。如果你不能改变它,那么你可以在你的结构中使用一个计算属性来返回一个ActivityModel的数组。其次,您需要处理可选的,最好在获取数据并且有要列出的内容之前甚至不进入此视图,但是您可以使用 nil 合并运算符来提供空数组 -
最后我建议你使用编码键来消除 ``activity_desc` 中的 un-Swifty _ 并将其映射到
activityDesc -
很多这些术语都让我头疼...我无法将 JSON 输出更改为没有动态标签,因为它是服务器端的 SQL 返回
标签: ios arrays json swift combine