缺少视图的祖先视图

时间:2020-05-11 16:12:29

标签: swift observable swiftui swift5 observableobject

我有一个login.swift,主要是:

import SwiftUI

class GlobalEnvironment: ObservableObject {

    @Published var accountId: Int = 0
}

struct Login: View {

    @EnvironmentObject var env: GlobalEnvironment

    @State private var username: String = ""
    @State private var password: String = ""

    @State var authenticationDdidFail: Bool = false
    @State var authenticationDidSucceed: Bool = false

    var body: some View {

        if env.accountId == 0 {
            return AnyView(LoginView(username: self.$username, password: self.$password, authenticationDdidFail: self.$authenticationDdidFail, authenticationDidSucceed: self.$authenticationDidSucceed))
        } else {
            return AnyView(ContentView().environmentObject(GlobalEnvironment()))
        }


    }
}
...

在LoginView中成功登录后,文件也会设置env.accontId

然后我有一个data.swit,其中:

struct Transaction: Codable, Identifiable {
    let id = UUID()
    var purpose: String
}

class Api {

    @EnvironmentObject var env: GlobalEnvironment

    func getTransactions(completion: @escaping ([Transaction]) -> ()) {

        guard let url = URL(string: "https://url.com/api.php?get_transactions&account=\(env.accountId)") else { return }

        URLSession.shared.dataTask(with: url) { (data, _, _) in
            let transactions = try! JSONDecoder().decode([Transaction].self, from: data!)
            DispatchQueue.main.async {
                completion(transactions)
            }

        }
        .resume()

}

Transactions.swift调用API:

import SwiftUI

struct ContentView: View {

    @EnvironmentObject var env: GlobalEnvironment

    @State var transactions: [Transaction] = []

    var body: some View {
        NavigationView {
            List(transactions) { transaction in
                Text(transaction.purpose)

                }
            .environmentObject(GlobalEnvironment())
            .onAppear {
                Api().getTransactions { (transactions) in
                    self.transactions = transactions
                }
            }
            .navigationBarTitle(Text("Transactions"))
        }
    }
}

我收到Thread 1: Fatal error: No ObservableObject of type GlobalEnvironment found. A View.environmentObject(_:) for GlobalEnvironment may be missing as an ancestor of this view.的错误guard let url = URL(string: "https://url.com/api.php?get_transactions&account=\(env.accountId)") else { return }

根据我的理解,将GlobalEnvironment添加到Api类中应该可以,但是不能。相反,我已经尝试将其添加到函数中,但是它都不起作用。如您所见,与将.environmentObject()添加到列表视图本身相同。

2 个答案:

答案 0 :(得分:0)

必须为:

  .environmentObject(self.env)

当然,在SceneDelegate或其他地方可能还会有其他错误。

答案 1 :(得分:0)

您能否在environmentObject的通话中发送onAppear

.onAppear 
{
    Api().getTransactions { (transactions) in
        self.transactions = transactions
    }.environmentObject(self.env)
}