Skip to content
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
170 changes: 77 additions & 93 deletions ACON-iOS/ACON-iOS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions ACON-iOS/ACON-iOS/Global/Literals/StringLiterals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ enum StringLiterals {

}

enum Onboarding {
enum Preference {

static let dislikeFoodTitle = "싫어하는 음식을\n알려줄 수 있나요?"

Expand Down Expand Up @@ -489,7 +489,7 @@ enum StringLiterals {

static let privacyPolicy = "개인정보처리방침"

static let onboarding = "취향탐색 다시하기"
static let preference = "취향탐색 다시하기"

static let localVerification = "지역 인증하기"

Expand Down
8 changes: 8 additions & 0 deletions ACON-iOS/ACON-iOS/Global/Service/AuthManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ final class AuthManager {
return UserDefaultsManager.get(Bool.self, forKey: .hasSeenTutorial) ?? false
}

var hasSeenLocalVerification: Bool {
return UserDefaultsManager.get(Bool.self, forKey: .hasSeenLocalVerification) ?? false
}

var hasSeenPreference: Bool {
return UserDefaultsManager.get(Bool.self, forKey: .hasSeenPreference) ?? false
}

func handleTokenRefresh() async throws -> Bool {
let refreshToken = UserDefaultsManager.get(String.self, forKey: .refreshToken) ?? ""
return try await withCheckedThrowingContinuation { continuation in
Expand Down
13 changes: 11 additions & 2 deletions ACON-iOS/ACON-iOS/Global/Service/UserDefaultsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ struct UserDefaultsManager {

case hasVerifiedArea
case hasPreference

case hasSeenTutorial // NOTE: 초기화되면 안 됨
case hasSeenLocalVerification // NOTE: 초기화되면 안 됨
case hasSeenPreference // NOTE: 초기화되면 안 됨

case lastTokenRefreshDate
case lastLocalVerificationAlertDate
Expand Down Expand Up @@ -45,10 +48,16 @@ struct UserDefaultsManager {
/// 앱에서 정의한 UserDefaults를 초기화합니다.
/// - Note:
/// - 시스템에서 사용하는 UserDefaults 키는 영향을 받지 않습니다.
/// - `hasSeenTutorial` 키는 유지됩니다.
/// - 1회 노출과 관련된 키는 유지됩니다.
/// - `hasSeenTutorial`
/// - `hasSeenLocalVerification`
/// - `hasSeenPreference`
static func resetAppUserDefaults() {
for key in Keys.allCases {
if key == .hasSeenTutorial { continue }
if key == .hasSeenTutorial
|| key == .hasSeenLocalVerification
|| key == .hasSeenPreference { continue }

remove(forKey: key)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ enum ACAlertType: CaseIterable {
case changeVerifiedArea // NOTE: 지역인증 변경 (지역 1개)
case timeoutFromVerification // NOTE: 지역인증 변경 (인증 1주일 - 3개월)

case quitOnboarding // NOTE: 취향탐색 그만두기
case quitPreference // NOTE: 취향탐색 그만두기

case logout // NOTE: 로그아웃

Expand Down Expand Up @@ -57,7 +57,7 @@ enum ACAlertType: CaseIterable {
case .changeVerifiedArea, .timeoutFromVerification:
return "지역 삭제 불가"

case .quitOnboarding:
case .quitPreference:
return "취향탐색을 그만둘까요?"

case .logout:
Expand Down Expand Up @@ -113,7 +113,7 @@ enum ACAlertType: CaseIterable {
return "끝내기"
case .changeNotSaved:
return "계속 작성"
case .quitOnboarding:
case .quitPreference:
return "계속하기"
default:
return nil
Expand All @@ -132,7 +132,7 @@ enum ACAlertType: CaseIterable {
return "나가기"
case .changeVerifiedArea:
return "변경하기"
case .quitOnboarding, .quitSpotUpload:
case .quitPreference, .quitSpotUpload:
return "그만두기"
case .logout:
return "로그아웃"
Expand Down
4 changes: 2 additions & 2 deletions ACON-iOS/ACON-iOS/Global/Utils/NavigatonUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ struct NavigationUtils {
}
}

static func naviateToLoginOnboarding() {
static func naviateToOnboardingPreference() {
if let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate {
sceneDelegate.window?.rootViewController = OnboardingViewController(flowType: .login)
sceneDelegate.window?.rootViewController = PreferenceViewController(flowType: .onboarding)
}
}

Expand Down
2 changes: 1 addition & 1 deletion ACON-iOS/ACON-iOS/Network/Base/ACService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ final class ACService {

lazy var spotUploadService = SpotUploadService()

lazy var onboardingService: OnboardingService = OnboardingService()
lazy var preferenceService: PreferenceService = PreferenceService()

lazy var spotListService = SpotListService()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//
// PutOnboardingRequest.swift
// PutPreferenceRequest.swift
// ACON-iOS
//
// Created by 이수민 on 6/16/25.
//

import Foundation

struct PutOnboardingRequest: Codable {
struct PutPreferenceRequest: Codable {

let dislikeFoodList: [String]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// OnboardingService.swift
// PreferenceService.swift
// ACON-iOS
//
// Created by 이수민 on 6/16/25.
Expand All @@ -9,17 +9,17 @@ import Foundation

import Moya

protocol OnboardingServiceProtocol {
protocol PreferenceServiceProtocol {

func putOnboarding(requestBody: PutOnboardingRequest,
func putPreference(requestBody: PutPreferenceRequest,
completion: @escaping (NetworkResult<EmptyResponse>) -> Void)

}

final class OnboardingService: BaseService<OnboardingTargetType>, OnboardingServiceProtocol {
final class PreferenceService: BaseService<PreferenceTargetType>, PreferenceServiceProtocol {

func putOnboarding(requestBody: PutOnboardingRequest, completion: @escaping (NetworkResult<EmptyResponse>) -> Void) {
self.provider.request(.putOnboarding(requestBody)) { result in
func putPreference(requestBody: PutPreferenceRequest, completion: @escaping (NetworkResult<EmptyResponse>) -> Void) {
self.provider.request(.putPreference(requestBody)) { result in
switch result {
case .success(let response):
let networkResult = self.judgeStatus(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// OnboardingTargetType.swift
// PreferenceTargetType.swift
// ACON-iOS
//
// Created by 이수민 on 6/16/25.
Expand All @@ -9,46 +9,46 @@ import Foundation

import Moya

enum OnboardingTargetType {
enum PreferenceTargetType {

case putOnboarding(_ requestBody: PutOnboardingRequest)
case putPreference(_ requestBody: PutPreferenceRequest)

}

extension OnboardingTargetType: ACTargetType {
extension PreferenceTargetType: ACTargetType {

var method: Moya.Method {
switch self {
case .putOnboarding:
case .putPreference:
return .put
}
}

var path: String {
switch self {
case .putOnboarding:
case .putPreference:
return utilPath + "preference"
}
}

var parameter: [String : Any]? {
switch self {
case .putOnboarding:
case .putPreference:
return .none
}
}

var task: Task {
switch self {
case .putOnboarding(let requestBody):
case .putPreference(let requestBody):
return .requestJSONEncodable(requestBody)
}
}

var headers: [String : String]? {
var headers = HeaderType.headerWithToken()
switch self {
case .putOnboarding:
case .putPreference:
headers = HeaderType.headerWithToken()
}
return headers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,9 @@ private extension LocalMapViewController {
if onSuccess {
switch flowType {
case .onboarding:
// NOTE: 취향탐색 O -> Tutorial 또는 TabBar
// NOTE: 취향탐색 X -> OnboardingVC
// NOTE: 취향탐색O ? TabBar : 취향탐색VC
let hasPreference = AuthManager.shared.hasPreference
let hasSeenTutorial = AuthManager.shared.hasSeenTutorial
hasPreference
? (hasSeenTutorial ? NavigationUtils.navigateToTabBar() : NavigationUtils.navigateToTutorial())
: NavigationUtils.naviateToLoginOnboarding()
hasPreference ? NavigationUtils.navigateToTabBar() : NavigationUtils.naviateToOnboardingPreference()
case .setting:
NavigationUtils.popToParentVC(from: self, targetVCType: VerifiedAreasEditViewController.self)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class LocalVerificationViewController: BaseNavViewController {
let now = Date()
UserDefaultsManager.set(now, forKey: .lastLocalVerificationAlertDate)

NavigationUtils.naviateToLoginOnboarding()
NavigationUtils.naviateToOnboardingPreference()
}
}
}
Expand All @@ -54,7 +54,16 @@ class LocalVerificationViewController: BaseNavViewController {
self.tabBarController?.tabBar.isHidden = true
startBlinkingWarningLabel()
}


override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

UserDefaultsManager.set(true, forKey: .hasSeenLocalVerification)
}


// MARK: - UI Settings

override func setHierarchy() {
super.setHierarchy()

Expand Down Expand Up @@ -92,7 +101,7 @@ private extension LocalVerificationViewController {
} else {
switch localVerificationViewModel.flowType {
case .onboarding:
self.showDefaultAlert(title: "알림", message: "현재 동네인증이 불가능한 지역에 있어요", okText: "온보딩으로 이동", completion: {NavigationUtils.naviateToLoginOnboarding()})
self.showDefaultAlert(title: "알림", message: "현재 동네인증이 불가능한 지역에 있어요", okText: "취향탐색으로 이동", completion: {NavigationUtils.naviateToOnboardingPreference()})
default:
self.showDefaultAlert(title: "알림", message: "현재 동네인증이 불가능한 지역에 있어요", okText: "홈으로 이동", completion: {NavigationUtils.navigateToTabBar()})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,34 @@ extension LoginModalViewController {
guard let self = self else { return }
self.onSuccessLogin?(onSuccess)
self.dismiss(animated: true)

let hasVerifiedArea = AuthManager.shared.hasVerifiedArea
let hasPreference = AuthManager.shared.hasPreference


let hasSeenTutorial = AuthManager.shared.hasSeenTutorial
let hasSeenLocalVerification = AuthManager.shared.hasSeenLocalVerification
let hasSeenPreference = AuthManager.shared.hasSeenPreference

if onSuccess {
hasVerifiedArea ? hasPreference ? NavigationUtils.navigateToTabBar() : NavigationUtils.naviateToLoginOnboarding() : NavigationUtils.navigateToOnboardingLocalVerification()

// NOTE: [온보딩 순서] 소셜로그인 > 서비스 온보딩(튜토리얼) > 지역인증 > 취향탐색

// NOTE: 튜토리얼X -> 튜토리얼VC
if !hasSeenTutorial {
NavigationUtils.navigateToTutorial()
}

// NOTE: 튜토리얼O && 지역인증X -> 지역인증VC
else if !hasSeenLocalVerification {
NavigationUtils.navigateToOnboardingLocalVerification()
}

// NOTE: 튜토리얼O && 지역인증O && 취향탐색X -> 취향탐색VC
else if !hasSeenPreference {
NavigationUtils.naviateToOnboardingPreference()
}

// NOTE: 튜토리얼O && 지역인증O && 취향탐색O -> TabBar
else {
NavigationUtils.navigateToTabBar()
}

if let presentedVCType = presentedVCType {
AmplitudeManager.shared.trackEventWithProperties(AmplitudeLiterals.EventName.guest, properties: [presentedVCType: true])
}
Expand Down
31 changes: 16 additions & 15 deletions ACON-iOS/ACON-iOS/Presentation/Login/View/LoginViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,33 +123,34 @@ extension LoginViewController {
self.loginViewModel.onSuccessLogin.bind { [weak self] onSuccess in
guard let onSuccess else { return }
guard let self = self else { return }
let hasVerifiedArea = AuthManager.shared.hasVerifiedArea
let hasPreference = AuthManager.shared.hasPreference

let hasSeenTutorial = AuthManager.shared.hasSeenTutorial
let hasSeenLocalVerificationOnboarding = AuthManager.shared.hasSeenLocalVerification
let hasSeenPreferenceOnboarding = AuthManager.shared.hasSeenPreference

if onSuccess {
AmplitudeManager.shared.trackEventWithProperties(AmplitudeLiterals.EventName.login, properties: ["did_login?": true])

// NOTE: 지역인증O && 취향탐색O && 튜토리얼O -> TabBar로 이동
if hasVerifiedArea && hasPreference && hasSeenTutorial {
NavigationUtils.navigateToTabBar()
}
// NOTE: [온보딩 순서] 소셜로그인 > 서비스 온보딩(튜토리얼) > 지역인증 > 취향탐색

// NOTE: 지역인증O && 취향탐색O && 튜토리얼X -> 튜토리얼로 이동
else if hasVerifiedArea && hasPreference && !hasSeenTutorial {
// NOTE: 튜토리얼X -> 튜토리얼VC
if !hasSeenTutorial {
NavigationUtils.navigateToTutorial()
}

// NOTE: 지역인증O && 취향탐색X -> 취향탐색으로 이동
// NOTE: 취향탐색 이후 튜토리얼을 거치는지는 OnboardingVC에서 분기처리
else if hasVerifiedArea && !hasPreference {
NavigationUtils.naviateToLoginOnboarding()
// NOTE: 튜토리얼O && 지역인증X -> 지역인증VC
else if !hasSeenLocalVerificationOnboarding {
NavigationUtils.navigateToOnboardingLocalVerification()
}

// NOTE: 튜토리얼O && 지역인증O && 취향탐색X -> 취향탐색VC
else if !hasSeenPreferenceOnboarding {
NavigationUtils.naviateToOnboardingPreference()
}

// NOTE: 지역인증X -> 지역인증으로 이동
// NOTE: 지역인증 이후 취항탐색, 튜토리얼을 거치는지는 LocalMapVC에서 분기처리
// NOTE: 튜토리얼O && 지역인증O && 취향탐색O -> TabBar
else {
NavigationUtils.navigateToOnboardingLocalVerification()
NavigationUtils.navigateToTabBar()
}
} else {
showLoginFailAlert()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// OnboardingModel.swift
// PreferenceModel.swift
// ACON-iOS
//
// Created by 이수민 on 6/16/25.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//
// OnboardingFlowType.swift
// PreferenceFlowType.swift
// ACON-iOS
//
// Created by 이수민 on 6/3/25.
//

import Foundation

enum OnboardingFlowType {
enum PreferenceFlowType {

case login, setting
case onboarding, setting

}
Loading