Thread 1: Fatal error: No ObservableObject of type

Thread 1: Fatal error: No ObservableObject of type

视频LinkYoutube

ConsoleError

Fatal error: No ObservableObject of type UserDefaultsConfig found. A View.environmentObject(_:) for UserDefaultsConfig may be missing as an ancestor of this view.: file SwiftUI, line 0

用户默认配置

class UserDefaultsConfig: ObservableObject {
    
    @Published var allFavoriteMovie: [PopularMovie] = []
    let defaults = UserDefaults.standard
    
    func setUserDefaults(value: PopularMovie) {
        let encoder = JSONEncoder()
        if let encoded = try? encoder.encode(value) {
            
            defaults.set(encoded, forKey: "favoriteMovie")
        }
        
        if let savedFavoriteMovie = defaults.object(forKey: "favoriteMovie") as? Data {
            let decoder = JSONDecoder()
            if let loadedFavMovie = try? decoder.decode(PopularMovie.self, from: savedFavoriteMovie) {
                allFavoriteMovie.append(loadedFavMovie)
                print("favMovie: \(allFavoriteMovie)")
            }
        }
    }
}

首先打开 CustomTabView

CustomTabView

TabView(selection: $selectedTab) {
                
       MainView(searchMovie: SearchMovieVM(), mainVM: MainVM())
                .ignoresSafeArea()
                .tag(TabCategory.movieList)
                
       FavoriteView()
                .ignoresSafeArea()
                .tag(TabCategory.favorite)
            }

我在 MainView 中单击 MovieCell 并将其定向到 DetailView。

主视图

        NavigationLink(
            destination: DetailView(movie: .constant(mainVM.popularMovie[movie])),
            label: {
                MovieCell(popularMovie: .constant(mainVM.popularMovie[movie]))
                   .foregroundColor(Color(UIColor.label))
            })

DetailView

当我点击这里的按钮时,userDefaultsConfig 中的 setUserDefaults 函数是 运行。

struct DetailView: View {
    ....
    @StateObject var userDefaultsConfig = UserDefaultsConfig()
    var body: some View {
        ZStack {
            .....
            ScrollView(.vertical, showsIndicators: false) {
                .....
                    
                    HStack {
                        Spacer()
                        Button(action: { self.userDefaultsConfig.setUserDefaults(value: movie) }) {
                            Image(systemName: "suit.heart")
                                .imageScale(.large)
                                .foregroundColor(.red)
                        }
                    }
                    
                   ....
                    
                }
                .padding(.horizontal)
                
            }
        }
        .environmentObject(userDefaultsConfig)
    }
}

保存在DetailView页面UserDefaults中的电影会显示在收藏夹页面,但是打开收藏夹页面时出现错误。

收藏夹视图

struct FavoriteView: View {
    @EnvironmentObject var userDefaultsConfig: UserDefaultsConfig
    var body: some View {
        VStack {
//            ForEach(userDefaultsConfig.allFavoriteMovie, id: \.id) { item in
//                Text(item.title ?? "")
//            }
            Text("")
                .onAppear {
                    print(self.userDefaultsConfig.allFavoriteMovie)
                }
        }
    }
}

你需要在CustomTabView中放置状态对象,比如

struct CustomTabView: View {
    ....
    @StateObject var userDefaultsConfig = UserDefaultsConfig()

    ...

      TabView(selection: $selectedTab) {
                
          MainView(searchMovie: SearchMovieVM(), mainVM: MainVM())
                .ignoresSafeArea()
                .tag(TabCategory.movieList)
                
          FavoriteView()
                .ignoresSafeArea()
                .tag(TabCategory.favorite)
       }
       .environmentObject(userDefaultsConfig)    // << here !!
    ...

并且在 DetailView 中只需将其用作环境对象,就像在 FavoriteView 中一样,即

struct DetailView: View {
    @EnvironmentObject var userDefaultsConfig: UserDefaultsConfig

    ...
}