2015-03-26 29 views
16

Tôi hiện đang phát triển ứng dụng iOS cho phép người dùng đăng nhập vào ứng dụng bằng TouchID, nhưng trước hết họ phải thiết lập mật khẩu bên trong ứng dụng trước. Vấn đề là, để hiển thị tùy chọn mật khẩu thiết lập để bật đăng nhập TouchID, tôi cần phát hiện xem thiết bị iOS có hỗ trợ TouchID hay không.Xác định xem thiết bị iOS có hỗ trợ TouchID mà không cài đặt mật mã

Sử dụng LAContext và canEvaluatePolicy (như các câu trả lời ở đây If Device Supports Touch ID), tôi có thể xác định xem thiết bị hiện hỗ trợ TouchID nếu người dùng đã thiết lập mật mã trên thiết bị iOS của họ. Dưới đây là một đoạn mã của tôi (Tôi đang sử dụng Xamarin, vì vậy trong 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; 
} 

Nếu người dùng chưa thiết lập các thiết bị mật mã, các authError sẽ chỉ trả lại "PasscodeNotSet" lỗi bất kể thiết bị có hỗ trợ TouchID hay không.

Nếu thiết bị của người dùng hỗ trợ TouchID, tôi muốn luôn hiển thị tùy chọn TouchID trong ứng dụng của mình bất kể người dùng đã thiết lập mật mã trên thiết bị của họ (trước tiên tôi sẽ cảnh báo người dùng thiết lập mật mã trên thiết bị của họ). Ngược lại, nếu thiết bị của người dùng không hỗ trợ TouchID, tôi rõ ràng không muốn hiển thị tùy chọn TouchID trong ứng dụng của mình. Vì vậy, câu hỏi của tôi là, có một cách hay để xác định liệu thiết bị iOS có hỗ trợ TouchID không phụ thuộc vào việc người dùng đã thiết lập mật mã trên thiết bị của họ hay chưa? Có phải không?

Cách khắc phục duy nhất tôi có thể nghĩ là xác định kiến ​​trúc của thiết bị (được trả lời trong Determine if iOS device is 32- or 64-bit), vì TouchID chỉ được hỗ trợ trên các thiết bị có kiến ​​trúc 64 bit. Tuy nhiên, tôi đang tìm kiếm nếu có bất kỳ cách nào đẹp hơn để làm điều này.

Cảm ơn trước! :)

Trả lời

13

Kết thúc cuộc thảo luận bên dưới, hiện tại không thể xác định liệu thiết bị có thực sự hỗ trợ TouchID hay không khi người dùng không thiết lập mật mã trên thiết bị của họ.

Tôi đã báo cáo lỗi TouchID này trên trình báo cáo lỗi của Apple. Những người muốn làm theo vấn đề này có thể nhìn thấy nó trên mở Radar ở đây: http://www.openradar.me/20342024

Cảm ơn @rckoenes cho đầu vào :)

EDIT

Hóa ra rằng ai đó đã báo cáo một vấn đề tương tự đã (# 18364575).Dưới đây là trả lời của Apple liên quan đến vấn đề này:

"Kỹ thuật đã xác định rằng vấn đề này cư xử như dự định dựa trên các thông tin sau:

Nếu mật mã không được thiết lập, bạn sẽ không thể phát hiện Touch ID hiện diện. Một khi các mật mã được thiết lập, canEvaluatePolicy cuối cùng sẽ trở LAErrorTouchIDNotAvailable hoặc LAErrorTouchIdNotEnrolled và bạn sẽ có khả năng phát hiện cảm ứng hiện diện ID/tiểu bang.

Nếu người dùng có mật mã vô hiệu hóa trên điện thoại với ID Touch, họ biết rằng họ sẽ không thể để sử dụng Touch ID, do đó, các ứng dụng không cần phát hiện sự hiện diện của Touch ID hoặc quảng bá các tính năng dựa trên Touch ID. "

Vì vậy ..... câu trả lời chính thức từ Apple là Không :(

Lưu ý: tương tự như StackOverflow câu hỏi từ người báo cáo này ->iOS8 check if device has Touch ID (tự hỏi tại sao tôi thì không. tìm câu hỏi này trước khi mặc dù tìm kiếm mở rộng của tôi ...)

9

Các cách chính xác để phát hiện nếu TouchID có sẵn:

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

Xin lỗi nó là trong Objective-C, bạn có thể phải dịch nó sang C#.

Bạn nên kiểm tra phiên bản hệ thống và chỉ kiểm tra xem lớp học hoặc phương pháp có sẵn hay không.

+3

Cám ơn câu trả lời của bạn, nhưng tôi sợ nó không phải là giải pháp tôi đang tìm kiếm. Theo tôi biết, lớp LAContext có sẵn trên tất cả các thiết bị chạy iOS8. Nhưng trong trường hợp thiết bị chạy iOS8 nhưng không có TouchID, thì mệnh đề if sẽ là true và NSError sẽ vẫn trả về PasscodeNotSet ... Sửa lỗi nếu tôi nhầm ở đây :) – ABVincita

+0

Có thể có, nhưng ' hasTouchId' sẽ là false vì vậy TouchID không khả dụng cho bạn với tư cách là nhà phát triển để sử dụng. – rckoenes

+0

Có hasTouchId cũng sẽ sai - nhưng sau đó không có cách nào để tôi xác định xem thiết bị có thực sự hỗ trợ TouchID hay không. Như đã nêu trong câu hỏi của tôi ở trên, vấn đề chính ở đây là khi người dùng không thiết lập mật mã trên thiết bị của họ; hasTouchId sẽ là false và NSError sẽ là PasscodeNotSet bất kể thiết bị có hỗ trợ TouchID hay không. – ABVincita

1

Dưới đây là một cách tẻ nhạt chút để tìm hiểu xem thiết bị có cảm biến cảm ứng id vật lý.

+ (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]; 

}

tham khảo: https://www.theiphonewiki.com/wiki/Models https://en.wikipedia.org/wiki/IOS

6

Tôi biết đây là một câu hỏi cách đây một năm, nhưng giải pháp này không làm những gì bạn cần? (Mã Swift)

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

Sau đó, khi người dùng nhấn nút đăng nhập với id liên lạc:

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

Hy vọng nó sẽ giúp!

3

Đối với Objective C
Nó hoạt động tốt trên tất cả các thiết bị mà không kiểm tra phiên bản thiết bị.

- (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; 
    } 
    } 
} 
Các vấn đề liên quan