prod 웹앱(spin.special-partners.com)을 감싸는 네이티브 셸. 화면 개발 없음. - InAppWebView: 쿠키/캐시 영속·UA(spinApp) 태그·풀투리프레시·외부링크 분기·오프라인 화면 - Android 하드웨어 뒤로가기(웹 히스토리→더블탭 종료), navy 스플래시/상태바 - 파일/카메라 업로드 권한(Android/iOS), 생체인증 잠금(local_auth) - FCM 푸시(firebase_messaging) — 설정 전 자동 비활성, 토큰은 웹 세션으로 /api/devices 등록 - prod URL 고정(app_config.dart) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
43 lines
1.1 KiB
Dart
43 lines
1.1 KiB
Dart
import "package:flutter/foundation.dart";
|
|
import "package:local_auth/local_auth.dart";
|
|
import "package:shared_preferences/shared_preferences.dart";
|
|
|
|
/// 생체인증 잠금 설정/검증.
|
|
class LockService {
|
|
LockService._();
|
|
static final LockService instance = LockService._();
|
|
|
|
static const _key = "spin.bioLock";
|
|
final _auth = LocalAuthentication();
|
|
|
|
Future<bool> isEnabled() async {
|
|
final p = await SharedPreferences.getInstance();
|
|
return p.getBool(_key) ?? false;
|
|
}
|
|
|
|
Future<void> setEnabled(bool v) async {
|
|
final p = await SharedPreferences.getInstance();
|
|
await p.setBool(_key, v);
|
|
}
|
|
|
|
Future<bool> canCheck() async {
|
|
try {
|
|
return await _auth.isDeviceSupported() && await _auth.canCheckBiometrics;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<bool> authenticate() async {
|
|
try {
|
|
return await _auth.authenticate(
|
|
localizedReason: "spin 잠금을 해제하려면 인증하세요",
|
|
options: const AuthenticationOptions(stickyAuth: true, biometricOnly: false),
|
|
);
|
|
} catch (e) {
|
|
debugPrint("lock: auth 오류 $e");
|
|
return false;
|
|
}
|
|
}
|
|
}
|