私は現在、ユーザーがTouchIDを使用してアプリにログインできるiOSアプリを開発していますが、最初にアプリ内でパスワードを設定する必要があります。問題は、TouchIDログインを有効にするためのセットアップパスワードオプションを表示するには、iOSデバイスがTouchIDをサポートしているかどうかを検出する必要があります。
LAContextとcanEvaluatePolicyを使用して(ここの回答 デバイスがタッチIDをサポートしている場合 )、ユーザーが設定した場合、現在のデバイスがTouchIDをサポートしているかどうかを確認できます iOSデバイスのパスコードをアップします。これが私のコードスニペットです(私はXamarinを使用しているため、C#で使用しています)。
static bool DeviceSupportsTouchID ()
{
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var context = new LAContext();
NSError authError;
bool touchIDSetOnDevice = context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out authError);
return (touchIDSetOnDevice || (LAStatus) Convert.ToInt16(authError.Code) != LAStatus.TouchIDNotAvailable);
}
return false;
}
ユーザーがデバイスのパスコードを設定していない場合、authErrorは "PasscodeNotSet "デバイスが実際にTouchIDをサポートしているかどうかに関係なくエラー。
ユーザーのデバイスがTouchIDをサポートしている場合、ユーザーがデバイスにパスコードを設定したかどうかに関係なく、アプリに常にTouchIDオプションを表示します(最初にデバイスにパスコードを設定するようユーザーに警告します)。逆に、ユーザーのデバイスがTouchIDをサポートしていない場合、アプリにTouchIDオプションを表示したくありません。
だから私の質問は、ユーザーが自分のデバイスにパスコードを設定したかどうかに関係なく、iOSデバイスがTouchIDをサポートしているかどうかを一貫して判断する良い方法はありますか?
TouchIDは64のデバイスでのみサポートされているため、私が考えることができる唯一の回避策は、デバイスのアーキテクチャを決定することです(これは iOSデバイスが32ビットか64ビットかを判断 で回答されます)。ビットアーキテクチャ。しかし、これを行うためのより良い方法があるかどうかを探しています。
以下の議論の結論として、当面は、ユーザーがデバイスにパスコードを設定していない場合、デバイスが実際にTouchIDをサポートしているかどうかを判断することはできません。
このTouchIDの欠陥をAppleバグレポーターに報告しました。この問題を追跡したい人は、Open Radarで確認できます: http://www.openradar.me/ 20342024
入力してくれてありがとう@rckoenes :)
[〜#〜]編集[〜#〜]
誰かがすでに同様の問題を報告していることが判明しました(#18364575)。この問題に関するAppleの回答は次のとおりです。
"エンジニアリングは、この問題が以下の情報に基づいて意図したとおりに動作すると判断しました:
パスコードが設定されていない場合、Touch IDの存在を検出できません。パスコードが設定されると、canEvaluatePolicyは最終的にLAErrorTouchIDNotAvailableまたはLAErrorTouchIdNotEnrolledを返し、Touch IDの存在/状態を検出できるようになります。
Touch IDを備えた電話でパスコードを無効にした場合、ユーザーはTouch IDを使用できないことを知っているため、アプリはTouch IDの存在を検出したり、Touch IDベースの機能を宣伝したりする必要はありません。 「
だから... Appleからの最後の答えはいいえです:)
注:これを報告した人からの同様のStackOverflow質問-> iOS8にデバイスにTouch IDがあるかどうかを確認 (徹底的な検索にもかかわらず、なぜこの質問が以前に見つからなかったのか...)
TouchIDが利用可能かどうかを検出する正しい方法:
BOOL hasTouchID = NO;
// if the LAContext class is available
if ([LAContext class]) {
LAContext *context = [LAContext new];
NSError *error = nil;
hasTouchId = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];
}
Objective-Cで申し訳ありませんが、C#に変換する必要がある場合があります。
システムバージョンの確認は控え、クラスまたはメソッドが使用可能かどうかを確認してください。
私はこれが昨年の質問であることを知っていますが、この解決策はあなたが必要とするものを作りませんか? (スウィフトコード)
if #available(iOS 8.0, *) {
var error: NSError?
let hasTouchID = LAContext().canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error)
//Show the touch id option if the device has touch id hardware feature (even if the passcode is not set or touch id is not enrolled)
if(hasTouchID || (error?.code != LAError.TouchIDNotAvailable.rawValue)) {
touchIDContentView.hidden = false
}
}
次に、ユーザーがボタンを押してtouch idでログインすると、次のようになります。
@IBAction func loginWithTouchId() {
let context = LAContext()
var error: NSError?
let reasonString = "Log in with Touch ID"
if (context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error)) {
[context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success: Bool, evalPolicyError: NSError?) -> Void in
//Has touch id. Treat the success boolean
})]
} else {
//Then, if the user has touch id but is not enrolled or the passcode is not set, show a alert message
switch error!.code{
case LAError.TouchIDNotEnrolled.rawValue:
//Show alert message to inform that touch id is not enrolled
break
case LAError.PasscodeNotSet.rawValue:
//Show alert message to inform that passcode is not set
break
default:
// The LAError.TouchIDNotAvailable case.
// Will not catch here, because if not available, the option will not visible
}
}
}
それが役に立てば幸い!
目的Cの場合
デバイスのバージョンを確認しなくても、すべてのデバイスで問題なく機能します。
- (void)canAuthenticatedByTouchID{
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = touchIDRequestReason;
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
}else{
switch (authError.code) {
case kLAErrorTouchIDNotAvailable:
[labelNotSupportTouchID setHidden:NO];
[switchBtn setHidden:YES];
[labelEnableTouchid setHidden:YES];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self showAlertMessage:@"EyeCheck Pro" message:@"Device does not support Touch ID Service."];
});
break;
}
}
}
これは、デバイスに物理的なタッチIDセンサーがあるかどうかを判断するための少し面倒な方法です。
+ (BOOL)isTouchIDExist {
if(![LAContext class]) //Since this mandotory class is not there, that means there is no physical touch id.
return false;
//Get the current device model name
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *model = malloc(size);
sysctlbyname("hw.machine", model, &size, NULL, 0);
NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
//Devices that does not support touch id
NSArray *deviceModelsWithoutTouchID = [[NSArray alloc]
initWithObjects:
@"iPhone1,1", //iPhone
@"iPhone1,2", //iPhone 3G
@"iPhone2,1", //iPhone 3GS
@"iPhone3,1", //iPhone 4
@"iPhone3,2",
@"iPhone3,3",
@"iPhone4,1", //iPhone 4S
@"iPhone5,1", //iPhone 5
@"iPhone5,2",
@"iPhone5,3", //iPhone 5C
@"iPhone5,4",
@"iPod1,1", //iPod
@"iPod2,1",
@"iPod3,1",
@"iPod4,1",
@"iPod5,1",
@"iPod7,1",
@"iPad1,1", //iPad
@"iPad2,1", //iPad 2
@"iPad2,2",
@"iPad2,3",
@"iPad2,4",// iPad mini 1G
@"iPad2,5",
@"iPad2,5",
@"iPad2,7",
@"iPad3,1", //iPad 3
@"iPad3,2",
@"iPad3,3",
@"iPad3,4", //iPad 4
@"iPad3,5",
@"iPad3,6",
@"iPad4,1", //iPad Air
@"iPad4,2",
@"iPad4,3",
@"iPad4,4", //iPad mini 2
@"iPad4,5",
@"iPad4,6",
@"iPad4,7",
nil];
return ![deviceModelsWithoutTouchID containsObject:deviceModel];
}
リファレンス: https://www.theiphonewiki.com/wiki/Modelshttps://en.wikipedia.org/wiki/IOS
以下は、デバイスでTouch IdまたはFace IDがサポートされているかどうかを確認する方法です
open class LocalAuth: NSObject {
public static let shared = LocalAuth()
private override init() {}
var laContext = LAContext()
func canAuthenticate() -> Bool {
var error: NSError?
let hasTouchId = laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
return hasTouchId
}
func hasTouchId() -> Bool {
if canAuthenticate() && laContext.biometryType == .touchID {
return true
}
return false
}
func hasFaceId() -> Bool {
if canAuthenticate() && laContext.biometryType == .faceID {
return true
}
return false
}
}
そして、以下は上記の共有コードの使用法です
if LocalAuth.shared.hasTouchId() {
print("Has Touch Id")
} else if LocalAuth.shared.hasFaceId() {
print("Has Face Id")
} else {
print("Device does not have Biometric Authentication Method")
}
IOS 11以降の場合はbiometryType: LABiometryType
/LAContext
。その他のAppleドキュメント:
/// Indicates the type of the biometry supported by the device.
///
/// @discussion This property is set only when canEvaluatePolicy succeeds for a biometric policy.
/// The default value is LABiometryTypeNone.
@available(iOS 11.0, *)
open var biometryType: LABiometryType { get }
@available(iOS 11.0, *)
public enum LABiometryType : Int {
/// The device does not support biometry.
@available(iOS 11.2, *)
case none
/// The device does not support biometry.
@available(iOS, introduced: 11.0, deprecated: 11.2, renamed: "LABiometryType.none")
public static var LABiometryNone: LABiometryType { get }
/// The device supports Touch ID.
case touchID
/// The device supports Face ID.
case faceID
}