在初始化中等待功能初始化的初始化函数

时间:2020-03-31 20:57:37

标签: ios swift class swiftui combine

我有一个Observable Object类,用于存储我的应用的预测对象

该类如下:

final class ForecastData: ObservableObject {
    @Published var forecast: DarkSkyResponse

    public func getForecast(at location: CLLocation) {
        let request = DarkSkyRequest(key: "KEYGOESHERE")
        let point = DarkSkyRequest.Point(location.coordinate.latitude, location.coordinate.longitude)

        guard let url = request.buildURL(point: point) else {
            //Handle this better
            preconditionFailure("Failed to construct URL")
        }

        let task = URLSession.shared.dataTask(with: url) {
            data, response, error in

            DispatchQueue.main.async {
                guard let data = data else {
                    //Handle this better
                    fatalError("No Data Recieved")
                }
                guard let forecast = DarkSkyResponse(data: data) else {
                    //Handle this better
                    fatalError("Decoding Failed")
                }
                self.forecast = forecast
            }
        }
        task.resume()
    }

    init() {
        self.getForecast(at: CLLocation(latitude: 37.334987, longitude: -122.009066))
    }
}

第一部分只是生成一个URL来访问API。然后,我启动一个URLSession,该文件下载数据,然后将其解析为DarkSkyResponse对象。最后,我将@Published变量设置为预测对象。

我的问题是,当我在初始化程序中调用该函数时,由于未初始化Forecast属性,因此出现错误。解决此问题的最佳方法是什么?我应该在哪里调用该函数? 顺便说一下,我正在使用@ObservedObject属性包装器在我的SwiftUI视图中使用该类

2 个答案:

答案 0 :(得分:1)

案例1:使用可选(您需要在View中处理)

 @Rule
    TemporaryFolder testProjectDir = new TemporaryFolder()
    File tempFile
    tempFile = testProjectDir.newFile('tempFile')
    buildFile = testProjectDir.newFile('build.gradle')

    buildFile << """
             plugins {
                id 'java'
               }
   """
def "should add test Resources into build/resources/test"(){
        when:
        def result = GradleRunner.create().withProjectDir(testProjectDir.root).withPluginClasspath().withArguments('processTestResources').withDebug(true).build()
        then:
        result.task(":processTestResources").outcome == TaskOutcome.SUCCESS
        and:
        Files.exists(Paths.get("${testProjectDir.root.path}/build/resources/test/tempFile"))
    }

案例2:使用一些默认实例

@Published var forecast: DarkSkyResponse?

两个变体都是等效的并且可以接受,因此仅根据您的喜好。

答案 1 :(得分:0)

尝试此更改:

@Published var forecast: DarkSkyResponse!

init() {
    super.init()
    self.getForecast(at: CLLocation(latitude: 37.334987, longitude: -122.009066))
}