如何在 SwiftUI 中启动应用程序时使用用户当前位置调用 API?

How can I call an API with user's current location on app launch in SwiftUI?

我正在尝试在应用启动时使用用户的当前位置调用 API。我当前的代码是:

ContentView.swift:

struct ContentView: View {
    
    @StateObject var locationManager = LocationManager()
    
    var userLocation: String {
        let latitude = "\(locationManager.lastLocation?.coordinate.latitude ?? 0)"
        let longitude = "\(locationManager.lastLocation?.coordinate.longitude ?? 0)"
        return "\(latitude),\(longitude)"
    }
    
    @ObservedObject var api = randomAPI(location: userLocation)

    var body: some View {
        ...

randomAPI.swift:

class randomAPI: ObservableObject {
    
    init(location: String) {
        callAPI(userLocation: location)
    }
    
    func callAPI(userLocation: String) {
        ...

我收到错误消息:
不能在 属性 初始化程序中使用实例成员 'userLocation'; 属性 初始值设定项 运行 在 'self' 可用之前。

我不知道应该把下面这行代码放在哪里来初始化随机数API。 (我什至不知道这是否是正确的初始化方法 LOL)

@ObservedObject var api = randomAPI(location: userLocation)

有人可以帮我解决这个问题吗?谢谢!

Joakim所述,您需要使用.onAppear。这是因为在结构中设置 属性 之前,您无法访问它。

对于您的情况,代码如下所示:

struct ContentView: View {
    
    @StateObject var locationManager = LocationManager()
    
    var userLocation: String {
        let latitude = "\(locationManager.lastLocation?.coordinate.latitude ?? 0)"
        let longitude = "\(locationManager.lastLocation?.coordinate.longitude ?? 0)"
        return "\(latitude),\(longitude)"
    }
    
    @ObservedObject var api: randomAPI?

    var body: some View {
        SomeView()
            .onAppear {
                api = randomAPI(location: userLocation)
            }
...

但是,我不认为在视图出现后立即设置 ObservedObject 是执行此操作的最佳方法。

如果我是你,我会删除 rapidAPI class:

中的 init 方法
class randomAPI: ObservableObject {
    func callAPI(userLocation: String) {
        ...

并在视图出现时调用callAPI方法:

struct ContentView: View {
    
    @StateObject var locationManager = LocationManager()
    
    var userLocation: String {
        let latitude = "\(locationManager.lastLocation?.coordinate.latitude ?? 0)"
        let longitude = "\(locationManager.lastLocation?.coordinate.longitude ?? 0)"
        return "\(latitude),\(longitude)"
    }
    
    @ObservedObject var api = randomAPI()

    var body: some View {
        SomeView()
            .onAppear {
                api.callAPI(location: userLocation)
            }
...