0

我有 2 个选项卡,关联的视图是 tabAView 和 tabBView。在 tabAView 上,有 1 个 API 调用并获得了用户对象,该对象是其 ViewModel 中的已发布对象。ViewModel 名称是 UserViewModel。tabAView 正在观察 UserViewModel。在 tabBView 上,我必须使用该用户对象。因为在某些操作上,用户对象的值发生了变化,这些变化应该反映在后续视图中。

我对这里的环境对象使用感到困惑。请建议什么是最好的方法。

这是更好地理解我的问题的代码。

struct ContentView: View {
    enum AppPage: Int {
        case TabA=0, TabB=1
    }
    
    @StateObject var settings = Settings()
    var viewModel: UserViewModel
    
    var body: some View {
        NavigationView {
            TabView(selection: $settings.tabItem) {
                TabAView(viewModel: viewModel)
                    .tabItem {
                        Text("TabA")
                    }
                    .tag(AppPage.TabA)
                
                AppsView()
                    .tabItem {
                        Text("Apps")
                    }
                    .tag(AppPage.TabB)
            }
            .accentColor(.white)
            .edgesIgnoringSafeArea(.top)
            .onAppear(perform: {
                settings.tabItem = .TabA
            })
            .navigationBarTitleDisplayMode(.inline)
        }
        .environmentObject(settings)
    }
}

这是 TabAView:

struct TabAView: View {

    @ObservedObject var viewModel: UserViewModel
    @EnvironmentObject var settings: Settings

    init(viewModel: UserViewModel) {
        self.viewModel = viewModel
    }

    var body: some View {
        Vstack {
        /// code
        }
        .onAppear(perform: {
            /// code
        })
        .environmentObject(settings)
    }
}

这是命中 API 和用户对象的 UserViewModel:

class UserViewModel: ObservableObject {
    
    private var apiService = APIService.shared
    @Published var user: EndUserData?

    init () {
        getUserProfile()
    }
    
    func getUserProfile() {
        apiService.getUserAccount() { user in
            DispatchQueue.main.async {
                self.user = user
            }
        }
    }
}

下面是 APIService 函数,其中用户对象被保存到 UserDefaults 中以供使用。我知道这是不正确的。(这就是我寻找另一种解决方案的原因)。隐藏 URL,因为它是机密的。

func getUserAccount(completion: @escaping (EndUserData?) -> Void) {
    self.apiManager.makeRequest(toURL: url, withHttpMethod: .get) { results in
        guard let response = results.response else { return completion(nil) }
        if response.httpStatusCode == 200 {
            guard let data = results.data else { return completion(nil) }
            do {
                let str = String(decoding: data, as: UTF8.self)
                print(str)
                let decoder = JSONDecoder()
                let responseData = try decoder.decode(ResponseData<EndUserData>.self, from: data)
                UserDefaults.standard.set(data, forKey: "Account")
                completion(responseData.data)
            } catch let jsonError as NSError {
                print(jsonError.localizedDescription)
                return completion(nil)
            }
        }
    }
}

这是另一个 TabBView:

struct TabBView: View {
    
    var user: EndUserData?
    
    init() {
        do {
            guard let data = UserDefaults.standard.data(forKey: "Account") else {
                return
            }
            let decoder = JSONDecoder()
            let responseData = try decoder.decode(ResponseData<EndUserData>.self, from: data)
            user = responseData.data
        } catch let jsonError as NSError {
            print(jsonError.localizedDescription)
        }
    }
    var body: some View {
        VStack (spacing: 10) {
            UserSearch()
        }
    }
}

这是 TabBView 中的另一个视图,其中使用了 User 对象。变化没有反映在这里。

结构用户搜索:查看 {

    private var user: EndUserData?
    
    init(comingFromAppsSection: Bool) {
        do {
            guard let data = UserDefaults.standard.data(forKey: "Account") else {
                return
            }
            let decoder = JSONDecoder()
            let responseData = try decoder.decode(ResponseData<EndUserData>.self, from: data)
            user = responseData.data
        } catch let jsonError as NSError {
            print(jsonError.localizedDescription)
        }
    }
    
    var body: some View {
        Vstack {
            Text(user.status)
        }
    }
}

从机密的角度来看,我已经删除了大部分代码,但这段代码将解释原因和错误。请查看代码并帮助我。

4

0 回答 0