简体   繁体   中英

Touch Id with Xamarin Forms Application

We are trying to use Touch Id with iOS using our Xamarin Forms application.

In our Xamarin Forms Application, in the App.Xaml.cs constructor we are using an interface to reference the iOS native touch id implementation:

bool _authenticatedWithTouchID = DependencyService.Get<ITouchID>().AuthenticateUserIDWithTouchID();
            if (_authenticatedWithTouchID)
            {
                MainPage = new NavigationPage(new MainPage());
            }
            else
            {
                MainPage = new NavigationPage(new LoginPage());
            }

This is the interface signature within Forms Application:

public interface ITouchID
{
    bool AuthenticateUserIDWithTouchID();
}

This is the implementation of the interface within the iOS project:

[assembly: Dependency(typeof(TouchID))]
namespace GetIn.iOS
{
public class TouchID : ITouchID
{
        public bool AuthenticateUserIDWithTouchID()
        {
            bool outcome = false;

            var context = new LAContext();
            if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out NSError AuthError))
            {
                var replyHandler = new LAContextReplyHandler((success, error) => {

                    Device.BeginInvokeOnMainThread(() => {
                        if (success)
                        {
                            outcome = true;
                        }
                        else
                        {
                            outcome = false;
                        }
                    });

                });
                context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "Logging with touch ID", replyHandler);
            };
            return outcome;
        }
    }
}

We get a response from the outcome variable (which is true if user is authenticated) but that is not being passed back to the forms application.

We have also tried using async tasks with no luck.

Is there a recommended way we do this? We are trying to keep this as simple as possible.

You need to change your code to handle asynchronous behavior.

public class TouchID : ITouchID
{
    public Task<bool> AuthenticateUserIDWithTouchID()
    {
        var taskSource = new TaskCompletionSource<bool>();            

        var context = new LAContext();
        if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out NSError AuthError))
        {
            var replyHandler = new LAContextReplyHandler((success, error) => {

                taskSource.SetResult(success);                    

            });
            context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "Logging with touch ID", replyHandler);
        };

        return taskSource.Task;
    }
}

Remember add the using on top

using System.Threading.Tasks;

And change your interface declaration

public interface ITouchID
{
    Task<bool> AuthenticateUserIDWithTouchID();
}

And finally your Xamarin.Forms code...

 var touchId = DependencyService.Get<ITouchID>();
 var _authenticatedWithTouchID = await touchId.AuthenticateUserIDWithTouchID();
 if (_authenticatedWithTouchID)
 {
   MainPage = new NavigationPage(new MainPage());
 }
 else
 {
   MainPage = new NavigationPage(new LoginPage());
 }

Managed to get this working by using the async changes above (although you can do this without using the async method), and then doing the following:

By moving and adapting the following code from the app.xaml.cs to our MainPage.xaml.cs (our tabbed page) constructor.

var touchId = DependencyService.Get<ITouchID>();
var _authenticatedWithTouchID = await 
touchId.AuthenticateUserIDWithTouchID();
 if (_authenticatedWithTouchID)
 {
  //Do Nothing as on this page
 }
 else
 {
  //Go back to login page
    Navigation.InsertPageBefore(new LoginPage(), this);
    await Navigation.PopAsync(); 
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM