目前在我的应用程序中,我有两个导航堆栈。
我的身份验证堆栈如下所示:
之后我打电话给:
CoreMethods.SwitchOutRootNavigation(NavigationContext.Main);
一切正常。
当我从主堆栈中调用Logout时,如下所示:
CoreMethods.SwitchOutRootNavigation(NavigationContext.Authentication);
我目前会在“登录页面”,但我真的希望它成为第一页“Splash Page”。
让导航堆栈记住堆栈历史记录非常适合所有其他情况。
问题:“重置”身份验证堆栈的最佳解决方案是什么?
答案 0 :(得分:1)
我通常在我的应用中执行的操作是:
我的IAuthenticationService
具有State
属性,可以是LoggedIn
或LoggedOut
。当会话状态由于显式登录而更改,或者例如令牌过期时,我将State
设置为LoggedOut
。此外,我通过SessionStateChanged
发送广播消息Messenger
,因此我可以在应用程序周围捕获此消息,并在UI级别相应地做出反应,如更改屏幕状态等。
如果需要完全记录用户,我的意思是在State
为LoggedOut
时显示登录页面,这是您的情况,我会执行以下操作。我使用Xamarin.Forms,但如果你使用原生iOS或Android,这种方法会类似。
在我的主App
类(源自Xamarin.Forms.Application
的类)中,我创建了一个方法调用UpdateMainPage
,类似这样的
private async void UpdateMainPage()
{
if (_authService.State == SessionState.LoggedIn)
MainPage = new NavigationPage(new RequestPage());
else
MainPage = new NavigationPage(new SignInPage());
}
我只是根据SessionState
将应用程序的根页面更改为SignIn flow或Main flow。然后在我的构造函数中,我执行以下操作。
public FormsApp()
{
InitializeComponent();
_authService = Mvx.Resolve<IAuthenticationService>();
UpdateMainPage();
var messenger = Mvx.Resolve<IMvxMessenger>();
_sessionStateChangedToken = messenger.Subscribe<SessionStateChangedMessage>(HandleSessionStateChanged);
}
我需要做什么,我需要事先设置主页,然后订阅SessionStateChanged
事件,我触发UpdateMainPage
private void HandleSessionStateChanged(SessionStateChangedMessage sessionStateChangedMessage)
{
UpdateMainPage();
}
我将这种方法用于多个应用程序,它对我来说非常适合。希望这有帮助
答案 1 :(得分:1)
我最近遇到了同样的问题,这就是我所做的:
导航堆栈:
public enum NavigationStacks {Authentication, Main}
在App.xaml.cs中:
//Navigation stack when user is authenticated.
var mainPage = FreshPageModelResolver.ResolvePageModel<MainPageModel>();
var mainNavigation = new FreshNavigationContainer(MainPage, NavigationStacks.Main.ToString());
//Navigation stack for when user is not authenticated.
var splashScreenPage= FreshPageModelResolver.ResolvePageModel<SplashScreenPageModel>();
var authenticationNavigation = new FreshNavigationContainer(splashScreenPage, NavigationStacks.Authentication.ToString());
在这里,您可以利用James Montemagno's Settings Plugin
if (Settings.IsUserLoggedIn)
{
MainPage = mainNavigation;
}
else
{
MainPage = authenticationNavigation;
}
到目前为止,您已经完成了上面的代码。但问题的想法是清除除根页面之外的身份验证堆栈,即启动屏幕:
public static void PopToStackRoot(NavigationStacks navigationStack)
{
switch (navigationStack)
{
case NavigationStacks.Authentication:
{
var mainPage = FreshPageModelResolver.ResolvePageModel<MainPageModel>();
var mainNavigation = new FreshNavigationContainer(MainPage, NavigationStacks.Main.ToString());
break;
}
case NavigationStacks.Main:
{
var splashScreenPage= FreshPageModelResolver.ResolvePageModel<SplashScreenPageModel>();
var authenticationNavigation = new FreshNavigationContainer(splashScreenPage, NavigationStacks.Authentication.ToString());
break;
}
}
}
最后这里是Logout命令中的代码:
private void Logout()
{
Settings.IsUserLoggedIn = false;
NavigationService.PopToStackRoot(NavigationStacks.Authentication);
CoreMethods.SwitchOutRootNavigation(NavigationStacks.Authentication.ToString());
}
我知道可能有更好,更有效的方法。但这对我有用。