生物辨識使用local_auth
<key>NSFaceIDUsageDescription</key>
<string>Why is my app authenticating using face id?</string>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<manifest>
都是透過LocalAuthentication()
這個實例
canEvaluatePolicy☘️☘️☘️
Future<void> _checkBiometrics() async {
bool canCheckBiometrics;
canCheckBiometrics = await _localAuth.canCheckBiometrics;
if (!mounted) return;
setState(() {
_canEvaluatePolicy = canCheckBiometrics ? "是" : "否";
});
}
LABiometryType☘️☘️☘️
注意一下 這邊是回傳一個陣列 不是某個類型⚠️⚠️⚠️
所以代表Andorid好像有裝置可以同時支援(難保以後iPhone不會)
Future<void> _getAvailableBiometrics() async {
List<BiometricType> availableBiometrics;
availableBiometrics = await _localAuth.getAvailableBiometrics();
if (!mounted) return;
setState(() {
if (availableBiometrics.isEmpty) {
_biometryType = noEnrolledWording;
} else {
switch (availableBiometrics.first) {
case BiometricType.face:
_biometryType = "點我驗證Face ID";
break;
case BiometricType.fingerprint:
_biometryType = "點我驗證Touch ID";
break;
default:
_biometryType = noEnrolledWording;
break;
}
}
});
}
evaluatePolicy☘️☘️☘️
Future<void> _authenticate() async {
print("驗證中");
bool authenticated = false;
try {
authenticated = await _localAuth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to authenticate',
stickyAuth: true,
useErrorDialogs: true,
iOSAuthStrings: IOSAuthMessages(
lockOut: "鎖",
goToSettingsButton: "設定",
goToSettingsDescription: "請設定",
cancelButton: "算了"
)
);
} on PlatformException catch (e) {
print("例外");
print(e);
}
if (!mounted) return;
final result = authenticated ? "驗證成功" : "驗證失敗";
scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(result)));
}
上面第2節中的三個function中可以看到
官方用了個小技巧mounted
來判斷await是否回來了
如果是Android的話
可以透過_localAuth.stopAuthentication()
來中斷驗證
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_auth/auth_strings.dart';
import 'package:local_auth/local_auth.dart';
class LessonPageLocalAuthentication extends StatefulWidget {
@override
_LessonPageLocalAuthenticationState createState() => _LessonPageLocalAuthenticationState();
}
class _LessonPageLocalAuthenticationState extends State<LessonPageLocalAuthentication> {
final noEnrolledWording = "未啟用生物辨識";
final scaffoldKey = GlobalKey<ScaffoldState>();
final LocalAuthentication _localAuth = LocalAuthentication();
String _canEvaluatePolicy = "";
String _biometryType = "";
Future<void> _checkBiometrics() async {
bool canCheckBiometrics;
canCheckBiometrics = await _localAuth.canCheckBiometrics;
if (!mounted) return;
setState(() {
_canEvaluatePolicy = canCheckBiometrics ? "是" : "否";
});
}
Future<void> _getAvailableBiometrics() async {
List<BiometricType> availableBiometrics;
availableBiometrics = await _localAuth.getAvailableBiometrics();
if (!mounted) return;
setState(() {
if (availableBiometrics.isEmpty) {
_biometryType = noEnrolledWording;
} else {
switch (availableBiometrics.first) {
case BiometricType.face:
_biometryType = "點我驗證Face ID";
break;
case BiometricType.fingerprint:
_biometryType = "點我驗證Touch ID";
break;
default:
_biometryType = noEnrolledWording;
break;
}
}
});
}
Future<void> _authenticate() async {
print("驗證中");
bool authenticated = false;
try {
authenticated = await _localAuth.authenticateWithBiometrics(
localizedReason: 'Scan your fingerprint to authenticate',
stickyAuth: true,
useErrorDialogs: true,
iOSAuthStrings: IOSAuthMessages(
lockOut: "鎖",
goToSettingsButton: "設定",
goToSettingsDescription: "請設定",
cancelButton: "算了"
)
);
} on PlatformException catch (e) {
print("例外");
print(e);
}
if (!mounted) return;
final result = authenticated ? "驗證成功" : "驗證失敗";
scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(result)));
}
@override
void initState() {
super.initState();
_checkBiometrics();
_getAvailableBiometrics();
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
appBar: AppBar(
title: Text("Local Authentication"),
),
body: Container(
alignment: Alignment.center,
child: Column(
children: [
SizedBox(height: 100),
Text("您的裝置是否支援生物辨識:$_canEvaluatePolicy"),
OutlineButton(
child: Text(_biometryType),
onPressed: _biometryType == noEnrolledWording ? null : _authenticate
// onPressed: _authenticate
)
],
)
)
);
}
}
本集內容Android版請見:iOS Developer Learning Android. Lesson 21
下集預告:Map
最後提供一下github.com/mark33699/IDLF