diff --git a/CHANGELOG.md b/CHANGELOG.md index 987fdd3..0f63b7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Error messages are localized (English and Japanese). A request that fails without the API's `error_message` shows "Something went wrong while communicating with the server. Please try again later." (`NATIVEAPPTEMPLATE-2001`); developer-only errors (`NATIVEAPPTEMPLATE-1001`, `2002`–`2008`, `4001`–`4004`) show "An unexpected error occurred." The API's `error_message` is shown without the " [Status: nnn]" suffix. Error codes are unchanged; status codes, field names and underlying errors go to the log (`CodedError.debugDescription`) ### Fixed +- A failed sign-in's error message stayed on screen after the next attempt signed in; a new attempt now dismisses it - Debug builds lost the local API when launched other than from Xcode, e.g. from the Home Screen or when iOS relaunched the app after its language was changed in Settings: the endpoint came only from the scheme's environment variables, which only Xcode passes. It now comes from `API.xcconfig` (override it in the gitignored `API.local.xcconfig`) and is built into `Info.plist`; `NATIVEAPPTEMPLATE_API_*` environment variables still win. The scheme no longer sets them ### Added diff --git a/NativeAppTemplate/UI/App Root/SignInEmailAndPasswordViewModel.swift b/NativeAppTemplate/UI/App Root/SignInEmailAndPasswordViewModel.swift index 0cab50a..5f02810 100644 --- a/NativeAppTemplate/UI/App Root/SignInEmailAndPasswordViewModel.swift +++ b/NativeAppTemplate/UI/App Root/SignInEmailAndPasswordViewModel.swift @@ -66,6 +66,10 @@ final class SignInEmailAndPasswordViewModel { let theEmail = email.trimmingCharacters(in: whitespacesAndNewlines) let thePassword = password.trimmingCharacters(in: whitespacesAndNewlines) + // The previous attempt's error no longer applies, and would stay over the + // shops after this attempt signs in + messageBus.dismiss() + do { isLoggingIn = true try await sessionController.login(email: theEmail, password: thePassword) diff --git a/NativeAppTemplateTests/UI/App Root/SignInEmailAndPasswordViewModelTest.swift b/NativeAppTemplateTests/UI/App Root/SignInEmailAndPasswordViewModelTest.swift index 9ec21e0..c950e65 100644 --- a/NativeAppTemplateTests/UI/App Root/SignInEmailAndPasswordViewModelTest.swift +++ b/NativeAppTemplateTests/UI/App Root/SignInEmailAndPasswordViewModelTest.swift @@ -160,6 +160,25 @@ struct SignInEmailAndPasswordViewModelTest { #expect(viewModel.isLoggingIn == false) } + @Test("A new attempt dismisses the previous attempt's error") + func signInDismissesPreviousError() async { + let viewModel = SignInEmailAndPasswordViewModel( + sessionController: sessionController, + messageBus: messageBus + ) + // TestSessionController starts signed in; the wait below must see this sign-in + sessionController.userState = .notLoggedIn + messageBus.post(message: Message(error: NativeAppTemplateAPIError.requestFailed(nil, 401, "Invalid email or password."))) + + viewModel.email = "test@example.com" + viewModel.password = "password123" + viewModel.signIn() + + await waitUntil { sessionController.userState == .loggedIn && !viewModel.isLoggingIn } + + #expect(messageBus.messageVisible == false) + } + @Test func signInError() async { // Simulate an error by setting the sessionController to throw an error