1

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

  1. 验证
  2. 主要的

我的身份验证堆栈如下所示:

  1. 启动页面
  2. 选择创建或登录页面
  3. 登录页面

之后我打电话:

CoreMethods.SwitchOutRootNavigation(NavigationContext.Main);

这一切都很好。

当我像这样从主堆栈中调用注销时:

CoreMethods.SwitchOutRootNavigation(NavigationContext.Authentication);

我目前将在“登录页面”上,但我真的希望它成为第一页“启动页面”。

让导航堆栈记住堆栈历史记录对于所有其他情况都是完美的。

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

4

2 回答 2

1

我通常在我的应用程序中执行的操作如下。

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

如果需要完全登录用户,我的意思是显示登录页面 when Stateis 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());
    }

我只是将应用程序的根页面更改为 SignIn 流或 Main 流,具体取决于SessionState. 然后在我的构造函数中,我执行以下操作。

 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();
    }

我在几个应用程序中使用了这种方法,它对我来说非常适合。希望这可以帮助

于 2016-05-26T06:01:12.937 回答
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 的设置插件

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());
}

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

于 2017-07-29T07:41:16.770 回答