我有 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)
}
}
}
从机密的角度来看,我已经删除了大部分代码,但这段代码将解释原因和错误。请查看代码并帮助我。