Is this a wrong usage of the concept of "error manager"? Is it something in SwiftUI that is not used anymore? On second tab, when I try to show error, on console I get this:
Presenting view controller <SwiftUI.PlatformAlertController: 0x10580c400> from detached view controller <TtGC7SwiftUI19UIHostingControllerVS_14_ViewList_View: 0x10385ee00> is not supported, and may result in incorrect safe area insets and a corrupt root presentation. Make sure <TtGC7SwiftUI19UIHostingControllerVS_14_ViewList_View: 0x10385ee00> is in the view controller hierarchy before presenting from it. Will become a hard exception in a future release.
class ErrorManager: ObservableObject {
static let shared = ErrorManager()
@Published var currentError: TestError?
private init() {}
func handleError(_ error: TestError) {
self.currentError = error
}
}
enum TestError: Error, Identifiable, LocalizedError {
var id: String {localizedDescription}
case genericError
var errorDescription: String? {
switch self {
case .genericError:
return "Generic Error"
}
}
}
import SwiftUI
@main
struct errorManagerInTabViewControlelrAppApp: App {
let classFromEntryPoint = ClassFromEntryPoint()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(ErrorManager.shared)
.environmentObject(classFromEntryPoint)
}
}
}
//*****************************************************
class ClassFromEntryPoint: ObservableObject {
@Published var alertError: TestError?
init() {}
func testThrowsError() throws {
print("func called")
throw TestError.genericError
}
}
//*****************************************************
import SwiftUI
struct ContentView: View {
@State private var selectedTab: Int = 0
var body: some View {
TabView(selection: $selectedTab) {
FirstView(changeTab: self.changeTab)
.tabItem { Label("First", systemImage: "star") }
.tag(0)
SecondView()
.tabItem { Label("Second", systemImage: "star") }
.tag(1)
}
}
func changeTab(to index: Int) {
selectedTab = index
}
}
//*****************************************************
import SwiftUI
struct FirstView: View {
@EnvironmentObject var classFromEntryPoint: ClassFromEntryPoint
@EnvironmentObject var errorManager: ErrorManager
var changeTab: (Int) -> Void
var body: some View {
VStack {
Text("Hello first")
.alert(item: $errorManager.currentError) { error in
Alert(title: Text("Error"), message: Text(error.localizedDescription), dismissButton: .default(Text("OK"), action: {
// do stuff
}))
}
Button("launch the error") {
do {
try self.classFromEntryPoint.testThrowsError()
} catch {
ErrorManager.shared.handleError(error as! TestError)
print("Error triggered: \(error.localizedDescription)")
}
}
}
}
}
//*****************************************************
import SwiftUI
struct SecondView: View {
@EnvironmentObject var classFromEntryPoint: ClassFromEntryPoint
@EnvironmentObject var errorManager: ErrorManager
var body: some View {
VStack {
Text("Hello second")
Button("Test Print") {
do {
try self.classFromEntryPoint.testThrowsError()
} catch {
ErrorManager.shared.handleError(error as! TestError)
print("Error triggered: \(error.localizedDescription)")
}
}
}
}
}
Put the alert on the TabView
or even ContentView
not the FirstView
.