In iOS 10, if TouchID is used and the user has too many attempts (such as using the wrong finger), the OS locks the...

In iOS 10, if TouchID is used and the user has too many attempts (such as using the wrong finger), the OS locks the user out until they enter their PIN. For applications, this means that the canEvaluatePolicy call on the LAContext class will always return False until the user "unlocks" TouchID with their PIN.

The problem is being able to detect if this is the reason why the call returns False, which can be done only through examining the Code property on the error parameter in the canEvaluatePolicy call. The docs show that the error parameter is an NSErrorPointer:

https://developer.apple.com/reference/localauthentication/lacontext/1514149-canevaluatepolicy

i.e. a pointer to an NSError, so in Delphi I have the method declared like this:

function canEvaluatePolicy(policy: LAPolicy; error: Pointer): Boolean; cdecl;

Except that I'm having trouble with how to access the returned error. Simply dereferencing the parameter doesn't work (which I wouldn't expect it to anyway), however using the Wrap method of TNSError also does not work (the former locks up the app, the latter causes a crash). Some example code:

var
LPointer: Pointer;
LError: NSError;
LCode: Int64;
begin
Result := FContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, LPointer);
if LPointer <> nil then
begin
LError := TNSError.Wrap(LPointer); // PNSError(LPointer)^; // Neither way works
LCode := LError.code;
if LCode <> 0 then
// Take action here
end;
end;

Any ideas on how to solve this?

https://developer.apple.com/reference/localauthentication/lacontext/1514149-canevaluatepolicy

Comments