[英]How do I display an array from this local JSON file as a SwiftUI list in a view?
例如,如何顯示列表中每條記錄的描述符,例如:
(請注意,我在 model 中將描述符設為可選,因為數組可能為空)
這是我的 JSON 文件代碼,來自名為 flavor.json 的文件:
[
{
"id": "U45773",
"flavorGroup": "CASHEW",
"name": "NATURAL CASHEW FLAVORING",
"isBeer": true,
"isSeltzer": true,
"isNatural": true,
"descriptors": ["NUTTY", "FRUITY"],
"keywords": ["aromatic", "fattt-buttery", "brown", "nutty", "roasted", "creamy"]
},
{
"id": "U63639",
"flavorGroup": "BLACK WALNUT",
"name": "NATURAL AND ARTIFICIAL WALNUT FLAVOR",
"isBeer": true,
"isSeltzer": false,
"isNatural": true,
"descriptors": ["FATTY"],
"keywords": ["sweet", "molasses", "woody", "slight dried fruit (amber ale)"]
},
{
"id": "562811",
"flavorGroup": "APRICOT",
"name": "NATURAL AND ARTIFICIAL APRICOT FLAVOR",
"isBeer": true,
"isSeltzer": false,
"isNatural": true,
"descriptors": ["FRUITY"],
"keywords": ["juicy", "skunky", "peach", "floral", "slight green (sierra nevada pale ale)"]
}
]
這是我的 model 代碼:
struct Flavor: Codable, Identifiable {
enum CodingKeys: CodingKey {
case id
case flavorGroup
case name
case isBeer
case isSeltzer
case isNatural
case descriptors
case keywords
}
let id, flavorGroup, name: String
let isBeer, isSeltzer, isNatural: Bool
let descriptors, keywords: [String]?
}
這是我的看法 model 代碼:
class ReadData: ObservableObject {
@Published var flavors = [Flavor]()
init(){
loadData()
}
func loadData() {
guard let url = Bundle.main.url(forResource: "flavors", withExtension: "json")
else {
print("Json file not found")
return
}
let data = try? Data(contentsOf: url)
let flavors = try? JSONDecoder().decode([Flavor].self, from: data!)
self.flavors = flavors!
}
}
這是我對視圖代碼的最佳嘗試:
struct DescriptorListView: View {
@ObservedObject var datas = ReadData()
var body: some View {
List(datas.flavors) { item in
ForEach(item.descriptors, id: \.self) { descriptor in
Text("- \(descriptor)")
}
}
}
}
它會產生這些我不明白如何修復的編譯器錯誤:
可選類型 '[String]?' 的值必須解包為“[String]”類型的值
使用 '??' 合並當可選值包含“nil”時提供默認值
使用“!”強制展開如果可選值包含“nil”,則中止執行
你的嘗試非常接近。 主要問題是descriptors
是一個Optional
。 這意味着您必須以某種方式解開該可選值——我使用過if let
,這是一種稱為“可選綁定”的技術。
另一個問題是您當前的代碼將在不同的行上列出每個描述符。 我已經使用joined
將描述符連接在一起,並將它們呈現在一行中。
struct DescriptorListView: View {
@ObservedObject var datas = ReadData()
var body: some View {
List(datas.flavors) { item in
HStack {
if let descriptors = item.descriptors {
Text(descriptors.joined(separator: ", "))
} else {
Text("(no data)")
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.