【问题标题】:What is the best solution for "reseting" the Authentication stack?“重置”身份验证堆栈的最佳解决方案是什么?
【发布时间】:2016-09-23 20:46:09
【问题描述】:

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

  1. 身份验证
  2. 主要

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

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

然后我打电话:

CoreMethods.SwitchOutRootNavigation(NavigationContext.Main);

这一切都很好。

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

CoreMethods.SwitchOutRootNavigation(NavigationContext.Authentication);

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

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

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

【问题讨论】:

  • 您的启动页面是 xaml/C# 页面还是活动?如果它的活动,那么这将不起作用。

标签: xamarin freshmvvm


【解决方案1】:

我通常在我的应用中做的事情是跟随。

我有IAuthenticationService,它有一个State 属性,可以是LoggedInLoggedOut。当会话状态由于显式登录而改变,或者例如令牌过期时,我将State 设置为LoggedOut。此外,我通过Messenger 发送了一条广播消息SessionStateChanged,因此我可以在应用程序周围捕捉到此消息,并在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 将应用程序的根页面更改为登录流或主流。然后在我的构造函数中执行以下操作。

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

我在几个应用程序中都使用了这种方法,它非常适合我。希望这会有所帮助

【讨论】:

  • 感谢 kyurkchyan,虽然不完全是我所追求的,但确实帮助我找到了一种方法(我们专门使用 FreshMvvm)。
【解决方案2】:

我最近遇到了同样的问题,这就是我所做的:

导航栈:

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

最后是注销命令中的代码:

private void Logout()
{
    Settings.IsUserLoggedIn = false;
    NavigationService.PopToStackRoot(NavigationStacks.Authentication);  
    CoreMethods.SwitchOutRootNavigation(NavigationStacks.Authentication.ToString());
}

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

【讨论】:

    猜你喜欢
    • 2015-03-18
    • 1970-01-01
    • 2010-09-06
    • 2015-03-01
    • 1970-01-01
    • 2015-05-27
    • 2010-12-04
    • 2016-02-23
    • 2010-09-13
    相关资源
    最近更新 更多