From 2b846e2074a4c1616ae01ab1e5d8c2e1b7e6b346 Mon Sep 17 00:00:00 2001
From: Jeon Seoung Hun <jsh097610@gmail.com>
Date: Fri, 29 Dec 2023 02:24:05 +0900
Subject: [PATCH] =?UTF-8?q?[Feat]:=20=EB=93=B1=EB=A1=9D=20api=20=EC=97=B0?=
 =?UTF-8?q?=EA=B2=B0,=20network=20cancellable=20=EA=B8=B0=EB=8A=A5=20?=
 =?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 AVIRO.xcodeproj/project.pbxproj               |  44 ++---
 AVIRO/App/AppController.swift                 |   6 +-
 .../APIManager/APIManagerProtocol.swift       | 142 +++++++-------
 .../{AVIROAPIManager.swift => AVIROAPI.swift} | 157 ++++++++++++----
 .../AVIROAPIManagerProtocol.swift             |   6 +-
 .../AVIROManager/AVIROPostAPI.swift           |   1 +
 .../APIManager/KakaoMapManager/KakaoAPI.swift | 173 ++++++++++++++++++
 .../KakaoMapManager/KakaoAPIManager.swift     |  92 ----------
 ...PublicAPIManager.swift => PublicAPI.swift} |   6 +-
 .../FacadeManager/BookmarkManager.swift       |   4 +-
 .../FacadeManager/MarkerModelManager.swift    |   6 +-
 .../AVIRO/AVIROPost/AVIROResult+DTO.swift     |   7 +
 .../AVIROPost/Enroll/AVIROReview+DTO.swift    |   7 -
 AVIRO/Scene/Base/AVIROTabBarController.swift  |  81 +++++---
 .../NickNameChangeblePresenter.swift          |   4 +-
 .../ViewPresenter/SettingViewPresenter.swift  |   2 +-
 .../ChallengeLevelView.swift                  |   4 +-
 .../ChallengeUserInfoView.swift               |   9 +-
 .../ViewModel/ChallengeViewModel.swift        |   6 +-
 .../ViewPresenter/SearchPlacePresenter.swift  |   6 +-
 .../EnrollPlaceViewController.swift           |  10 +-
 .../ViewPresenter/EnrollPlacePresenter.swift  |  22 +--
 .../ViewPresenter/EditMenuPresenter.swift     |   2 +-
 .../ChangeableAddressPresenter.swift          |   6 +-
 .../EditPlaceInfoPresenter.swift              |  12 +-
 .../ViewPresenter/HomeSearchPresenter.swift   |   4 +-
 .../ViewPresenter/ReportReviewPresenter.swift |   2 +-
 .../ViewModel/ReviewWriteViewModel.swift      |   4 +-
 .../ViewController/HomeViewController.swift   |   9 +-
 .../ViewPresenter/HomeViewPresenter.swift     |  18 +-
 .../FirstRegistrationPresenter.swift          |   2 +-
 .../ThridRegistrationPresenter.swift          |   2 +-
 .../ViewPresenter/LoginViewPresenter.swift    |   4 +-
 33 files changed, 537 insertions(+), 323 deletions(-)
 rename AVIRO/Manager/APIManager/AVIROManager/{AVIROAPIManager.swift => AVIROAPI.swift} (86%)
 create mode 100644 AVIRO/Manager/APIManager/KakaoMapManager/KakaoAPI.swift
 delete mode 100644 AVIRO/Manager/APIManager/KakaoMapManager/KakaoAPIManager.swift
 rename AVIRO/Manager/APIManager/PublicManager/{PublicAPIManager.swift => PublicAPI.swift} (92%)

diff --git a/AVIRO.xcodeproj/project.pbxproj b/AVIRO.xcodeproj/project.pbxproj
index db2690fe..3acc3106 100644
--- a/AVIRO.xcodeproj/project.pbxproj
+++ b/AVIRO.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 56;
+	objectVersion = 60;
 	objects = {
 
 /* Begin PBXBuildFile section */
@@ -112,7 +112,7 @@
 		C5476B762B314D4900F5FC6E /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = C5476B752B314D4900F5FC6E /* Settings.bundle */; };
 		C5476B792B314F6F00F5FC6E /* LicensesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5476B782B314F6F00F5FC6E /* LicensesViewController.swift */; };
 		C5476B7B2B31516000F5FC6E /* LicenseDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5476B7A2B31516000F5FC6E /* LicenseDetailViewController.swift */; };
-		C547A8BA2A17D8D4004D1339 /* KakaoAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C547A8B92A17D8D4004D1339 /* KakaoAPIManager.swift */; };
+		C547A8BA2A17D8D4004D1339 /* KakaoAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C547A8B92A17D8D4004D1339 /* KakaoAPI.swift */; };
 		C54BC0DB2A2C2D0D00B65439 /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C54BC0DA2A2C2D0D00B65439 /* UIColor+Extension.swift */; };
 		C552D5342ABE8CA500933D8A /* AVIRODeleteAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C552D5332ABE8CA500933D8A /* AVIRODeleteAPI.swift */; };
 		C5538AAF2A1BB81200661DE2 /* AVIROEnrollPlace+DTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5538AAE2A1BB81200661DE2 /* AVIROEnrollPlace+DTO.swift */; };
@@ -128,7 +128,7 @@
 		C56857802A7113C600F52715 /* NormalTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C568577F2A7113C600F52715 /* NormalTableViewCell.swift */; };
 		C56857822A7113CF00F52715 /* RequestTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56857812A7113CF00F52715 /* RequestTableViewCell.swift */; };
 		C56E7A112A971504009CCAF2 /* ReportCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56E7A102A971504009CCAF2 /* ReportCellView.swift */; };
-		C5732C712A41739000CDC499 /* AVIROAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5732C702A41739000CDC499 /* AVIROAPIManager.swift */; };
+		C5732C712A41739000CDC499 /* AVIROAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5732C702A41739000CDC499 /* AVIROAPI.swift */; };
 		C5732C732A41778A00CDC499 /* AVIROPostAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5732C722A41778A00CDC499 /* AVIROPostAPI.swift */; };
 		C5732C752A41962D00CDC499 /* AVIRORequestAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5732C742A41962D00CDC499 /* AVIRORequestAPI.swift */; };
 		C5732C772A41A0A500CDC499 /* AVIROMapMarker+DTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5732C762A41A0A500CDC499 /* AVIROMapMarker+DTO.swift */; };
@@ -230,7 +230,7 @@
 		C5FBDA602B398280007AC77E /* ChallengeInfoOrangeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FBDA5F2B398280007AC77E /* ChallengeInfoOrangeView.swift */; };
 		C5FD92E32A9C6C1E00CF4673 /* EditLocationAddressTextTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FD92E22A9C6C1E00CF4673 /* EditLocationAddressTextTableViewCell.swift */; };
 		C5FD92EB2A9C786600CF4673 /* PublicAPIRequestComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FD92EA2A9C786600CF4673 /* PublicAPIRequestComponents.swift */; };
-		C5FD92ED2A9C7AE800CF4673 /* PublicAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FD92EC2A9C7AE800CF4673 /* PublicAPIManager.swift */; };
+		C5FD92ED2A9C7AE800CF4673 /* PublicAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FD92EC2A9C7AE800CF4673 /* PublicAPI.swift */; };
 		C5FD92F02A9C803600CF4673 /* PublicAddress+DTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FD92EF2A9C803600CF4673 /* PublicAddress+DTO.swift */; };
 		C5FD92F22A9C805700CF4673 /* PublicXMLParserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FD92F12A9C805700CF4673 /* PublicXMLParserDelegate.swift */; };
 		C5FD92F42A9CD2FC00CF4673 /* KakaoAddressPlace+DTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5FD92F32A9CD2FC00CF4673 /* KakaoAddressPlace+DTO.swift */; };
@@ -364,7 +364,7 @@
 		C5476B752B314D4900F5FC6E /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
 		C5476B782B314F6F00F5FC6E /* LicensesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LicensesViewController.swift; sourceTree = "<group>"; };
 		C5476B7A2B31516000F5FC6E /* LicenseDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LicenseDetailViewController.swift; sourceTree = "<group>"; };
-		C547A8B92A17D8D4004D1339 /* KakaoAPIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KakaoAPIManager.swift; sourceTree = "<group>"; };
+		C547A8B92A17D8D4004D1339 /* KakaoAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KakaoAPI.swift; sourceTree = "<group>"; };
 		C54BC0DA2A2C2D0D00B65439 /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
 		C552D5332ABE8CA500933D8A /* AVIRODeleteAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVIRODeleteAPI.swift; sourceTree = "<group>"; };
 		C5538AAE2A1BB81200661DE2 /* AVIROEnrollPlace+DTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVIROEnrollPlace+DTO.swift"; sourceTree = "<group>"; };
@@ -380,7 +380,7 @@
 		C568577F2A7113C600F52715 /* NormalTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NormalTableViewCell.swift; sourceTree = "<group>"; };
 		C56857812A7113CF00F52715 /* RequestTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestTableViewCell.swift; sourceTree = "<group>"; };
 		C56E7A102A971504009CCAF2 /* ReportCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportCellView.swift; sourceTree = "<group>"; };
-		C5732C702A41739000CDC499 /* AVIROAPIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVIROAPIManager.swift; sourceTree = "<group>"; };
+		C5732C702A41739000CDC499 /* AVIROAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVIROAPI.swift; sourceTree = "<group>"; };
 		C5732C722A41778A00CDC499 /* AVIROPostAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVIROPostAPI.swift; sourceTree = "<group>"; };
 		C5732C742A41962D00CDC499 /* AVIRORequestAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVIRORequestAPI.swift; sourceTree = "<group>"; };
 		C5732C762A41A0A500CDC499 /* AVIROMapMarker+DTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVIROMapMarker+DTO.swift"; sourceTree = "<group>"; };
@@ -484,7 +484,7 @@
 		C5FBDA5F2B398280007AC77E /* ChallengeInfoOrangeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeInfoOrangeView.swift; sourceTree = "<group>"; };
 		C5FD92E22A9C6C1E00CF4673 /* EditLocationAddressTextTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditLocationAddressTextTableViewCell.swift; sourceTree = "<group>"; };
 		C5FD92EA2A9C786600CF4673 /* PublicAPIRequestComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicAPIRequestComponents.swift; sourceTree = "<group>"; };
-		C5FD92EC2A9C7AE800CF4673 /* PublicAPIManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicAPIManager.swift; sourceTree = "<group>"; };
+		C5FD92EC2A9C7AE800CF4673 /* PublicAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicAPI.swift; sourceTree = "<group>"; };
 		C5FD92EF2A9C803600CF4673 /* PublicAddress+DTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicAddress+DTO.swift"; sourceTree = "<group>"; };
 		C5FD92F12A9C805700CF4673 /* PublicXMLParserDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicXMLParserDelegate.swift; sourceTree = "<group>"; };
 		C5FD92F32A9CD2FC00CF4673 /* KakaoAddressPlace+DTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KakaoAddressPlace+DTO.swift"; sourceTree = "<group>"; };
@@ -843,7 +843,7 @@
 			isa = PBXGroup;
 			children = (
 				C58FBF912AC2D87300AB6EFC /* KakaoAPIManagerProtocol.swift */,
