无法从可观察对象中提取数据
Posted
技术标签:
【中文标题】无法从可观察对象中提取数据【英文标题】:Unable to extract data from Observable Object 【发布时间】:2020-01-16 23:51:48 【问题描述】:我正在尝试显示来自观察对象的数据。
最初我试图保持简单,只显示结构的一个成员:'base'(值:“stations”)。
struct Sample: Codable
let coord: Coord
let weather: [Weather]
let base: String
let main: Main
let visibility: Int
let wind: Wind
let clouds: Clouds
let dt: Double
// let sys: Sys
let id: Int
let name: String
// let cod: Int
我用“?”做了一些防御性编码但我得到以下编译器错误:
所以我替换了'?用'!',知道我应该有一些数据。
我发现这令人沮丧,来自命令式范式背景。 我做错了什么?
这是数据转储:
示例(坐标:DataTaskPubTab.Coord(经度:-0.13,纬度:51.51),天气: [DataTaskPubTab.Weather(id: 300, main: "细雨", description: "光 强度毛毛雨")],基地:“车站”,主要: DataTaskPubTab.Main(温度:280.32,压力:1012,湿度:81, tempMin:279.15,tempMax:281.15),能见度:10000,风: DataTaskPubTab.Wind(速度:4.1,度:80),云: DataTaskPubTab.Clouds(all: 90), dt: 1485789600.0, id: 2643743, name: “伦敦”)
这是 Observable 对象:
class StandardWeatherReportLoader: ObservableObject
@Published var networkMessage: String?
@Published var hasAlert = false
@Published var weatherReport: Sample?
@Published var hasReport = false
func doStandard()
let url = EndPoint.weather.path()
var request = URLRequest(url: EndPoint.weather.path()!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: url!) (data: Data?, _: URLResponse?, error: Error?) -> Void in
DispatchQueue.main.async
guard error == nil else
self.networkMessage = error?.localizedDescription
self.hasAlert = true
return
do
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Sample.self, from: data!)
self.weatherReport = result
self.hasReport = true
print(result)
catch let error as NSError
print(error)
task.resume()
【问题讨论】:
【参考方案1】:显然这有效:
struct StandardWeatherView: View
@EnvironmentObject var settings: Settings
@ObservedObject var standardWeatherReportLoader = StandardWeatherReportLoader()
init()
self.standardWeatherReportLoader.doStandard()
var body: some View
NavigationView
ZStack
Color("FernGreen").edgesIgnoringSafeArea(.all)
VStack
if standardWeatherReportLoader.weatherReport?.base == nil
Text("Sorry, NO data.")
else
Text(standardWeatherReportLoader.weatherReport!.base)
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
.navigationBarTitle(Text("Weather Report"), displayMode: .inline)
.alert(isPresented: $standardWeatherReportLoader.hasAlert, content: () -> Alert in
Alert(title: Text(verbatim: standardWeatherReportLoader.networkMessage!))
)
【讨论】:
【参考方案2】:很可能在第一次呈现视图时 Web 服务数据还不可用。所以你不应该用!
强制解开这个值。如果你想在这两种情况下都创建一个Text()
元素,你可以简单地使用??
操作(参见Swift 语言文档中的Nil-Coalescing Operator):
Text(standardWeatherReportLoader.weatherReport?.base ?? "Sorry, NO data.")
【讨论】:
以上是关于无法从可观察对象中提取数据的主要内容,如果未能解决你的问题,请参考以下文章