Переход от PageRenderer к платформе (UWP) и обратно на страницу PCL

  • У меня есть MainPage в PCL, которая затем переходит на страницу входа для конкретной платформы на событии ClickButton Click
  • Login Page наследуется от PageRenderer для конкретной платформы, так как ему требуется аутентификация для конкретной платформы для социальных провайдеров (Facebook, Google, Twitter, Microsoft и т. Д.)
  • Я использую Xamarin.Auth для аутентификации.
  • Внутри события OnElementChanged объекта Login Page он создает объект OAuth2Authenticator.
  • После успешного создания экземпляра (на основе сведений о поставщике и приложении) необходимо вызвать пользовательский интерфейс определенного поставщика.
  • Для этого я вызываю auth.GetUI, где auth - объект Xamarin.Auth.OAuth2Authenticator.

У меня есть два вопроса:

  1. В UWP как перейти к интерфейсу входа для провайдера? В частности, что эквивалентно в UWP следующих фрагментов кода в iOS и Android? В iOS используется следующий код: PresentViewController(auth.GetUI(), true, null); где auth - объект Xamarin.Auth.OAuth2Authenticator. В Android используется следующее: activity.StartActivity(auth.GetUI(activity));

Я ищу эквивалентный код в UWP. Пожалуйста, имейте в виду, что эти вызовы сделаны из Login Page, который получен из специфичного для платформы PageRenderer

  1. Как мне вернуться к моей главной странице (которая находится в PCL) после успешной аутентификации?

Код основан на образце из следующего источника: http://www.c-sharpcorner.com/article/oauth-login-authenticating-with-identity-provider-in-xamarin-forms/

Вот мой код для LoginPage:

using System;
using Valufy;
using Xamarin.Forms.Platform.UWP;
using System.ComponentModel;
using Valufy.UWP;
using Valufy.AuthConfiguration;
using Xamarin.Forms;
[assembly: ExportRenderer(typeof(ProviderLoginPage), typeof(LoginRenderer))]

namespace Valufy.UWP
{
class LoginRenderer: PageRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.Page> e)
{
    base.OnElementChanged(e);

    //Get and Assign ProviderName from ProviderLoginPage
    ProviderLoginPage loginPage = (ProviderLoginPage)Element;
    string providername = loginPage.ProviderName;

        //Create OauthProviderSetting class with Oauth Implementation .Refer Step 6
        OAuthProviderSetting oauth = new OAuthProviderSetting();

            Xamarin.Auth.OAuth2Authenticator auth = oauth.LoginWithProvider(providername);  

            // After facebook,google and all identity provider login completed 
            auth.Completed += Auth_Completed;

            Type page_type = auth.GetUI();
//////THIS IS WHERE I AM STUCK...HOW DO I GO TO THE PROVIDER AUTH UI ////////////

//this.Frame.Navigate(page_type, auth);
//parentPage.Navigation.PushModalAsync(auth.GetUI());

            }

    }

    private void Auth_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
    {
        if (e.IsAuthenticated)
        {
            OAuthConfig.User = new UserDetails();
            // Get and Save User Details 
            OAuthConfig.User.Token = e.Account.Properties["oauth_token"];
            OAuthConfig.User.TokenSecret = e.Account.Properties["oauth_token_secret"];
            OAuthConfig.User.TwitterId = e.Account.Properties["user_id"];
        OAuthConfig.User.ScreenName = e.Account.Properties["screen_name"];

/////NOW, HOW GO I GO BACK TO THE CALLING PAGE IN PCL ///////////////////

    }
    else
    {
        // The user cancelled
/////NOW, HOW GO I GO BACK TO THE CALLING PAGE IN PCL ///////////////////
}
}
}
}                

2 ответа

Решение

Вот код для перехода к логину провайдера для UWP: WindowsPage windowsPage = new WindowsPage();

                _frame = windowsPage.Frame;
                if (_frame == null)
                {
                    _frame = new Windows.UI.Xaml.Controls.Frame
                    {
                        Language = global::Windows.Globalization.ApplicationLanguages.Languages[0]
                    };
                    windowsPage.Content = _frame;
                    SetNativeControl(windowsPage);
                }

                Type pageType = auth.GetUI();
                _frame.Navigate(pageType, auth);

Чтобы вернуться на мою страницу после успешной аутентификации, вот код:

private async void Auth_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
    {
        if (e.IsAuthenticated)
        {

            var request = new OAuth2Request("GET", new Uri("https://login.microsoftonline.com/common/oauth2/V2.0/token?oauth2_access_token=" + e.Account.Properties["access_token"]), null, e.Account);
            try
            {
                string response = await MSGetUserInfo(e.Account);


            }
            catch (System.OperationCanceledException)
            {
                                }
            catch (Exception ex)
            {
                                }
            this.Element.Navigation.PushModalAsync(new MainPage());


        }
        else
        {
            // The user cancelled
        }
    }

1- В UWP как перейти к интерфейсу входа провайдера

Вам нужно создать объект страницы UWP, тот же объект, который вы будете использовать для отображения в рендере, тот, который вы будете использовать для навигации.

Type page_type = auth.GetUI();

page = new MyUWPLoginPage();

page.Frame.Navigate(page_type, auth);

2- Как мне вернуться к моей главной странице (которая находится в PCL) после успешной аутентификации?

Есть много способов сделать это, самый простой - создать публичный метод в вашем ProviderLoginPage class и из классов рендерера вызывают этот метод и передают параметры.

public class ProviderLoginPage: ContentPage
{
    ......

    public void AuthenticationCompleted(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
    {
        // Do your logic
    }

}

В вашем Renderer, используя элемент:

private void Auth_Completed(object sender, Xamarin.Auth.AuthenticatorCompletedEventArgs e)
{
    var xamElement = Element as ProviderLogin;

    xamElement?.AuthenticationCompleted(sender, e);
}

Переместите всю логику в класс PCL, чтобы вам не приходилось повторять ее для каждого рендера.

Это должно помочь.

Другие вопросы по тегам