-				C547A8B92A17D8D4004D1339 /* KakaoAPIManager.swift */,
+				C547A8B92A17D8D4004D1339 /* KakaoAPI.swift */,
 				C5351B4C2A19223300116D50 /* KakaoMapRequestAPI.swift */,
 			);
 			path = KakaoMapManager;
@@ -1316,7 +1316,7 @@
 			isa = PBXGroup;
 			children = (
 				C58FBF8F2AC2B83A00AB6EFC /* AVIROAPIManagerProtocol.swift */,
-				C5732C702A41739000CDC499 /* AVIROAPIManager.swift */,
+				C5732C702A41739000CDC499 /* AVIROAPI.swift */,
 				C5732C742A41962D00CDC499 /* AVIRORequestAPI.swift */,
 				C5732C722A41778A00CDC499 /* AVIROPostAPI.swift */,
 				C552D5332ABE8CA500933D8A /* AVIRODeleteAPI.swift */,
@@ -1795,7 +1795,7 @@
 		C5FD92E82A9C77CE00CF4673 /* PublicManager */ = {
 			isa = PBXGroup;
 			children = (
-				C5FD92EC2A9C7AE800CF4673 /* PublicAPIManager.swift */,
+				C5FD92EC2A9C7AE800CF4673 /* PublicAPI.swift */,
 				C5FD92EA2A9C786600CF4673 /* PublicAPIRequestComponents.swift */,
 				C5FD92F12A9C805700CF4673 /* PublicXMLParserDelegate.swift */,
 			);
@@ -1914,7 +1914,7 @@
 				};
 			};
 			buildConfigurationList = C52FA33A2A175B20005E70DC /* Build configuration list for PBXProject "AVIRO" */;
-			compatibilityVersion = "Xcode 14.0";
+			compatibilityVersion = "Xcode 15.0";
 			developmentRegion = ko;
 			hasScannedForEncodings = 0;
 			knownRegions = (
@@ -2150,7 +2150,7 @@
 				C5E430B32A5DADBE00CB67EC /* SecondRegistrationPresenter.swift in Sources */,
 				C5EB510D2A20A4B400B29CC1 /* HomeSearchViewTableViewCell.swift in Sources */,
 				C510005C2AB9C39500F65C1F /* MarkerModelManager.swift in Sources */,
-				C5FD92ED2A9C7AE800CF4673 /* PublicAPIManager.swift in Sources */,
+				C5FD92ED2A9C7AE800CF4673 /* PublicAPI.swift in Sources */,
 				C50367F52A1795D10020C6BB /* HomeViewPresenter.swift in Sources */,
 				C5FD92F42A9CD2FC00CF4673 /* KakaoAddressPlace+DTO.swift in Sources */,
 				C5ED46952AAEB3F300F2DA04 /* OperationHourView.swift in Sources */,
@@ -2194,7 +2194,7 @@
 				C52066332A7E80350038ECCD /* MatchedPlaceCellModel.swift in Sources */,
 				C595ACCD2A84A1A200D35123 /* PlaceView.swift in Sources */,
 				C51385422AAADB0E001AB827 /* EditNickNameButton.swift in Sources */,
-				C547A8BA2A17D8D4004D1339 /* KakaoAPIManager.swift in Sources */,
+				C547A8BA2A17D8D4004D1339 /* KakaoAPI.swift in Sources */,
 				C5732C772A41A0A500CDC499 /* AVIROMapMarker+DTO.swift in Sources */,
 				C5FF13532A42C8810026981D /* AVIROPlaceInfo+DTO.swift in Sources */,
 				C5351B5C2A19F60200116D50 /* SearchPlacePresenter.swift in Sources */,
@@ -2243,7 +2243,7 @@
 				C5351B602A19F9A700116D50 /* PlaceListModel.swift in Sources */,
 				C5476B612B3028FA00F5FC6E /* ChallengeViewController.swift in Sources */,
 				C5A201C52A98A67900A54381 /* EditPhoneView.swift in Sources */,
-				C5732C712A41739000CDC499 /* AVIROAPIManager.swift in Sources */,
+				C5732C712A41739000CDC499 /* AVIROAPI.swift in Sources */,
 				C54386792B3432FE00BD2CAF /* ViewModel.swift in Sources */,
 				C50F6AF92A68FFBB00E942F5 /* EnrollStoreInfoView.swift in Sources */,
 				C505C1DA2B3AC0070058F115 /* AVIROConfiguration.swift in Sources */,
@@ -2428,7 +2428,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = AVIRO/AVIRO.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 6;
+				CURRENT_PROJECT_VERSION = 7;
 				DEVELOPMENT_TEAM = C4K2HXA435;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AVIRO/App/Info.plist;
@@ -2438,15 +2438,15 @@
 				INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "현재 내 위치와 가까운 가게를 찾아드려요. 위치 정보를 저장하지 않으니 안심하세요.";
 				INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
-				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
-				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+				INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait";
+				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
 				INFOPLIST_KEY_UIUserInterfaceStyle = Light;
 				IPHONEOS_DEPLOYMENT_TARGET = 15.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.0.2;
+				MARKETING_VERSION = 1.1.1;
 				PRODUCT_BUNDLE_IDENTIFIER = SeonghunJeon.VeganRestaurant;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_EMIT_LOC_STRINGS = YES;
@@ -2463,7 +2463,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = AVIRO/AVIRO.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 6;
+				CURRENT_PROJECT_VERSION = 7;
 				DEVELOPMENT_TEAM = C4K2HXA435;
 				GENERATE_INFOPLIST_FILE = YES;
 				INFOPLIST_FILE = AVIRO/App/Info.plist;
@@ -2473,15 +2473,15 @@
 				INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "현재 내 위치와 가까운 가게를 찾아드려요. 위치 정보를 저장하지 않으니 안심하세요.";
 				INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
 				INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
-				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
-				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+				INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait";
+				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
 				INFOPLIST_KEY_UIUserInterfaceStyle = Light;
 				IPHONEOS_DEPLOYMENT_TARGET = 15.0;
 				LD_RUNPATH_SEARCH_PATHS = (
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 1.0.2;
+				MARKETING_VERSION = 1.1.1;
 				PRODUCT_BUNDLE_IDENTIFIER = SeonghunJeon.VeganRestaurant;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_EMIT_LOC_STRINGS = YES;
diff --git a/AVIRO/App/AppController.swift b/AVIRO/App/AppController.swift
index 001855be..bcae85c6 100644
--- a/AVIRO/App/AppController.swift
+++ b/AVIRO/App/AppController.swift
@@ -34,8 +34,8 @@ final class AppController {
         window.backgroundColor = .gray7
         window.makeKeyAndVisible()
         
-        checkState()
-//        setTabBarView()
+//        checkState()
+        setTabBarView()
     }
     
     // MARK: 불러올 view 확인 메서드
@@ -54,7 +54,7 @@ final class AppController {
 
         let userCheck = AVIROAutoLoginWhenAppleUserDTO(refreshToken: userKey)
 
-        AVIROAPIManager().appleUserCheck(with: userCheck) { [weak self] result in
+        AVIROAPI.manager.appleUserCheck(with: userCheck) { [weak self] result in
             switch result {
             case .success(let model):
                 if model.statusCode == 200 {
diff --git a/AVIRO/Manager/APIManager/APIManagerProtocol.swift b/AVIRO/Manager/APIManager/APIManagerProtocol.swift
index bec5da3e..6273e272 100644
--- a/AVIRO/Manager/APIManager/APIManagerProtocol.swift
+++ b/AVIRO/Manager/APIManager/APIManagerProtocol.swift
@@ -21,75 +21,77 @@ protocol APIManagerProtocol {
 
 extension APIManagerProtocol {
     var session: URLSession {
-         let configuration = URLSessionConfiguration.default
-         configuration.timeoutIntervalForRequest = 10.0
-        configuration.waitsForConnectivity = false
-         return URLSession(configuration: configuration)
-     }
-
-    func performRequest<T: Decodable>(
-            with url: URL,
-            httpMethod: HTTPMethodType = .get,
-            requestBody: Data? = nil,
-            headers: [String: String]? = nil,
-            completionHandler: @escaping (Result<T, APIError>) -> Void
-    ) {
-        var request = URLRequest(url: url)
-        
-        request.httpMethod = httpMethod.rawValue
-        request.httpBody = requestBody
-        
-        if let headers = headers {
-            for (key, value) in headers {
-                request.addValue(value, forHTTPHeaderField: key)
-            }
-        }
-        
-        session.dataTask(with: request) { data, response, error in
-            if let error = error {
-                completionHandler(.failure(.networkError(error)))
-                return
-            }
-            
-            guard let httpResponse = response as? HTTPURLResponse else {
-                completionHandler(.failure(.invalidResponse))
-                return
-            }
-            
-            if let apiError = handleStatusCode(with: httpResponse.statusCode) {
-                completionHandler(.failure(apiError))
-                return
-            }
-            
-            guard let data = data else {
-                completionHandler(.failure(.badRequest))
-                return
-            }
-            
-            do {
-                let decodedObject = try JSONDecoder().decode(T.self, from: data)
-                completionHandler(.success(decodedObject))
-            } catch {
-                completionHandler(.failure(.decodingError(error)))
-            }
-        }.resume()
-        
-    }
-    
-    private func handleStatusCode(with code: Int) -> APIError? {
-        switch code {
-        case 100..<200:
-            return APIError.informationResponse
-        case 200..<300:
-            return nil
-        case 300..<400:
-            return APIError.redirectionRequired
-        case 400..<500:
-            return APIError.clientError(code)
-        case 500...:
-            return APIError.serverError(code)
-        default:
-            return APIError.badRequest
-        }
+        let configuration = URLSessionConfiguration.default
+        configuration.timeoutIntervalForRequest = 10.0
+//        configuration.waitsForConnectivity = false
+        return URLSession(configuration: configuration)
     }
+//
+//    func performRequest<T: Decodable>(
+//            with url: URL,
+//            httpMethod: HTTPMethodType = .get,
+//            requestBody: Data? = nil,
+//            headers: [String: String]? = nil,
+//            completionHandler: @escaping (Result<T, APIError>) -> Void
+//    ) {
+//        var request = URLRequest(url: url)
+//        
+//        request.httpMethod = httpMethod.rawValue
+//        request.httpBody = requestBody
+//        
+//        if let headers = headers {
+//            for (key, value) in headers {
+//                request.addValue(value, forHTTPHeaderField: key)
+//            }
+//        }
+//        
+//        let task = session.dataTask(with: request) { data, response, error in
+//            if let error = error {
+//                completionHandler(.failure(.networkError(error)))
+//                return
+//            }
+//            
+//            guard let httpResponse = response as? HTTPURLResponse else {
+//                completionHandler(.failure(.invalidResponse))
+//                return
+//            }
+//            
+//            if let apiError = handleStatusCode(with: httpResponse.statusCode) {
+//                completionHandler(.failure(apiError))
+//                return
+//            }
+//            
+//            guard let data = data else {
+//                completionHandler(.failure(.badRequest))
+//                return
+//            }
+//            
+//            do {
+//                let decodedObject = try JSONDecoder().decode(T.self, from: data)
+//                completionHandler(.success(decodedObject))
+//            } catch {
+//                completionHandler(.failure(.decodingError(error)))
+//            }
+//        }
+//        
+//        task.resume()
+//        
+//    }
+//    
+//    private func handleStatusCode(with code: Int) -> APIError? {
+//        switch code {
+//        case 100..<200:
+//            return APIError.informationResponse
+//        case 200..<300:
+//            return nil
+//        case 300..<400:
+//            return APIError.redirectionRequired
+//        case 400..<500:
+//            return APIError.clientError(code)
+//        case 500...:
+//            return APIError.serverError(code)
+//        default:
+//            return APIError.badRequest
+//        }
+//    }
 }
diff --git a/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManager.swift b/AVIRO/Manager/APIManager/AVIROManager/AVIROAPI.swift
similarity index 86%
rename from AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManager.swift
rename to AVIRO/Manager/APIManager/AVIROManager/AVIROAPI.swift
index a3e8e5fe..083d1612 100644
--- a/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManager.swift
+++ b/AVIRO/Manager/APIManager/AVIROManager/AVIROAPI.swift
@@ -7,14 +7,17 @@
 
 import Foundation
 
-final class AVIROAPIManager: AVIROAPIMangerProtocol {
+final class AVIROAPI: AVIROAPIMangerProtocol {
+    static let manager = AVIROAPI()
+    var onRequest: Set<URL> = []
+    
     var session: URLSession
     
     var postAPI = AVIROPostAPI()
     var requestAPI = AVIRORequestAPI()
     var deleteAPI = AVIRODeleteAPI()
     
-    init(session: URLSession = .shared) {
+    private init(session: URLSession = .shared) {
         self.session = session
     }
         
@@ -27,7 +30,6 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.urlError))
             return
         }
-
         performRequest(
             with: url,
             headers: requestAPI.headers,
@@ -64,7 +66,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -83,7 +85,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.urlError))
             return
         }
-        
+
         performRequest(
             with: url,
             headers: requestAPI.headers,
@@ -104,7 +106,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -122,7 +124,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.urlError))
             return
         }
-        
+
         performRequest(
             with: url,
             headers: requestAPI.headers,
@@ -133,7 +135,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
     // MARK: Create Refer
     func createPlaceModel(
         with placeModel: AVIROEnrollPlaceDTO,
-        completionHandler: @escaping (Result<AVIROResultDTO, APIError>) -> Void
+        completionHandler: @escaping (Result<AVIROChallengeResultDTO, APIError>) -> Void
     ) {
         guard let url = postAPI.placeEnroll().url else {
             completionHandler(.failure(.urlError))
@@ -144,7 +146,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -156,7 +158,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
     
     func createReview(
         with reviewModel: AVIROEnrollReviewDTO,
-        completionHandler: @escaping (Result<AVIROEnrollReviewResultDTO, APIError>) -> Void
+        completionHandler: @escaping (Result<AVIROChallengeResultDTO, APIError>) -> Void
     ) {
         guard let url = postAPI.commentUpload().url else {
             completionHandler(.failure(.urlError))
@@ -203,7 +205,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.urlError))
             return
         }
-        
+
         performRequest(
             with: url,
             headers: requestAPI.headers,
@@ -219,7 +221,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.urlError))
             return
         }
-        
+
         performRequest(
             with: url,
             headers: requestAPI.headers,
@@ -235,7 +237,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.urlError))
             return
         }
-        
+
         performRequest(
             with: url,
             headers: requestAPI.headers,
@@ -251,7 +253,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.urlError))
             return
         }
-        
+
         performRequest(
             with: url,
             headers: requestAPI.headers,
@@ -273,7 +275,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -296,7 +298,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -319,7 +321,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -342,7 +344,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -365,7 +367,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -388,7 +390,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -412,7 +414,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -468,6 +470,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
         with user: AVIROAutoLoginWhenAppleUserDTO,
         completionHandler: @escaping (Result<AVIROAutoLoginWhenAppleUserResultDTO, APIError>) -> Void
     ) {
+        
         guard let url = postAPI.appleUserAutoLogin().url else {
             completionHandler(.failure(.urlError))
             return
@@ -500,7 +503,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -523,7 +526,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -546,7 +549,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -569,7 +572,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -592,7 +595,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.encodingError))
             return
         }
-        
+
         performRequest(
             with: url,
             httpMethod: .post,
@@ -611,7 +614,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
             completionHandler(.failure(.urlError))
             return
         }
-        
+
         performRequest(
             with: url,
             headers: requestAPI.headers,
@@ -620,17 +623,18 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
     }
     
     func loadChallengeInfo(
-        completionHandler: @escaping (Result<AVIROChallengeInfoDTO, APIError>) -> Void) {
-            guard let url = requestAPI.getChallengeInfo().url else {
-                completionHandler(.failure(.urlError))
-                return
-            }
-            
-            performRequest(
-                with: url,
-                headers: requestAPI.headers,
-                completionHandler: completionHandler
-            )
+        completionHandler: @escaping (Result<AVIROChallengeInfoDTO, APIError>) -> Void
+    ) {
+        guard let url = requestAPI.getChallengeInfo().url else {
+            completionHandler(.failure(.urlError))
+            return
+        }
+
+        performRequest(
+            with: url,
+            headers: requestAPI.headers,
+            completionHandler: completionHandler
+        )
     }
     
     func loadMyChallengeLevel(
@@ -649,3 +653,80 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol {
         )
     }
 }
+
+extension AVIROAPI {
+    func performRequest<T>(
+        with url: URL,
+        httpMethod: HTTPMethodType = .get,
+        requestBody: Data? = nil,
+        headers: [String: String]? = nil,
+        completionHandler: @escaping (Result<T, APIError>) -> Void
+    ) where T: Decodable {
+        guard !onRequest.contains(url) else { return }
+        
+        onRequest.insert(url)
+        
+        var request = URLRequest(url: url)
+        
+        request.httpMethod = httpMethod.rawValue
+        request.httpBody = requestBody
+        
+        if let headers = headers {
+            for (key, value) in headers {
+                request.addValue(value, forHTTPHeaderField: key)
+            }
+        }
+        
+        let task = session.dataTask(with: request) { [weak self] data, response, error in
+            defer {
+                self?.onRequest.remove(url)
+            }
+            
+            if let error = error {
+                completionHandler(.failure(.networkError(error)))
+                return
+            }
+            
+            guard let httpResponse = response as? HTTPURLResponse else {
+                completionHandler(.failure(.invalidResponse))
+                return
+            }
+            
+            if let apiError = self?.handleStatusCode(with: httpResponse.statusCode) {
+                completionHandler(.failure(apiError))
+                return
+            }
+            
+            guard let data = data else {
+                completionHandler(.failure(.badRequest))
+                return
+            }
+            
+            do {
+                let decodedObject = try JSONDecoder().decode(T.self, from: data)
+                completionHandler(.success(decodedObject))
+            } catch {
+                completionHandler(.failure(.decodingError(error)))
+            }
+        }
+        
+        task.resume()
+    }
+    
+    private func handleStatusCode(with code: Int) -> APIError? {
+        switch code {
+        case 100..<200:
+            return APIError.informationResponse
+        case 200..<300:
+            return nil
+        case 300..<400:
+            return APIError.redirectionRequired
+        case 400..<500:
+            return APIError.clientError(code)
+        case 500...:
+            return APIError.serverError(code)
+        default:
+            return APIError.badRequest
+        }
+    }
+}
diff --git a/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManagerProtocol.swift b/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManagerProtocol.swift
index e2030f99..f92756d8 100644
--- a/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManagerProtocol.swift
+++ b/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManagerProtocol.swift
@@ -7,7 +7,7 @@
 
 import Foundation
 
-protocol AVIROAPIMangerProtocol: APIManagerProtocol {
+protocol AVIROAPIMangerProtocol: APIManagerProtocol {    
     // MARK: Marker Refer
     func loadNerbyPlaceModels(
         with mapModel: AVIROMapModelDTO,
@@ -39,11 +39,11 @@ protocol AVIROAPIMangerProtocol: APIManagerProtocol {
     // MARK: Create Refer
     func createPlaceModel(
         with placeModel: AVIROEnrollPlaceDTO,
-        completionHandler: @escaping(Result<AVIROResultDTO, APIError>) -> Void
+        completionHandler: @escaping(Result<AVIROChallengeResultDTO, APIError>) -> Void
     )
     func createReview(
         with reviewModel: AVIROEnrollReviewDTO,
-        completionHandler: @escaping(Result<AVIROEnrollReviewResultDTO, APIError>) -> Void
+        completionHandler: @escaping(Result<AVIROChallengeResultDTO, APIError>) -> Void
     )
     
     // MARK: Load Refer
diff --git a/AVIRO/Manager/APIManager/AVIROManager/AVIROPostAPI.swift b/AVIRO/Manager/APIManager/AVIROManager/AVIROPostAPI.swift
index 23dc2a4a..c0001bc8 100644
--- a/AVIRO/Manager/APIManager/AVIROManager/AVIROPostAPI.swift
+++ b/AVIRO/Manager/APIManager/AVIROManager/AVIROPostAPI.swift
@@ -32,6 +32,7 @@ struct AVIROPostAPI {
         "Content-Type": "application/json",
         "X-API-KEY": "\(AVIROConfiguration.apikey)"
     ]
+    
     static let placeEnrollPath = "/1/map/add/place"
     static let placeListMatchedAVIROPath = "/1/map/check/place"
     static let placeListReportPath = "/1/map/report/place"
diff --git a/AVIRO/Manager/APIManager/KakaoMapManager/KakaoAPI.swift b/AVIRO/Manager/APIManager/KakaoMapManager/KakaoAPI.swift
new file mode 100644
index 00000000..d1694c1f
--- /dev/null
+++ b/AVIRO/Manager/APIManager/KakaoMapManager/KakaoAPI.swift
@@ -0,0 +1,173 @@
+//
+//  KakaoMapRequestManager.swift
+//  VeganRestaurant
+//
+//  Created by 전성훈 on 2023/05/20.
+//
+
+import Foundation
+
+final class KakaoAPI: KakaoAPIManagerProtocol {
+    static let manager = KakaoAPI()
+    
+    var onRequest: Set<URL> = []
+
+    let session: URLSession
+    
+    let api = KakaoMapRequestAPI()
+    
+    private var kakaoMapAPIKey: String? = {
+        guard let path = Bundle.main.url(forResource: "API", withExtension: "plist"),
+              let dict = NSDictionary(contentsOf: path) as? [String: Any],
+              let key = dict["KakaoMapAPI_ Authorization _Key"] as? String else {
+            return nil
+        }
+        return key
+    }()
+    
+    private lazy var headers = ["Authorization": "\(kakaoMapAPIKey ?? "")"]
+    
+    private init(session: URLSession = .shared) {
+        self.session = session
+    }
+    
+    func keywordSearchPlace(
+        with model: KakaoKeywordSearchDTO,
+        completionHandler: @escaping (Result<KakaoKeywordResultDTO, APIError>) -> Void
+    ) {
+        guard let url = api.searchPlace(model: model).url else {
+            completionHandler(.failure(.urlError))
+            return
+        }
+        
+        performRequest(
+            with: url,
+            headers: headers,
+            completionHandler: completionHandler)
+    }
+    
+    func allSearchPlace(
+        with model: KakaoKeywordSearchDTO,
+        completionHandler: @escaping (Result<KakaoKeywordResultDTO, APIError>) -> Void
+    ) {
+        guard let url = api.searchLocation(model: model).url else {
+            completionHandler(.failure(.urlError))
+            return
+        }
+        
+        performRequest(
+            with: url,
+            headers: headers,
+            completionHandler: completionHandler
+        )
+    }
+    
+    func coordinateSearch(
+        with model: KakaoCoordinateSearchDTO,
+        completionHandler: @escaping (Result<KakaoCoordinateSearchResultDTO, APIError>) -> Void
+    ) {
+        guard let url = api.searchCoodinate(model: model).url else {
+            completionHandler(.failure(.urlError))
+            return
+        }
+        
+        performRequest(
+            with: url,
+            headers: headers,
+            completionHandler: completionHandler
+        )
+    }
+    
+    func addressSearch(
+        with address: String,
+        completionHandler: @escaping (Result<KakaoAddressPlaceDTO, APIError>) -> Void
+    ) {
+        guard let url = api.searchAddress(query: address).url else {
+            completionHandler(.failure(.urlError))
+            return
+        }
+        
+        performRequest(
+            with: url,
+            headers: headers,
+            completionHandler: completionHandler
+        )
+    }
+}
+
+extension KakaoAPI {
+    func performRequest<T>(
+        with url: URL,
+        httpMethod: HTTPMethodType = .get,
+        requestBody: Data? = nil,
+        headers: [String: String]? = nil,
+        completionHandler: @escaping (Result<T, APIError>) -> Void
+    ) where T: Decodable {
+        guard !onRequest.contains(url) else { return }
+        
+        onRequest.insert(url)
+        
+        var request = URLRequest(url: url)
+        
+        request.httpMethod = httpMethod.rawValue
+        request.httpBody = requestBody
+        
+        if let headers = headers {
+            for (key, value) in headers {
+                request.addValue(value, forHTTPHeaderField: key)
+            }
+        }
+        
+        let task = session.dataTask(with: request) { [weak self] data, response, error in
+            defer {
+                self?.onRequest.remove(url)
+            }
+            
+            if let error = error {
+                completionHandler(.failure(.networkError(error)))
+                return
+            }
+            
+            guard let httpResponse = response as? HTTPURLResponse else {
+                completionHandler(.failure(.invalidResponse))
+                return
+            }
+            
+            if let apiError = self?.handleStatusCode(with: httpResponse.statusCode) {
+                completionHandler(.failure(apiError))
+                return
+            }
+            
+            guard let data = data else {
+                completionHandler(.failure(.badRequest))
+                return
+            }
+            
+            do {
+                let decodedObject = try JSONDecoder().decode(T.self, from: data)
+                completionHandler(.success(decodedObject))
+            } catch {
+                completionHandler(.failure(.decodingError(error)))
+            }
+        }
+        
+        task.resume()
+    }
+    
+    private func handleStatusCode(with code: Int) -> APIError? {
+        switch code {
+        case 100..<200:
+            return APIError.informationResponse
+        case 200..<300:
+            return nil
+        case 300..<400:
+            return APIError.redirectionRequired
+        case 400..<500:
+            return APIError.clientError(code)
+        case 500...:
+            return APIError.serverError(code)
+        default:
+            return APIError.badRequest
+        }
+    }
+}
diff --git a/AVIRO/Manager/APIManager/KakaoMapManager/KakaoAPIManager.swift b/AVIRO/Manager/APIManager/KakaoMapManager/KakaoAPIManager.swift
deleted file mode 100644
index 8a1a3d30..00000000
--- a/AVIRO/Manager/APIManager/KakaoMapManager/KakaoAPIManager.swift
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-//  KakaoMapRequestManager.swift
-//  VeganRestaurant
-//
-//  Created by 전성훈 on 2023/05/20.
-//
-
-import Foundation
-
-final class KakaoAPIManager: KakaoAPIManagerProtocol {
-    let session: URLSession
-    
-    let api = KakaoMapRequestAPI()
-    
-    private var kakaoMapAPIKey: String? = {
-        guard let path = Bundle.main.url(forResource: "API", withExtension: "plist"),
-              let dict = NSDictionary(contentsOf: path) as? [String: Any],
-              let key = dict["KakaoMapAPI_ Authorization _Key"] as? String else {
-            return nil
-        }
-        return key
-    }()
-    
-    private lazy var headers = ["Authorization": "\(kakaoMapAPIKey ?? "")"]
-    
-    init(session: URLSession = .shared) {
-        self.session = session
-    }
-    
-    func keywordSearchPlace(
-        with model: KakaoKeywordSearchDTO,
-        completionHandler: @escaping (Result<KakaoKeywordResultDTO, APIError>) -> Void
-    ) {
-        guard let url = api.searchPlace(model: model).url else {
-            completionHandler(.failure(.urlError))
-            return
-        }
-        
-        performRequest(
-            with: url,
-            headers: headers,
-            completionHandler: completionHandler)
-    }
-    
-    func allSearchPlace(
-        with model: KakaoKeywordSearchDTO,
-        completionHandler: @escaping (Result<KakaoKeywordResultDTO, APIError>) -> Void
-    ) {
-        guard let url = api.searchLocation(model: model).url else {
-            completionHandler(.failure(.urlError))
-            return
-        }
-        
-        performRequest(
-            with: url,
-            headers: headers,
-            completionHandler: completionHandler
-        )
-    }
-    
-    func coordinateSearch(
-        with model: KakaoCoordinateSearchDTO,
-        completionHandler: @escaping (Result<KakaoCoordinateSearchResultDTO, APIError>) -> Void
-    ) {
-        guard let url = api.searchCoodinate(model: model).url else {
-            completionHandler(.failure(.urlError))
-            return
-        }
-        
-        performRequest(
-            with: url,
-            headers: headers,
-            completionHandler: completionHandler
-        )
-    }
-    
-    func addressSearch(
-        with address: String,
-        completionHandler: @escaping (Result<KakaoAddressPlaceDTO, APIError>) -> Void
-    ) {
-        guard let url = api.searchAddress(query: address).url else {
-            completionHandler(.failure(.urlError))
-            return
-        }
-        
-        performRequest(
-            with: url,
-            headers: headers,
-            completionHandler: completionHandler
-        )
-    }
-}
diff --git a/AVIRO/Manager/APIManager/PublicManager/PublicAPIManager.swift b/AVIRO/Manager/APIManager/PublicManager/PublicAPI.swift
similarity index 92%
rename from AVIRO/Manager/APIManager/PublicManager/PublicAPIManager.swift
rename to AVIRO/Manager/APIManager/PublicManager/PublicAPI.swift
index a310d5b3..fb79f305 100644
--- a/AVIRO/Manager/APIManager/PublicManager/PublicAPIManager.swift
+++ b/AVIRO/Manager/APIManager/PublicManager/PublicAPI.swift
@@ -14,11 +14,13 @@ protocol PublicAPIManagerProtocol {
         completion: @escaping (Result<PublicAddressDTO, Error>) -> Void)
 }
 
-final class PublicAPIManager: PublicAPIManagerProtocol {
+final class PublicAPI: PublicAPIManagerProtocol {
+    static let manager = PublicAPI()
+    
     private let session: URLSession
     let api = PublicAPIRequestComponents()
     
-    init(session: URLSession = .shared) {
+    private init(session: URLSession = .shared) {
         self.session = session
     }
     
diff --git a/AVIRO/Manager/FacadeManager/BookmarkManager.swift b/AVIRO/Manager/FacadeManager/BookmarkManager.swift
index 96c4b0d3..80ccf144 100644
--- a/AVIRO/Manager/FacadeManager/BookmarkManager.swift
+++ b/AVIRO/Manager/FacadeManager/BookmarkManager.swift
@@ -24,7 +24,7 @@ final class BookmarkFacadeManager: BookmarkFacadeProtocol {
     }
     
     func fetchAllData(completionHandler: @escaping ((String) -> Void)) {
-        AVIROAPIManager().loadBookmarkModels(with: MyData.my.id) { [weak self] result in
+        AVIROAPI.manager.loadBookmarkModels(with: MyData.my.id) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
@@ -81,7 +81,7 @@ final class BookmarkFacadeManager: BookmarkFacadeProtocol {
             userId: MyData.my.id
         )
         
-        AVIROAPIManager().createBookmarkModel(with: postModel) { result in
+        AVIROAPI.manager.createBookmarkModel(with: postModel) { result in
             switch result {
             case .success(let success):
                 if success.statusCode != 200 {
diff --git a/AVIRO/Manager/FacadeManager/MarkerModelManager.swift b/AVIRO/Manager/FacadeManager/MarkerModelManager.swift
index 4f52240d..86333066 100644
--- a/AVIRO/Manager/FacadeManager/MarkerModelManager.swift
+++ b/AVIRO/Manager/FacadeManager/MarkerModelManager.swift
@@ -75,7 +75,7 @@ final class MarkerModelManager: MarkerModelManagerProtocol {
             time: updateTime
         )
         
-        AVIROAPIManager().loadNerbyPlaceModels(with: mapModel) { result in
+        AVIROAPI.manager.loadNerbyPlaceModels(with: mapModel) { result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
@@ -133,7 +133,7 @@ final class MarkerModelManager: MarkerModelManagerProtocol {
             time: nil
         )
         
-        AVIROAPIManager().loadNerbyPlaceModels(with: model) { result in
+        AVIROAPI.manager.loadNerbyPlaceModels(with: model) { result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
@@ -193,7 +193,7 @@ final class MarkerModelManager: MarkerModelManagerProtocol {
             time: updateTime
         )
         
-        AVIROAPIManager().loadNerbyPlaceModels(with: mapModel) { [weak self] result in
+        AVIROAPI.manager.loadNerbyPlaceModels(with: mapModel) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
diff --git a/AVIRO/Model/APIResonseModel/AVIRO/AVIROPost/AVIROResult+DTO.swift b/AVIRO/Model/APIResonseModel/AVIRO/AVIROPost/AVIROResult+DTO.swift
index 3e3ac56b..d20ab2ef 100644
--- a/AVIRO/Model/APIResonseModel/AVIRO/AVIROPost/AVIROResult+DTO.swift
+++ b/AVIRO/Model/APIResonseModel/AVIRO/AVIROPost/AVIROResult+DTO.swift
@@ -12,3 +12,10 @@ struct AVIROResultDTO: Decodable {
     let statusCode: Int
     let message: String?
 }
+
+struct AVIROChallengeResultDTO: Decodable {
+    let statusCode: Int
+    let message: String
+    let levelUp: Bool?
+    let userLevel: Int?
+}
diff --git a/AVIRO/Model/APIResonseModel/AVIRO/AVIROPost/Enroll/AVIROReview+DTO.swift b/AVIRO/Model/APIResonseModel/AVIRO/AVIROPost/Enroll/AVIROReview+DTO.swift
index ce598016..683e38ae 100644
--- a/AVIRO/Model/APIResonseModel/AVIRO/AVIROPost/Enroll/AVIROReview+DTO.swift
+++ b/AVIRO/Model/APIResonseModel/AVIRO/AVIROPost/Enroll/AVIROReview+DTO.swift
@@ -14,13 +14,6 @@ struct AVIROEnrollReviewDTO: Encodable {
     let content: String
 }
 
-struct AVIROEnrollReviewResultDTO: Decodable {
-    let statusCode: Int
-    let message: String
-    let levelUp: Bool?
-    let userLevel: Int?
-}
-
 struct AVIROEditReviewDTO: Encodable {
     let commentId: String
     let content: String
diff --git a/AVIRO/Scene/Base/AVIROTabBarController.swift b/AVIRO/Scene/Base/AVIROTabBarController.swift
index d9a0261a..e00b1bc9 100644
--- a/AVIRO/Scene/Base/AVIROTabBarController.swift
+++ b/AVIRO/Scene/Base/AVIROTabBarController.swift
@@ -60,7 +60,9 @@ enum TabBarType: CaseIterable {
 
 protocol TabBarDelegate: AnyObject {
     var selectedIndex: Int { get set }
-    var isHidden: (isHidden: Bool,isSameNavi: Bool) { get set }
+    var isHidden: (isHidden: Bool, isSameNavi: Bool) { get set }
+    
+    func hideBlurEffectView(with active: Bool)
 }
 
 final class AVIROTabBarController: UIViewController, TabBarDelegate {
@@ -73,6 +75,10 @@ final class AVIROTabBarController: UIViewController, TabBarDelegate {
         let view = UIView()
         
         view.backgroundColor = .gray7
+        view.layer.shadowOpacity = 0.1
+        view.layer.shadowRadius = 3.0
+        view.layer.shadowColor = UIColor.gray0.cgColor
+        view.layer.shadowOffset = CGSize(width: 0, height: -1)
         
         return view
     }()
@@ -85,6 +91,17 @@ final class AVIROTabBarController: UIViewController, TabBarDelegate {
         return view
     }()
     
+    private lazy var blurEffectView: UIVisualEffectView = {
+        let view = UIVisualEffectView()
+        
+        let blurEffect = UIBlurEffect(style: .dark)
+        
+        view.effect = blurEffect
+        view.alpha = 0.6
+        
+        return view
+    }()
+    
     var selectedIndex: Int = 0 {
         willSet {
             previousIndex = selectedIndex
@@ -102,7 +119,6 @@ final class AVIROTabBarController: UIViewController, TabBarDelegate {
     
     var isHidden: (isHidden: Bool,isSameNavi: Bool) = (false,true) {
         didSet {
-            print(isHidden)
             tabBarView.isHidden = isHidden.isHidden
             bottomInsetView.isHidden = isHidden.isHidden
             
@@ -127,35 +143,35 @@ final class AVIROTabBarController: UIViewController, TabBarDelegate {
     func setViewControllers(with types: [TabBarType]) {
         
         self.types = types
-        types.forEach { tabBarType in
-            switch tabBarType {
-            case .home:
-                let vc = HomeViewController()
-                vc.tabBarDelegate = self
-                
-                let navigationVC = UINavigationController(rootViewController: vc)
-                viewControllers.append(navigationVC)
-            case .plus:
-                let vc = EnrollPlaceViewController()
-                vc.tabBarDelegate = self
-                
-                let navigationVC = UINavigationController(rootViewController: vc)
-                viewControllers.append(navigationVC)
-            case .challenge:
-                let viewModel = ChallengeViewModel()
-                let vc = ChallengeViewController.create(with: viewModel)
-                vc.tabBarDelegate = self
-                
-                let navigationVC = UINavigationController(rootViewController: vc)
-                viewControllers.append(navigationVC)
-            }
-        }
+        let home = HomeViewController()
+        
+        let enroll = EnrollPlaceViewController()
+        
+        let challengeViewModel = ChallengeViewModel()
+        let challenge = ChallengeViewController.create(with: challengeViewModel)
+        
+        home.tabBarDelegate = self
+        enroll.tabBarDelegate = self
+        challenge.tabBarDelegate = self
+        
+        enroll.homeViewDelegate = home
+        
+        let homeNaviVC = UINavigationController(rootViewController: home)
+        let enrollNaviVC = UINavigationController(rootViewController: enroll)
+        let challengeNaviVC = UINavigationController(rootViewController: challenge)
+        
+        viewControllers.append(contentsOf: [
+            homeNaviVC,
+            enrollNaviVC,
+            challengeNaviVC
+        ])
     }
     
     private func setupLayout() {
         [
             tabBarView,
-            bottomInsetView
+            bottomInsetView,
+            blurEffectView
         ].forEach {
             $0.translatesAutoresizingMaskIntoConstraints = false
             self.view.addSubview($0)
@@ -170,9 +186,16 @@ final class AVIROTabBarController: UIViewController, TabBarDelegate {
             bottomInsetView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),
             bottomInsetView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),
             bottomInsetView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
-            bottomInsetView.topAnchor.constraint(equalTo: tabBarView.bottomAnchor)
+            bottomInsetView.topAnchor.constraint(equalTo: tabBarView.bottomAnchor),
+            
+            blurEffectView.topAnchor.constraint(equalTo: tabBarView.topAnchor),
+            blurEffectView.leadingAnchor.constraint(equalTo: tabBarView.leadingAnchor),
+            blurEffectView.trailingAnchor.constraint(equalTo: tabBarView.trailingAnchor),
+            blurEffectView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor)
         ])
         
+        blurEffectView.isHidden = true
+        
         setupButtons()
     }
     
@@ -260,4 +283,8 @@ final class AVIROTabBarController: UIViewController, TabBarDelegate {
     @objc private func tabBarButtonTapped(_ sender: TabBarButton) {
         selectedIndex = sender.tag
     }
+    
+    func hideBlurEffectView(with active: Bool) {
+        blurEffectView.isHidden = active
+    }
 }
diff --git a/AVIRO/Scene/Feature/Challenge/Setting/NicknameChangeableView/ViewPresenter/NickNameChangeblePresenter.swift b/AVIRO/Scene/Feature/Challenge/Setting/NicknameChangeableView/ViewPresenter/NickNameChangeblePresenter.swift
index 6b0234a9..8c62d156 100644
--- a/AVIRO/Scene/Feature/Challenge/Setting/NicknameChangeableView/ViewPresenter/NickNameChangeblePresenter.swift
+++ b/AVIRO/Scene/Feature/Challenge/Setting/NicknameChangeableView/ViewPresenter/NickNameChangeblePresenter.swift
@@ -43,7 +43,7 @@ final class NickNameChangeblePresenter {
         let nickname = AVIRONicknameIsDuplicatedCheckDTO(nickname: userNickname)
         
         if userNickname != initNickName {
-            AVIROAPIManager().checkNickname(with: nickname) { [weak self] result in
+            AVIROAPI.manager.checkNickname(with: nickname) { [weak self] result in
                 switch result {
                 case .success(let model):
                     if model.statusCode == 200 {
@@ -73,7 +73,7 @@ final class NickNameChangeblePresenter {
             nickname: userNickname
         )
         
-        AVIROAPIManager().editNickname(with: model) { [weak self] result in
+        AVIROAPI.manager.editNickname(with: model) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Challenge/Setting/ViewPresenter/SettingViewPresenter.swift b/AVIRO/Scene/Feature/Challenge/Setting/ViewPresenter/SettingViewPresenter.swift
index 3235034a..c98d8d54 100644
--- a/AVIRO/Scene/Feature/Challenge/Setting/ViewPresenter/SettingViewPresenter.swift
+++ b/AVIRO/Scene/Feature/Challenge/Setting/ViewPresenter/SettingViewPresenter.swift
@@ -113,7 +113,7 @@ final class SettingViewPresenter {
 
         let model = AVIROAutoLoginWhenAppleUserDTO(refreshToken: refreshToken)
                         
-        AVIROAPIManager().revokeAppleUser(with: model) { [weak self] result in
+        AVIROAPI.manager.revokeAppleUser(with: model) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeLevelView.swift b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeLevelView.swift
index c3e23e18..8a0739f2 100644
--- a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeLevelView.swift
+++ b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeLevelView.swift
@@ -135,6 +135,8 @@ final class ChallengeLevelView: UIView {
         
         levelPointLabel.attributedText = attributedText
         
-        levelProgress.progress = Float(Double(levelPoint.now)!/Double(levelPoint.gool)!)
+        let currentProgress = Float(levelPoint.now)! / Float(levelPoint.gool)!
+
+        levelProgress.setProgress(currentProgress, animated: true)
     }
 }
diff --git a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeUserInfoView.swift b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeUserInfoView.swift
index e1e1f84d..9d575970 100644
--- a/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeUserInfoView.swift
+++ b/AVIRO/Scene/Feature/Challenge/ViewController/ChallengeUserInfoView/ChallengeUserInfoView.swift
@@ -24,7 +24,7 @@ final class ChallengeUserInfoView: UIView {
         imageView.layer.cornerRadius = 150/2
         imageView.backgroundColor = .gray7
         imageView.contentMode = .scaleAspectFill
-        imageView.layer.borderWidth = 10
+        imageView.layer.borderWidth = 5
         imageView.layer.borderColor = UIColor.challengeImageBorder.cgColor
         
         return imageView
@@ -87,7 +87,12 @@ final class ChallengeUserInfoView: UIView {
         
         nameLabel.text = "\(MyData.my.nickname)님의 나무"
         
-        levelView.updateLankLabel(with: "참여중인 \(total)명 중 \(rank)등이에요!")
+        if level == 1 && point == 0 {
+            levelView.updateLankLabel(with: "포인트를 모아 나무를 성장시켜보세요!")
+        } else {
+            levelView.updateLankLabel(with: "참여중인 \(total)명 중 \(rank)등이에요!")
+        }
+        
         levelView.updateLevelLabel(with: "레벨 \(level) 달성했어요!")
         levelView.updateLevelPoint(with: LevelPoint("\(point)", "\(pointForNext)"))
         
diff --git a/AVIRO/Scene/Feature/Challenge/ViewModel/ChallengeViewModel.swift b/AVIRO/Scene/Feature/Challenge/ViewModel/ChallengeViewModel.swift
index 68a1dc54..af4acccb 100644
--- a/AVIRO/Scene/Feature/Challenge/ViewModel/ChallengeViewModel.swift
+++ b/AVIRO/Scene/Feature/Challenge/ViewModel/ChallengeViewModel.swift
@@ -93,7 +93,7 @@ final class ChallengeViewModel: ViewModel {
     
     private func loadMyContributedCountAPI(userId: String) -> Single<AVIROMyContributionCountDTO> {
         return Single.create { single in
-            AVIROAPIManager().loadMyContributedCount(with: userId) { result in
+            AVIROAPI.manager.loadMyContributedCount(with: userId) { result in
                 switch result {
                 case .success(let data):
                     single(.success(data))
@@ -107,7 +107,7 @@ final class ChallengeViewModel: ViewModel {
 
     private func loadChallengeInfoAPI() -> Single<AVIROChallengeInfoDTO> {
         return Single.create { single in
-            AVIROAPIManager().loadChallengeInfo { result in
+            AVIROAPI.manager.loadChallengeInfo { result in
                 switch result {
                 case .success(let data):
                     single(.success(data))
@@ -121,7 +121,7 @@ final class ChallengeViewModel: ViewModel {
     
     private func loadMyChallengeLevelAPI(userId: String) -> Single<AVIROMyChallengeLevelResultDTO> {
         return Single.create { single in
-            AVIROAPIManager().loadMyChallengeLevel(with: userId) { result in
+            AVIROAPI.manager.loadMyChallengeLevel(with: userId) { result in
                 switch result {
                 case .success(let data):
                     single(.success(data))
diff --git a/AVIRO/Scene/Feature/Enroll/SearchPlaceView/ViewPresenter/SearchPlacePresenter.swift b/AVIRO/Scene/Feature/Enroll/SearchPlaceView/ViewPresenter/SearchPlacePresenter.swift
index 7c7b6c23..60171d24 100644
--- a/AVIRO/Scene/Feature/Enroll/SearchPlaceView/ViewPresenter/SearchPlacePresenter.swift
+++ b/AVIRO/Scene/Feature/Enroll/SearchPlaceView/ViewPresenter/SearchPlacePresenter.swift
@@ -77,7 +77,7 @@ final class SearchPlacePresenter: NSObject {
             isAccuracy: nil
         )
         
-        KakaoAPIManager().keywordSearchPlace(with: model) { [weak self] result in
+        KakaoAPI.manager.keywordSearchPlace(with: model) { [weak self] result in
             switch result {
             case .success(let listModel):
                 let placeList = listModel.documents.map { location in
@@ -138,7 +138,7 @@ final class SearchPlacePresenter: NSObject {
             isAccuracy: nil
         )
         
-        KakaoAPIManager().keywordSearchPlace(with: model) { [weak self] result in
+        KakaoAPI.manager.keywordSearchPlace(with: model) { [weak self] result in
             switch result {
             case .success(let listModel):
                 let placeList = listModel.documents.map { location in
@@ -177,7 +177,7 @@ final class SearchPlacePresenter: NSObject {
             y: String(selectedItem.y)
         )
         
-        AVIROAPIManager().checkPlaceOne(with: placeModel) { [weak self] result in
+        AVIROAPI.manager.checkPlaceOne(with: placeModel) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Enroll/ViewController/EnrollPlaceViewController.swift b/AVIRO/Scene/Feature/Enroll/ViewController/EnrollPlaceViewController.swift
index 1e8d7f4c..fb842abf 100644
--- a/AVIRO/Scene/Feature/Enroll/ViewController/EnrollPlaceViewController.swift
+++ b/AVIRO/Scene/Feature/Enroll/ViewController/EnrollPlaceViewController.swift
@@ -13,6 +13,7 @@ private enum Text: String {
 
 final class EnrollPlaceViewController: UIViewController, AVIROViewController {
     weak var tabBarDelegate: TabBarDelegate?
+    weak var homeViewDelegate: AfterHomeViewControllerProtocol?
     
     lazy var presenter = EnrollPlacePresenter(viewController: self)
     
@@ -241,10 +242,15 @@ extension EnrollPlaceViewController: EnrollPlaceProtocol {
     }
     
     // MARK: Pop View Controller
-    func popViewController() {
+    func popViewController(level: Int, isLevelUp: Bool) {
         DispatchQueue.main.async { [weak self] in
+            if isLevelUp {
+                self?.homeViewDelegate?.showLevelUpAlert(with: level)
+            }
+            
             self?.initData()
-            self?.tabBarController?.selectedIndex = 0
+            self?.tabBarDelegate?.selectedIndex = 0
+            self?.tabBarDelegate?.isHidden = (false, false)
         }
     }
     
diff --git a/AVIRO/Scene/Feature/Enroll/ViewPresenter/EnrollPlacePresenter.swift b/AVIRO/Scene/Feature/Enroll/ViewPresenter/EnrollPlacePresenter.swift
index e6546aca..969e07a6 100644
--- a/AVIRO/Scene/Feature/Enroll/ViewPresenter/EnrollPlacePresenter.swift
+++ b/AVIRO/Scene/Feature/Enroll/ViewPresenter/EnrollPlacePresenter.swift
@@ -20,7 +20,7 @@ protocol EnrollPlaceProtocol: NSObject {
     func keyboardWillShow(height: CGFloat, isFirst: Bool)
     func keyboardWillHide()
     func enableRightButton(_ bool: Bool)
-    func popViewController()
+    func popViewController(level: Int, isLevelUp: Bool)
     func pushAlertController()
     func showErrorAlert(with error: String, title: String?)
 }
@@ -122,23 +122,23 @@ final class EnrollPlacePresenter {
             return
         }
         
-        AVIROAPIManager().createPlaceModel(with: veganModel) { [weak self] result in
+        AVIROAPI.manager.createPlaceModel(with: veganModel) { [weak self] result in
             switch result {
-            case .success(let success):
-                if success.statusCode == 200 {
+            case .success(let resultModel):
+                if resultModel.statusCode == 200 {
                     self?.amplitude.uploadPlace(with: veganModel.title)
                     
                     CenterCoordinate.shared.longitude = veganModel.x
                     CenterCoordinate.shared.latitude = veganModel.y
                     CenterCoordinate.shared.isChangedFromEnrollView = true
-
-                    self?.viewController?.popViewController()
-                } else if success.statusCode == 400 {
-                    self?.viewController?.pushAlertController()
+                    
+                    self?.viewController?.popViewController(
+                        level: resultModel.userLevel ?? 0,
+                        isLevelUp: resultModel.levelUp ?? false
+                    )
+                    
                 } else {
-                    if let message = success.message {
-                        self?.viewController?.showErrorAlert(with: message, title: nil)
-                    }
+                    self?.viewController?.pushAlertController()
                 }
             case .failure(let error):
                 if let error = error.errorDescription {
diff --git a/AVIRO/Scene/Feature/Home/EditMenu/ViewPresenter/EditMenuPresenter.swift b/AVIRO/Scene/Feature/Home/EditMenu/ViewPresenter/EditMenuPresenter.swift
index 15fd189c..a74c5a44 100644
--- a/AVIRO/Scene/Feature/Home/EditMenu/ViewPresenter/EditMenuPresenter.swift
+++ b/AVIRO/Scene/Feature/Home/EditMenu/ViewPresenter/EditMenuPresenter.swift
@@ -906,7 +906,7 @@ final class EditMenuPresenter {
             isRequest: isRequest
         )
         
-        AVIROAPIManager().editMenu(with: editMenu) { [weak self] result in
+        AVIROAPI.manager.editMenu(with: editMenu) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Home/EditPlaceInfo/ChangeableAddressView/ViewPresenter/ChangeableAddressPresenter.swift b/AVIRO/Scene/Feature/Home/EditPlaceInfo/ChangeableAddressView/ViewPresenter/ChangeableAddressPresenter.swift
index 72f39d03..a43f9a9e 100644
--- a/AVIRO/Scene/Feature/Home/EditPlaceInfo/ChangeableAddressView/ViewPresenter/ChangeableAddressPresenter.swift
+++ b/AVIRO/Scene/Feature/Home/EditPlaceInfo/ChangeableAddressView/ViewPresenter/ChangeableAddressPresenter.swift
@@ -80,7 +80,7 @@ final class ChangeableAddressPresenter {
         pageIndex = 1
         self.changedColorText = text
         
-        PublicAPIManager().publicAddressSearch(currentPage: String(pageIndex), keyword: text) { [weak self] result in
+        PublicAPI.manager.publicAddressSearch(currentPage: String(pageIndex), keyword: text) { [weak self] result in
             switch result {
             case .success(let addressTableModel):
                 guard let totalCount = addressTableModel.totalCount else { return }
@@ -96,7 +96,7 @@ final class ChangeableAddressPresenter {
     func whenScrollingTableView() {
         if totalCount > pageIndex * 20 {
             pageIndex += 1
-            PublicAPIManager().publicAddressSearch(
+            PublicAPI.manager.publicAddressSearch(
                 currentPage: String(pageIndex),
                 keyword: changedColorText
             ) { [weak self] result in
@@ -131,7 +131,7 @@ final class ChangeableAddressPresenter {
         
         let model = KakaoCoordinateSearchDTO(lng: lng, lat: lat)
         
-        KakaoAPIManager().coordinateSearch(with: model) { [weak self] result in
+        KakaoAPI.manager.coordinateSearch(with: model) { [weak self] result in
             switch result {
             case .success(let model):
                 guard let firstDocument = model.documents?.first,
diff --git a/AVIRO/Scene/Feature/Home/EditPlaceInfo/ViewPresenter/EditPlaceInfoPresenter.swift b/AVIRO/Scene/Feature/Home/EditPlaceInfo/ViewPresenter/EditPlaceInfoPresenter.swift
index 9d7439d6..0efbd999 100644
--- a/AVIRO/Scene/Feature/Home/EditPlaceInfo/ViewPresenter/EditPlaceInfoPresenter.swift
+++ b/AVIRO/Scene/Feature/Home/EditPlaceInfo/ViewPresenter/EditPlaceInfoPresenter.swift
@@ -299,7 +299,7 @@ final class EditPlaceInfoPresenter {
         
         self.placeOperationModels = [EditOperationHoursModel]()
         
-        AVIROAPIManager().loadOperationHours(with: placeId) { [weak self] result in
+        AVIROAPI.manager.loadOperationHours(with: placeId) { [weak self] result in
             switch result {
             case .success(let model):
                 if model.statusCode == 200 {
@@ -347,7 +347,7 @@ final class EditPlaceInfoPresenter {
     }
     
     private func changeLocationFromKakaoAPI() {
-        KakaoAPIManager().addressSearch(with: afterChangedAddress) { [weak self] result in
+        KakaoAPI.manager.addressSearch(with: afterChangedAddress) { [weak self] result in
             switch result {
             case .success(let model):
                 guard let documents = model.documents,
@@ -638,7 +638,7 @@ extension EditPlaceInfoPresenter {
                 y: whenRequestAndLoadYLatitude(beforeAddress: beforeAddress)
             )
 
-            AVIROAPIManager().editPlaceLocation(with: model) { [weak self] result in
+            AVIROAPI.manager.editPlaceLocation(with: model) { [weak self] result in
                 defer { dispatchGroup.leave() }
                 switch result {
                 case .success(let success):
@@ -762,7 +762,7 @@ extension EditPlaceInfoPresenter {
                 )
             )
             
-            AVIROAPIManager().editPlacePhone(with: model) { [weak self] result in
+            AVIROAPI.manager.editPlacePhone(with: model) { [weak self] result in
                 defer { dispatchGroup.leave() }
                 switch result {
                 case .success(let success):
@@ -824,7 +824,7 @@ extension EditPlaceInfoPresenter {
                 sunBreak: operationHours[.sun]?.breakTime
             )
             
-            AVIROAPIManager().editPlaceOperation(with: model) { [weak self] result in
+            AVIROAPI.manager.editPlaceOperation(with: model) { [weak self] result in
                 defer { dispatchGroup.leave() }
                 switch result {
                 case .success(let success):
@@ -869,7 +869,7 @@ extension EditPlaceInfoPresenter {
                 )
             )
             
-            AVIROAPIManager().editPlaceURL(with: model) { [weak self] result in
+            AVIROAPI.manager.editPlaceURL(with: model) { [weak self] result in
                 defer { dispatchGroup.leave() }
                 switch result {
                 case .success(let success):
diff --git a/AVIRO/Scene/Feature/Home/HomeSearch/ViewPresenter/HomeSearchPresenter.swift b/AVIRO/Scene/Feature/Home/HomeSearch/ViewPresenter/HomeSearchPresenter.swift
index 07a6b146..cf8e4bd7 100644
--- a/AVIRO/Scene/Feature/Home/HomeSearch/ViewPresenter/HomeSearchPresenter.swift
+++ b/AVIRO/Scene/Feature/Home/HomeSearch/ViewPresenter/HomeSearchPresenter.swift
@@ -224,7 +224,7 @@ final class HomeSearchPresenter {
             isAccuracy: KakaoAPISortingQuery.shared.sorting
         )
         
-        KakaoAPIManager().allSearchPlace(with: model) { [weak self] result in
+        KakaoAPI.manager.allSearchPlace(with: model) { [weak self] result in
             switch result {
             case .success(let model):
                 let placeList = model.documents.map { location in
@@ -273,7 +273,7 @@ final class HomeSearchPresenter {
                 
         let beforeMatchedRequestModel = AVIROBeforeComparePlaceDTO(placeArray: beforeMatchedArray)
                 
-        AVIROAPIManager().checkPlaceList(with: beforeMatchedRequestModel) { [weak self] result in
+        AVIROAPI.manager.checkPlaceList(with: beforeMatchedRequestModel) { [weak self] result in
             switch result {
             case .success(let model):
                 if model.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Home/Report/ViewPresenter/ReportReviewPresenter.swift b/AVIRO/Scene/Feature/Home/Report/ViewPresenter/ReportReviewPresenter.swift
index c13fbbec..22e97574 100644
--- a/AVIRO/Scene/Feature/Home/Report/ViewPresenter/ReportReviewPresenter.swift
+++ b/AVIRO/Scene/Feature/Home/Report/ViewPresenter/ReportReviewPresenter.swift
@@ -160,7 +160,7 @@ final class ReportReviewPresenter {
             content: typeString
         )
          
-        AVIROAPIManager().reportReview(with: reportModel) { [weak self] result in
+        AVIROAPI.manager.reportReview(with: reportModel) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Home/ReviewWriteView/ViewModel/ReviewWriteViewModel.swift b/AVIRO/Scene/Feature/Home/ReviewWriteView/ViewModel/ReviewWriteViewModel.swift
index 99e3b7f6..5ada92ec 100644
--- a/AVIRO/Scene/Feature/Home/ReviewWriteView/ViewModel/ReviewWriteViewModel.swift
+++ b/AVIRO/Scene/Feature/Home/ReviewWriteView/ViewModel/ReviewWriteViewModel.swift
@@ -168,7 +168,7 @@ final class ReviewWriteViewModel: ViewModel {
     
     private func updateReview(with reviewModel: AVIROEnrollReviewDTO) -> Single<(AfterWriteReviewModel, Bool)> {
         return Single.create { single in
-            AVIROAPIManager().createReview(with: reviewModel) { [weak self] result in
+            AVIROAPI.manager.createReview(with: reviewModel) { [weak self] result in
                 
                 switch result {
                 case .success(let model):
@@ -206,7 +206,7 @@ final class ReviewWriteViewModel: ViewModel {
         )
         
         return Single.create { single in
-            AVIROAPIManager().editReview(with: model) { [weak self] result in
+            AVIROAPI.manager.editReview(with: model) { [weak self] result in
                 switch result {
                 case .success(let model):
                     if model.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Home/ViewController/HomeViewController.swift b/AVIRO/Scene/Feature/Home/ViewController/HomeViewController.swift
index 9522b14a..c617e691 100644
--- a/AVIRO/Scene/Feature/Home/ViewController/HomeViewController.swift
+++ b/AVIRO/Scene/Feature/Home/ViewController/HomeViewController.swift
@@ -182,7 +182,7 @@ final class HomeViewController: UIViewController, AVIROViewController {
         let blurEffect = UIBlurEffect(style: .dark)
         
         view.effect = blurEffect
-        view.frame = self.view.frame
+//        view.frame = self.view.frame
         view.alpha = 0.6
         
         return view
@@ -1117,6 +1117,7 @@ extension HomeViewController: AfterHomeViewControllerProtocol {
         // MARK: Update Review 추가
         updateReview(with: model)
 
+        tabBarDelegate?.hideBlurEffectView(with: false)
         blurEffectView.isHidden = false
         recommendPlaceAlertView.isHidden = false
 
@@ -1127,6 +1128,7 @@ extension HomeViewController: AfterHomeViewControllerProtocol {
             if model.levelUp {
                 self?.showLevelUpAlert(with: model.userLevel)
             } else {
+                self?.tabBarDelegate?.hideBlurEffectView(with: true)
                 self?.blurEffectView.isHidden = true
             }
             
@@ -1138,6 +1140,7 @@ extension HomeViewController: AfterHomeViewControllerProtocol {
             if model.levelUp {
                 self?.showLevelUpAlert(with: model.userLevel)
             } else {
+                self?.tabBarDelegate?.hideBlurEffectView(with: true)
                 self?.blurEffectView.isHidden = true
             }
         }
@@ -1168,10 +1171,13 @@ extension HomeViewController: AfterHomeViewControllerProtocol {
     
     func showLevelUpAlert(with level: Int) {
         levelUpAlertView.setMainTitle(with: level)
+        
+        tabBarDelegate?.hideBlurEffectView(with: false)
         blurEffectView.isHidden = false
         levelUpAlertView.isHidden = false
         
         levelUpAlertView.afterTappedCheckButtonTapped = { [weak self] in
+            self?.tabBarDelegate?.hideBlurEffectView(with: true)
             self?.blurEffectView.isHidden = true
             self?.levelUpAlertView.isHidden = true
             
@@ -1179,6 +1185,7 @@ extension HomeViewController: AfterHomeViewControllerProtocol {
         }
         
         levelUpAlertView.afterTappedNoCheckButtonTapped = { [weak self] in
+            self?.tabBarDelegate?.hideBlurEffectView(with: true)
             self?.blurEffectView.isHidden = true
             self?.levelUpAlertView.isHidden = true
         }
diff --git a/AVIRO/Scene/Feature/Home/ViewPresenter/HomeViewPresenter.swift b/AVIRO/Scene/Feature/Home/ViewPresenter/HomeViewPresenter.swift
index 6a7a7327..184ac246 100644
--- a/AVIRO/Scene/Feature/Home/ViewPresenter/HomeViewPresenter.swift
+++ b/AVIRO/Scene/Feature/Home/ViewPresenter/HomeViewPresenter.swift
@@ -409,7 +409,7 @@ final class HomeViewPresenter: NSObject {
 
         selectedPlaceId = placeId
         
-        AVIROAPIManager().loadPlaceSummary(with: placeId) { [weak self] result in
+        AVIROAPI.manager.loadPlaceSummary(with: placeId) { [weak self] result in
             switch result {
             case .success(let summary):
                 if summary.statusCode == 200 {
@@ -582,7 +582,7 @@ final class HomeViewPresenter: NSObject {
     
     private func loadPlaceInfo(with placeId: String, dispatchGroup: DispatchGroup) {
         dispatchGroup.enter()
-        AVIROAPIManager().loadPlaceInfo(with: placeId) { [weak self] result in
+        AVIROAPI.manager.loadPlaceInfo(with: placeId) { [weak self] result in
             defer { dispatchGroup.leave() }
             
             switch result {
@@ -604,7 +604,7 @@ final class HomeViewPresenter: NSObject {
     
     private func loadPlaceMenus(with placeId: String, dispatchGroup: DispatchGroup) {
         dispatchGroup.enter()
-        AVIROAPIManager().loadMenus(with: placeId) { [weak self] result in
+        AVIROAPI.manager.loadMenus(with: placeId) { [weak self] result in
             defer { dispatchGroup.leave() }
             
             switch result {
@@ -626,7 +626,7 @@ final class HomeViewPresenter: NSObject {
     
     private func loadPlaceReviews(with placeId: String, dispatchGroup: DispatchGroup) {
         dispatchGroup.enter()
-        AVIROAPIManager().loadReviews(with: placeId) { [weak self] result in
+        AVIROAPI.manager.loadReviews(with: placeId) { [weak self] result in
             defer { dispatchGroup.leave() }
             
             switch result {
@@ -656,7 +656,7 @@ final class HomeViewPresenter: NSObject {
             code: type.code
         )
 
-        AVIROAPIManager().reportPlace(with: model) { [weak self] result in
+        AVIROAPI.manager.reportPlace(with: model) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
@@ -682,7 +682,7 @@ final class HomeViewPresenter: NSObject {
             userId: MyData.my.id
         )
         
-        AVIROAPIManager().checkPlaceReportIsDuplicated(with: model) { [weak self] result in
+        AVIROAPI.manager.checkPlaceReportIsDuplicated(with: model) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
@@ -712,7 +712,7 @@ final class HomeViewPresenter: NSObject {
     func loadPlaceOperationHours() {
         guard let placeId = selectedPlaceId else { return }
         
-        AVIROAPIManager().loadOperationHours(with: placeId) { [weak self] result in
+        AVIROAPI.manager.loadOperationHours(with: placeId) { [weak self] result in
             switch result {
             case .success(let model):
                 if model.statusCode == 200 {
@@ -776,7 +776,7 @@ final class HomeViewPresenter: NSObject {
     
     func afterEditMenu() {
         guard let placeId = selectedPlaceId else { return }
-        AVIROAPIManager().loadMenus(with: placeId) { [weak self] result in
+        AVIROAPI.manager.loadMenus(with: placeId) { [weak self] result in
             switch result {
             case .success(let menuModel):
                 if menuModel.statusCode == 200 {
@@ -859,7 +859,7 @@ final class HomeViewPresenter: NSObject {
 //    }
     
     func deleteMyReview(_ postDeleteReviewModel: AVIRODeleteReveiwDTO) {
-        AVIROAPIManager().deleteReview(with: postDeleteReviewModel) { [weak self] result in
+        AVIROAPI.manager.deleteReview(with: postDeleteReviewModel) { [weak self] result in
             switch result {
             case .success(let model):
                 if model.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Login/Registration/ViewPresenter/FirstRegistrationPresenter.swift b/AVIRO/Scene/Feature/Login/Registration/ViewPresenter/FirstRegistrationPresenter.swift
index f619fe60..ec0361a5 100644
--- a/AVIRO/Scene/Feature/Login/Registration/ViewPresenter/FirstRegistrationPresenter.swift
+++ b/AVIRO/Scene/Feature/Login/Registration/ViewPresenter/FirstRegistrationPresenter.swift
@@ -67,7 +67,7 @@ final class FirstRegistrationPresenter {
         
         let nickname = AVIRONicknameIsDuplicatedCheckDTO(nickname: userNickname)
         
-        AVIROAPIManager().checkNickname(with: nickname) { [weak self] result in
+        AVIROAPI.manager.checkNickname(with: nickname) { [weak self] result in
             switch result {
             case .success(let model):
                 if model.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Login/Registration/ViewPresenter/ThridRegistrationPresenter.swift b/AVIRO/Scene/Feature/Login/Registration/ViewPresenter/ThridRegistrationPresenter.swift
index 2d7e0c7d..0ddbfd36 100644
--- a/AVIRO/Scene/Feature/Login/Registration/ViewPresenter/ThridRegistrationPresenter.swift
+++ b/AVIRO/Scene/Feature/Login/Registration/ViewPresenter/ThridRegistrationPresenter.swift
@@ -69,7 +69,7 @@ final class ThridRegistrationPresenter {
         
         userInfoModel.marketingAgree = false
                 
-        AVIROAPIManager().createAppleUser(with: userInfoModel) { [weak self] result in
+        AVIROAPI.manager.createAppleUser(with: userInfoModel) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
diff --git a/AVIRO/Scene/Feature/Login/ViewPresenter/LoginViewPresenter.swift b/AVIRO/Scene/Feature/Login/ViewPresenter/LoginViewPresenter.swift
index dddf8f63..0c0038db 100644
--- a/AVIRO/Scene/Feature/Login/ViewPresenter/LoginViewPresenter.swift
+++ b/AVIRO/Scene/Feature/Login/ViewPresenter/LoginViewPresenter.swift
@@ -77,7 +77,7 @@ final class LoginViewPresenter: NSObject {
             authorizationCode: model.authorizationCode
         )
                 
-        AVIROAPIManager().checkWhenAppleLogin(with: checkAppleLoginModel) { [weak self] result in
+        AVIROAPI.manager.checkWhenAppleLogin(with: checkAppleLoginModel) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {
@@ -127,7 +127,7 @@ final class LoginViewPresenter: NSObject {
         
         let model = AVIROAutoLoginWhenAppleUserDTO(refreshToken: refreshToken)
         
-        AVIROAPIManager().appleUserCheck(with: model) { [weak self] result in
+        AVIROAPI.manager.appleUserCheck(with: model) { [weak self] result in
             switch result {
             case .success(let success):
                 if success.statusCode == 200 {