Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M3-237 iOS 백그라운드 땅따먹기 구현 #72

Merged
merged 6 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions ios/PrivacyInfo.xcprivacy
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
PrivacyInfo.xcprivacy
Runner

Created by KooMin on 8/8/24.
Copyright (c) 2024 . All rights reserved.
-->
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<!-- [1] background_fetch: UserDefaults -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>

<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>

<!-- [2] background_geolocation: UserDefaults -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>

<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
<string>1C8F.1</string>
</array>
</dict>
<!-- [3] background_geolocation (CocoaLumberjack): FileTimestamp -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
<string>0A2A.1</string>
</array>
</dict>
<!-- [4] background_geolocation (CocoaLumberjack): DiskSpace -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>E174.1</string>
</array>
</dict>
</array>
<dict/>
</plist>
19 changes: 11 additions & 8 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
4EB854D129889EE1A9F5CBAF /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 239794E191ECC31390795268 /* Pods_Runner.framework */; };
6F8097AE2C64F082004A75E9 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 6F8097AD2C64F082004A75E9 /* PrivacyInfo.xcprivacy */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
Expand Down Expand Up @@ -51,7 +52,8 @@
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
411AA052E50F1F579C6A8C98 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
4D03C47278E5B0EB654A3EFA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
6F8097AA2C6398BA004A75E9 /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = "<group>"; };
6F8097AD2C64F082004A75E9 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
6F8097AF2C64F495004A75E9 /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = "<group>"; };
6FCD42AC2C266AE00030334E /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -113,6 +115,7 @@
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
6F8097AD2C64F082004A75E9 /* PrivacyInfo.xcprivacy */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
Expand All @@ -135,7 +138,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
6F8097AA2C6398BA004A75E9 /* RunnerRelease.entitlements */,
6F8097AF2C64F495004A75E9 /* RunnerRelease.entitlements */,
6FCD42AC2C266AE00030334E /* Runner.entitlements */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
Expand Down Expand Up @@ -499,7 +502,7 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 3BD2BV9TRM;
ENABLE_BITCODE = NO;
FLUTTER_BUILD_NAME = 1.0.3;
FLUTTER_BUILD_NAME = 1.0.4;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Ground Flip";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness";
Expand All @@ -508,7 +511,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.3;
MARKETING_VERSION = 1.0.4;
PRODUCT_BUNDLE_IDENTIFIER = com.m3pro.groundFlip;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
Expand Down Expand Up @@ -689,7 +692,7 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 3BD2BV9TRM;
ENABLE_BITCODE = NO;
FLUTTER_BUILD_NAME = 1.0.3;
FLUTTER_BUILD_NAME = 1.0.4;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Ground Flip";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness";
Expand All @@ -698,7 +701,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.3;
MARKETING_VERSION = 1.0.4;
PRODUCT_BUNDLE_IDENTIFIER = com.m3pro.groundFlip;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
Expand All @@ -719,7 +722,7 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 3BD2BV9TRM;
ENABLE_BITCODE = NO;
FLUTTER_BUILD_NAME = 1.0.3;
FLUTTER_BUILD_NAME = 1.0.4;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Ground Flip";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.healthcare-fitness";
Expand All @@ -728,7 +731,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.3;
MARKETING_VERSION = 1.0.4;
PRODUCT_BUNDLE_IDENTIFIER = com.m3pro.groundFlip;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
Expand Down
5 changes: 3 additions & 2 deletions lib/controllers/map_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ class MapController extends SuperController {
void _trackUserLocation() {
_locationService.location.onLocationChanged.listen((newLocation) async {
_locationService.currentLocation = newLocation;

if (isCameraTrackingUser.value) {
setCameraOnCurrentLocation();
}
Expand Down Expand Up @@ -225,7 +224,9 @@ class MapController extends SuperController {
}

void trackPixels() {
_updatePixelTimer = Timer.periodic(const Duration(seconds: 10), (timer) {
_updatePixelTimer =
Timer.periodic(const Duration(seconds: 10), (timer) async {
UserManager().updateSecureStorage();
updatePixels();
});
}
Expand Down
4 changes: 4 additions & 0 deletions lib/service/auth_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class AuthService {
return false;
} else {
UserManager().setUserId(extractUserIdFromToken(accessToken));
UserManager().setAccessToken(accessToken);
UserManager().setRefreshToken(refreshToken);
return true;
}
}
Expand Down Expand Up @@ -83,6 +85,8 @@ class AuthService {
await secureStorage.writeAccessToken(authResponse.accessToken);
await secureStorage.writeRefreshToken(authResponse.refreshToken);
UserManager().setUserId(extractUserIdFromToken(authResponse.accessToken!));
UserManager().setAccessToken(authResponse.accessToken!);
UserManager().setRefreshToken(authResponse.refreshToken!);
}

Future<LoginResponse> postKakaoLogin(String accessToken) async {
Expand Down
15 changes: 8 additions & 7 deletions lib/utils/dio_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import 'package:get/get.dart' hide Response;

import '../models/reissue_response.dart';
import '../service/auth_service.dart';
import 'secure_storage.dart';
import 'user_manager.dart';

class DioService {
static final DioService _dioServices = DioService._internal();
static final String baseUrl = dotenv.env['BASE_URL']!;
final SecureStorage secureStorage = SecureStorage();

final UserManager userManager = UserManager();

factory DioService() => _dioServices;

Expand All @@ -29,7 +30,7 @@ class DioService {
_dio.interceptors.add(
InterceptorsWrapper(
onRequest: (options, handler) async {
final accessToken = await secureStorage.readAccessToken();
final accessToken = userManager.getAccessToken();
options.headers.addAll({
'Authorization': 'Bearer $accessToken',
});
Expand All @@ -47,9 +48,8 @@ class DioService {
if (dioException.response?.statusCode == HttpStatus.unauthorized) {
try {
ReissueResponse reissueResponse = await reissueToken();
await secureStorage.writeAccessToken(reissueResponse.accessToken);
await secureStorage
.writeRefreshToken(reissueResponse.refreshToken);
userManager.setAccessToken(reissueResponse.accessToken!);
userManager.setRefreshToken(reissueResponse.refreshToken!);

Response<dynamic> resendResponse =
await resendRequest(dioException, reissueResponse);
Expand Down Expand Up @@ -82,12 +82,13 @@ class DioService {
}

Future<ReissueResponse> reissueToken() async {
final refreshToken = await secureStorage.readRefreshToken();
final refreshToken = userManager.getRefreshToken();
final dio = Dio();
var response = await dio
.post("$baseUrl/auth/reissue", data: {"refreshToken": refreshToken});
ReissueResponse reissueResponse =
ReissueResponse.fromJson(response.data["data"]);
UserManager().setTokenReissued();
return reissueResponse;
}

Expand Down
36 changes: 36 additions & 0 deletions lib/utils/user_manager.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'secure_storage.dart';

class UserManager {
static final UserManager _instance = UserManager._internal();
final SecureStorage secureStorage = SecureStorage();

factory UserManager() {
return _instance;
Expand All @@ -8,16 +11,49 @@ class UserManager {
UserManager._internal();

int? userId;
String? accessToken;
String? refreshToken;
bool? isTokenReissued;

void init() {
userId = null;
accessToken = null;
refreshToken = null;
isTokenReissued = null;
}

updateSecureStorage() {
if (isTokenReissued == true) {
secureStorage.writeAccessToken(accessToken);
secureStorage.writeRefreshToken(refreshToken);
}
}

void setUserId(int id) {
userId = id;
}

void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}

void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}

void setTokenReissued() {
isTokenReissued = true;
}

int? getUserId() {
return userId;
}

String getAccessToken() {
return accessToken ?? "token";
}

String getRefreshToken() {
return refreshToken ?? "token";
}
}