Touch Id 与 Xamarin Forms 应用程序

Touch Id with Xamarin Forms Application

我们正在尝试通过我们的 Xamarin Forms 应用程序将 Touch Id 与 iOS 结合使用。

在我们的 Xamarin Forms 应用程序中,在 App.Xaml.cs 构造函数中,我们使用一个接口来引用 iOS 本机触摸 ID 实现:

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

这是表单应用程序中的接口签名:

public interface ITouchID
{
    bool AuthenticateUserIDWithTouchID();
}

这是iOS项目中接口的实现:

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

我们从结果变量得到响应(如果用户通过身份验证则为真),但不会传回表单应用程序。

我们也尝试过使用异步任务,但没有成功。

有推荐的方法吗?我们正在努力使它尽可能简单。

您需要更改代码以处理异步行为。

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

通过使用上面的异步更改(尽管您可以在不使用异步方法的情况下执行此操作),然后执行以下操作设法使此工作正常进行:

通过将以下代码从 app.xaml.cs 移动到我们的 MainPage.xaml.cs(我们的标签页)构造函数中。

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