【问题标题】:Touch Id with Xamarin Forms Application使用 Xamarin Forms 应用程序的 Touch Id
【发布时间】:2018-02-16 16:18:56
【问题描述】:

我们正在尝试使用我们的 Xamarin Forms 应用程序在 iOS 中使用 Touch Id。

在我们的 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;
        }
    }
}

我们从结果变量中得到一个响应(如果用户通过了身份验证,则为真),但它没有被传递回表单应用程序。

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

我们有推荐的方法吗?我们正努力让这一切尽可能简单。

【问题讨论】:

  • Ajam,你可以查看这篇关于它的文章somostechies.com/fingerprint
  • 您好,感谢您的回复,我们正在为我们的代码寻找解决方案,而不是使用插件。
  • 您需要一个 taskcompletionsource,因为您的代码是异步的,但您的编码就像是同步的一样。

标签: c# xamarin xamarin.forms xamarin.ios touch-id


【解决方案1】:

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

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

记得在上面加上 using

using System.Threading.Tasks;

并更改您的接口声明

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

最后是您的 Xamarin.Forms 代码...

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

【讨论】:

  • 您好,由于您提供的函数现在是异步的,我们必须将其移至 onStart() 函数.... protected override async void OnStart()。我们仍然在 iOS 项目的 Main 中收到未处理的异常:Foundation.MonoTouchException: Objective-C exception throwed。名称:NSInternalInconsistencyException 原因:应用程序窗口在应用程序启动结束时应该有一个根视图控制器
【解决方案2】:

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

通过将以下代码从 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(); 
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多