作為這個問題的后續,我現在想遍歷 SwiftUI 中的 Codable 結構陣列,并將它們在我的 ContentView{} 中呈現為文本或串列項。
我嘗試在該部分中實作一個變數 ,geoDataArray然后在我的.task部分中使用 a 對其進行迭代,但收到了很多關于型別和展開值的錯誤。ForEachContentView
任何幫助表示贊賞!我還是 SwiftUI 的新手。
下面是我的代碼:
struct GeoService: Codable {
var status: String
var results: [GeoResult]
}
struct GeoResult: Codable {
struct Geometry: Codable {
struct Location: Codable {
let lat: Float
let lng: Float
init() {
lat = 32
lng = 30
}
}
let location: Location
}
let formatted_address: String
let geometry: Geometry
}
struct ContentView: View {
// @State private var results: Any ?????????
var body: some View {
NavigationView {
Text("Test")
.navigationTitle("Quotes")
.task {
await handleData()
}
}
}
func handleData() async {
let geoResult="""
{
"results": [
{
"formatted_address": "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
"geometry": {
"location": {
"lat": 37.4224764,
"lng": -122.0842499
}
}
},
{
"formatted_address": "Test addresss",
"geometry": {
"location": {
"lat": 120.32132145,
"lng": -43.90235469
}
}
}
],
"status": "OK"
}
""".data(using: .utf8)!
let decoder = JSONDecoder()
print("executing handleData()")
do {
let obj = try decoder.decode(GeoService.self, from: geoResult)
for result in obj.results {
print("Address: \(result.formatted_address)")
print("Lat/long: (\(result.geometry.location.lat), \(result.geometry.location.lng))")
}
} catch {
print("Did not work :(")
}
}
}
uj5u.com熱心網友回復:
您的代碼在列印到控制臺時作業正常,但ForEach要求GeoResult符合Identifiable(首選)或至少Hashable. 鑒于您沒有id在代碼中包含該屬性,讓我們讓該結構符合Hashable.
所以,假設每一個GeoResult都是不同formatted_address的,因為從不一樣(你必須檢查這是否是真的),你可以添加兩個函式來確保一致性。您將獲得以下資訊:
struct GeoResult: Codable, Hashable { // <- Conform to Hashable
// Differentiating
static func == (lhs: GeoResult, rhs: GeoResult) -> Bool {
lhs.formatted_address == rhs.formatted_address
}
// Hashing
func hash(into hasher: inout Hasher) {
hasher.combine(formatted_address)
}
struct Geometry: Codable {
struct Location: Codable {
let lat: Float
let lng: Float
init() {
lat = 32
lng = 30
}
}
let location: Location
}
let formatted_address: String
let geometry: Geometry
}
在視圖中,添加一個陣列GeoResult,這將是@State要迭代的變數。將.task()修改器放在最外面的視圖上。
// This is the list
@State private var geoArray: [GeoResult] = []
var body: some View {
NavigationView {
VStack {
// GeoResult is not Identifiable, so it is necessary to include id: \.self
ForEach(geoArray, id: \.self) { result in
NavigationLink {
Text("Lat/long: (\(result.geometry.location.lat), \(result.geometry.location.lng))")
} label: {
Text("Address: \(result.formatted_address)")
}
}
.navigationTitle("Quotes")
}
}
// Attach the task to the outermost view, in this case the NavigationView
.task {
await handleData()
}
}
最后,@State在解碼后更改函式中的變數:
func handleData() async {
// ...
let decoder = JSONDecoder()
do {
let obj = try decoder.decode(GeoService.self, from: geoResult)
// Add this
geoArray = obj.results
} catch {
print("Did not work :(\n\(error)")
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/478511.html
