我正在創建現有應用程式的新版本,并希望將新的異步等待格式用于 Web 請求。在 JSONDecoder().decode 行放置一個中斷,我看到我確實有資料 - 但解碼不起??作用。(網址和我的密鑰在舊版本中有效)
這是 Web 源的 JSON 格式(縮短 - 在fuel_station 中有更多專案):
{
"station_locator_url":"https://afdc.energy.gov/stations/",
"total_results":110,
"station_counts":{},
"fuel_stations":[
{
"access_code":"public",
"access_days_time":"24 hours daily; call 866-809-4869 for Clean Energy card",
"access_detail_code":"KEY_ALWAYS",
"cards_accepted":"CleanEnergy",
"date_last_confirmed":"2021-09-10",
}
]
}
我從上面創建了以下模型:
enum CodingKeys: String, CodingKey {
case fuelStations = "fuel_stations"
case accessCode = "access_code"
case accessDaysTime = "access_days_time"
case accessDetailCode = "access_detail_code"
case cardsAccepted = "cards_accepted"
case dateLastConfirmed = "date_last_confirmed"
}
struct TopLevel: Codable {
let fuelStations: [FuelStation]
}
struct FuelStation: Codable {
let accessCode, accessDaysTime, accessDetailCode, cardsAccepted: String
let dateLastConfirmed: String
let id: String
}
我將初始視圖的簡化版本放在一個檔案中進行測驗:
struct SiteListView: View {
@State private var fuelStations: [FuelStation] = []
@State private var topLevel: TopLevel = TopLevel(fuelStations: [])
var body: some View {
NavigationView {
VStack {
List(fuelStations, id: \.id) { item in
VStack {
Text(item.accessCode)
Text(item.accessDaysTime)
}
}
}
.navigationTitle("Site List View")
.task {
await loadData()
}
}//nav
}
func loadData() async {
//I believe the DEMO_KEY in the url will allow limited retrievals
guard let url = URL(string: "https://developer.nrel.gov/api/alt-fuel-stations/v1.json?api_key=DEMO_KEY") else {
print("Invalid URL")
return
}
do {
let (data, response) = try await URLSession.shared.data(from: url)
guard (response as? HTTPURLResponse)?.statusCode == 200 else { return }
print("response status code is 200")
if let decodedResponse = try? JSONDecoder().decode(TopLevel.self, from: data) {
topLevel = decodedResponse
print("in decoding: topLevel.fuelStations.count is \(topLevel.fuelStations.count)")
//I would iterate through topLevel here and add to the fuelStations
//array but I never get here
}
} catch {
print("Invalid Data")
}
}//load data
}//struct
任何指導將不勝感激。Xcode 13.2.1 iOS 15.2
uj5u.com熱心網友回復:
首先,當像這樣的解碼出現問題時,您應該?從try?捕獲中洗掉
func loadData() async {
//I believe the DEMO_KEY in the url will allow limited retrievals
guard let url = URL(string: "https://developer.nrel.gov/api/alt-fuel-stations/v1.json?api_key=DEMO_KEY") else {
print("Invalid URL")
return
}
do {
let (data, response) = try await URLSession.shared.data(from: url)
guard (response as? HTTPURLResponse)?.statusCode == 200 else { return }
print("response status code is 200")
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let decodedResponse = try decoder.decode(TopLevel.self, from: data)
print("in decoding: topLevel.fuelStations.count is \(decodedResponse.fuelStations.count)")
//I would iterate through topLevel here and add to the fuelStations
//array but I never get here
} catch {
print(error)
}
}
完成這一步之后,你會發現你的一些屬性struct在未來應對空,所以你應該改變string,以string?最終成為
struct TopLevel: Codable {
let fuelStations: [FuelStation]
}
struct FuelStation: Codable {
let accessCode, accessDaysTime, accessDetailCode, cardsAccepted,dateLastConfirmed: String?
let id: Int
}
另外注意使用
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
而不是硬編碼enum
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/412310.html
標籤:
