“重置”身份验证堆栈的最佳解决方案是什么?

时间:2016-05-26 02:59:13

标签: xamarin freshmvvm

目前在我的应用程序中,我有两个导航堆栈。

  1. 验证
  2. 主要
  3. 我的身份验证堆栈如下所示:

    1. Splash Page
    2. 选择创建或登录页面
    3. 登录页面
    4. 之后我打电话给:

      CoreMethods.SwitchOutRootNavigation(NavigationContext.Main);

      一切正常。

      当我从主堆栈中调用Logout时,如下所示:

      CoreMethods.SwitchOutRootNavigation(NavigationContext.Authentication);

      我目前会在“登录页面”,但我真的希望它成为第一页“Splash Page”。

      让导航堆栈记住堆栈历史记录非常适合所有其他情况。

      问题:“重置”身份验证堆栈的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:1)

我通常在我的应用中执行的操作是:

我的IAuthenticationService具有State属性,可以是LoggedInLoggedOut。当会话状态由于显式登录而更改,或者例如令牌过期时,我将State设置为LoggedOut。此外,我通过SessionStateChanged发送广播消息Messenger,因此我可以在应用程序周围捕获此消息,并在UI级别相应地做出反应,如更改屏幕状态等。

如果需要完全记录用户,我的意思是在StateLoggedOut时显示登录页面,这是您的情况,我会执行以下操作。我使用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());
}

我知道可能有更好,更有效的方法。但这对我有用。

相关问题