...
This commit is contained in:
@@ -21,10 +21,8 @@ class UserSession {
|
||||
|
||||
// 앱-고유 ID와 사용자 이름, 레벨 진행 상황을 관리하는 서비스
|
||||
class IdentityService {
|
||||
// --- (모든 키 이름은 동일하게 유지) ---
|
||||
static const String _userIdKey = 'app_user_id';
|
||||
static const String _userNameKey = 'app_user_name';
|
||||
// 🔽 [신규] 로그인 상태 저장을 위한 키
|
||||
static const String _loginProviderKey = 'app_login_provider';
|
||||
static const String _userEmailKey = 'app_user_email';
|
||||
|
||||
@@ -33,9 +31,12 @@ class IdentityService {
|
||||
static const String _spiderMaxLevelKey = 'max_unlocked_spider_level';
|
||||
static const String _spiderRankMapKey = 'last_checked_spider_rank_map';
|
||||
|
||||
// 🔽 [신규] 수학 퀴즈 전용 키
|
||||
static const String _mathQuizMaxLevelKey = 'max_unlocked_mathquiz_level';
|
||||
static const String _mathQuizRankMapKey = 'last_checked_mathquiz_rank_map';
|
||||
|
||||
final _storage = const FlutterSecureStorage();
|
||||
|
||||
/// 🔽 [신규] iOS 앱 간 데이터 공유를 위한 옵션
|
||||
IOSOptions _getIOSOptions() => const IOSOptions(
|
||||
// 🔽 [수정] Xcode 설정 전까지 'groupId'를 주석 처리하여 크래시 방지
|
||||
// groupId: 'group.com.lunaticbum.mygamecenter',
|
||||
@@ -45,9 +46,9 @@ class IdentityService {
|
||||
encryptedSharedPreferences: true,
|
||||
);
|
||||
|
||||
// 🔽 [신규] 1. 현재 세션 정보를 '객체'로 가져오기
|
||||
// 1. 현재 세션 정보를 '객체'로 가져오기
|
||||
Future<UserSession> getUserSession() async {
|
||||
final userId = await getOrCreateUserId(); // 게스트 ID는 항상 보장
|
||||
final userId = await getOrCreateUserId();
|
||||
final userName = await getSavedUserName();
|
||||
final loginProvider = await _storage.read(
|
||||
key: _loginProviderKey,
|
||||
@@ -107,12 +108,12 @@ class IdentityService {
|
||||
);
|
||||
}
|
||||
|
||||
// 🔽 [신규] 5. 소셜 로그인 성공 시 호출 (계정 연결)
|
||||
// 5. 소셜 로그인 성공 시 호출 (계정 연결)
|
||||
Future<UserSession> saveSocialLogin({
|
||||
required String newUserId, // 서버가 발급한 마스터 계정 ID
|
||||
required String newUserId,
|
||||
required String newUserName,
|
||||
required String newEmail,
|
||||
required String provider, // "google" 또는 "apple"
|
||||
required String provider,
|
||||
}) async {
|
||||
await _storage.write(key: _userIdKey, value: newUserId, iOptions: _getIOSOptions(), aOptions: _getAndroidOptions());
|
||||
await _storage.write(key: _userNameKey, value: newUserName, iOptions: _getIOSOptions(), aOptions: _getAndroidOptions());
|
||||
@@ -127,9 +128,8 @@ class IdentityService {
|
||||
);
|
||||
}
|
||||
|
||||
// 🔽 [신규] 6. 로그아웃 (게스트 계정으로 되돌리기)
|
||||
// 6. 로그아웃 (게스트 계정으로 되돌리기)
|
||||
Future<UserSession> logout() async {
|
||||
// 소셜 로그인 정보만 삭제
|
||||
await _storage.delete(key: _userNameKey, iOptions: _getIOSOptions(), aOptions: _getAndroidOptions());
|
||||
await _storage.delete(key: _userEmailKey, iOptions: _getIOSOptions(), aOptions: _getAndroidOptions());
|
||||
await _storage.delete(key: _loginProviderKey, iOptions: _getIOSOptions(), aOptions: _getAndroidOptions());
|
||||
@@ -137,20 +137,40 @@ class IdentityService {
|
||||
return await getUserSession();
|
||||
}
|
||||
|
||||
// 7. 최대 레벨 가져오기
|
||||
// 🔽 [수정] 7. 최대 레벨 가져오기 (gameType 분기)
|
||||
Future<int> getMaxUnlockedLevel({String gameType = 'SUDOKU'}) async {
|
||||
final key = gameType == 'SPIDER' ? _spiderMaxLevelKey : _sudokuMaxLevelKey;
|
||||
String key;
|
||||
switch (gameType) {
|
||||
case 'SPIDER':
|
||||
key = _spiderMaxLevelKey;
|
||||
break;
|
||||
case 'MATH_QUIZ': // 👈 [추가]
|
||||
key = _mathQuizMaxLevelKey;
|
||||
break;
|
||||
default: // 'SUDOKU'
|
||||
key = _sudokuMaxLevelKey;
|
||||
}
|
||||
String? levelString = await _storage.read(
|
||||
key: key,
|
||||
iOptions: _getIOSOptions(),
|
||||
aOptions: _getAndroidOptions(),
|
||||
);
|
||||
return int.parse(levelString ?? '1'); // 기본값 1
|
||||
return int.parse(levelString ?? '1');
|
||||
}
|
||||
|
||||
// 8. 최대 레벨 저장하기
|
||||
// 🔽 [수정] 8. 최대 레벨 저장하기 (gameType 분기)
|
||||
Future<void> saveMaxUnlockedLevel(int level, {String gameType = 'SUDOKU'}) async {
|
||||
final key = gameType == 'SPIDER' ? _spiderMaxLevelKey : _sudokuMaxLevelKey;
|
||||
String key;
|
||||
switch (gameType) {
|
||||
case 'SPIDER':
|
||||
key = _spiderMaxLevelKey;
|
||||
break;
|
||||
case 'MATH_QUIZ': // 👈 [추가]
|
||||
key = _mathQuizMaxLevelKey;
|
||||
break;
|
||||
default: // 'SUDOKU'
|
||||
key = _sudokuMaxLevelKey;
|
||||
}
|
||||
await _storage.write(
|
||||
key: key,
|
||||
value: level.toString(),
|
||||
@@ -159,9 +179,19 @@ class IdentityService {
|
||||
);
|
||||
}
|
||||
|
||||
// 9. 마지막 랭킹 맵 가져오기
|
||||
// 🔽 [수정] 9. 마지막 랭킹 맵 가져오기 (gameType 분기)
|
||||
Future<Map<int, int>> getLastSavedRankMap({String gameType = 'SUDOKU'}) async {
|
||||
final key = gameType == 'SPIDER' ? _spiderRankMapKey : _sudokuRankMapKey;
|
||||
String key;
|
||||
switch (gameType) {
|
||||
case 'SPIDER':
|
||||
key = _spiderRankMapKey;
|
||||
break;
|
||||
case 'MATH_QUIZ': // 👈 [추가]
|
||||
key = _mathQuizRankMapKey;
|
||||
break;
|
||||
default: // 'SUDOKU'
|
||||
key = _sudokuRankMapKey;
|
||||
}
|
||||
String? jsonString = await _storage.read(
|
||||
key: key,
|
||||
iOptions: _getIOSOptions(),
|
||||
@@ -177,9 +207,19 @@ class IdentityService {
|
||||
}
|
||||
}
|
||||
|
||||
// 10. 마지막 랭킹 맵 저장하기
|
||||
// 🔽 [수정] 10. 마지막 랭킹 맵 저장하기 (gameType 분기)
|
||||
Future<void> saveLastRankMap(Map<int, int> rankMap, {String gameType = 'SUDOKU'}) async {
|
||||
final key = gameType == 'SPIDER' ? _spiderRankMapKey : _sudokuRankMapKey;
|
||||
String key;
|
||||
switch (gameType) {
|
||||
case 'SPIDER':
|
||||
key = _spiderRankMapKey;
|
||||
break;
|
||||
case 'MATH_QUIZ': // 👈 [추가]
|
||||
key = _mathQuizRankMapKey;
|
||||
break;
|
||||
default: // 'SUDOKU'
|
||||
key = _sudokuRankMapKey;
|
||||
}
|
||||
|
||||
final Map<String, int> stringKeyMap =
|
||||
rankMap.map((key, value) => MapEntry(key.toString(), value));
|
||||
|
||||
Reference in New Issue
Block a user