I have one application in which i am making api call, in this application i want to display error if API does not return the response. When i navigate first time to the screen, it displays alert message, but when i go back to previous screen and again navigate back to same screen. alert is not displayed.
struct DashboardView: View {
@ObservedObject var viewModel = DashboardViewModel()
@State private var showingAlert = true
init() {
UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: UIColor.black]
self.showingAlert = true
}
var body: some View {
ZStack {
Color.white
if case .LOADING = viewModel.currentState {
loaderView()
.onAppear(perform: viewModel.getDashboardData)
} else if case .SUCCESS(let dashboard) = viewModel.currentState {
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .leading, spacing: 10) {
HStack {
Text("Date:")
.foregroundColor(Color.black)
Text(dashboard.date)
.foregroundColor(Color.black)
}
VStack(alignment: .leading) {
Text("HDURL:")
.foregroundColor(Color.black)
Text(dashboard.hdurl)
.foregroundColor(Color.black)
}
HStack {
Text("Media Type:")
.foregroundColor(Color.black)
Text(dashboard.mediaType)
.foregroundColor(Color.black)
}
HStack {
Text("Service Version:")
.foregroundColor(Color.black)
Text(dashboard.serviceVersion)
.foregroundColor(Color.black)
}
VStack(alignment: .leading) {
Text("Title:")
.foregroundColor(Color.black)
Text(dashboard.title)
.foregroundColor(Color.black)
}
VStack(alignment: .leading) {
Text("url:")
.foregroundColor(Color.black)
Text(dashboard.url)
.foregroundColor(Color.black)
}
VStack(alignment: .leading) {
Text("Explanation:")
.foregroundColor(Color.black)
Text(dashboard.explanation)
.foregroundColor(Color.black)
}
}
.padding(.horizontal, 10)
.padding(.top, UIApplication.shared.keyWindow!.safeAreaInsets.top )
}
.padding(.top, UIApplication.shared.keyWindow!.safeAreaInsets.top )
} else if case .FAILURE(let error) = viewModel.currentState {
VStack {
Text("No Data")
.foregroundColor(Color.black)
}
}
}
.navigationBarTitle("Dashboard", displayMode: .inline)
.alert(item: $viewModel.appError) { appAlert in
Alert(title: Text("Error"),
message: Text("""
\(appAlert.errorString)
Please try again later!
"""
)
)
}
.ignoresSafeArea(.all)
}
}
enum ViewStateDashboard { case START case LOADING case SUCCESS(dashboardModel: Dashboard) case FAILURE(error: String) }
protocol FetchDashboardDataFromServer { func getDashboardData() var currentState: ViewStateDashboard { get set } }
class DashboardViewModel: ObservableObject, FetchDashboardDataFromServer {
struct AppError: Identifiable {
let id = UUID().uuidString
let errorString: String
}
@Published var appError: AppError?
let monitor = NWPathMonitor()
let monitorPostUser = NWPathMonitor()
let queue = DispatchQueue(label: "InternetConnectionMonitor")
var cancelable: Set<AnyCancellable> = []
@Published var currentState: ViewStateDashboard = .START
init() {
self.currentState = .LOADING
}
// GET Method
func getDashboardData() {
print("fetch dashboard data")
self.currentState = .LOADING
monitor.pathUpdateHandler = { pathUpdateHandler in
if pathUpdateHandler.status == .satisfied {
APIClient.dispatch(
APIRouter.GetDashboardData(queryParams:
APIParameters.GetDasbhboardParams(apikey: "API_KEY")))
.sink { completion in
switch completion {
case .finished:
print("Execution Finihsed dashboard.")
case .failure(let error):
DispatchQueue.main.async {
print("dashboard error", error)
self.appError = AppError(errorString: error.localizedDescription)
self.currentState = .FAILURE(error: error.localizedDescription)
}
}
}
receiveValue: { dashboardData in
print("received dashboard data", dashboardData)
self.currentState = .SUCCESS(dashboardModel: dashboardData)
}.store(in: &self.cancelable)
} else {
DispatchQueue.main.async {
self.currentState = .FAILURE(error: StringConstants.NoInterNet)
self.appError = AppError(errorString: StringConstants.NoInterNet)
print("no internet get users")
}
}
}
monitor.start(queue: queue)
}
}
What could be the issue here? Any help would be appreciated.
When you close the alert,
viewModel.appErroris set tonil. If you want it to appear again, you must set it to a value again.