diff --git a/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate b/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate index bb10369..bcea3c4 100644 Binary files a/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate and b/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/AcaMate/0. Setup/AppDelegate.swift b/AcaMate/0. Setup/AppDelegate.swift index 91b7438..961b9d4 100644 --- a/AcaMate/0. Setup/AppDelegate.swift +++ b/AcaMate/0. Setup/AppDelegate.swift @@ -44,8 +44,8 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele } center.delegate = self -//MARK: - 네트워크 모니터 초기화 -// _ = NetworkMonitor.shared + //MARK: - 네트워크 모니터 초기화 + _ = NetworkMonitor.shared printLog("End Set AppDelegate") return true diff --git a/AcaMate/1. View/0. Common/NavigationView.swift b/AcaMate/1. View/0. Common/NavigationView.swift new file mode 100644 index 0000000..610011f --- /dev/null +++ b/AcaMate/1. View/0. Common/NavigationView.swift @@ -0,0 +1,84 @@ +// +// NavigationView.swift +// AcaMate +// +// Created by Sean Kim on 12/12/24. +// + +import SwiftUI +import Combine + + + +struct NavigationView: View { + @State private var naviState : NaviState = .init(act: .NONE, path: .Intro) + @State private var history: [PathName] = [.Intro] + + + var body: some View { + ZStack { + switch naviState.path { + case .NONE: + EmptyView() + case .Intro: + IntroView(naviState: $naviState) + case .Login : + LoginView(naviState: $naviState) + case .Main: + EmptyView() + } + } + .onChange(of: naviState) { old, new in + switch new.act { + case .NONE: + break + case .ADD: + addHistory(path: new.path) + case .POP: + popHistory() + case .RESET: + resetHistory(path: new.path) + case .MOVE: + moveHistory(path: new.path) + } + + // LOG + printLog("\(old.path) => \(new.path)") + showHistory() + } + } + + private func addHistory(path: PathName) { + history.append(path) + } + + private func popHistory() { + history.removeLast() + naviState.set(act: .NONE, path: history.last ?? .NONE) + } + + private func resetHistory(path: PathName) { + history.removeAll() + addHistory(path: path) + } + + private func moveHistory(path: PathName) { + if path == .NONE { + naviState.set(act: .RESET, path: history.first ?? .Main) + } + if history.contains(path) { + let remove = history.count - history.firstIndex(of: path)! - 1 + history.removeLast(remove) + if remove > 0 { + naviState.set(act: .NONE, path: path) + return + } + } + naviState.set(act: .RESET, path: path) + } + + private func showHistory() { + printLog(history) + } + +} diff --git a/AcaMate/1. View/1. Intro & Login/IntroView.swift b/AcaMate/1. View/1. Intro & Login/IntroView.swift index 47ad830..3ae437c 100644 --- a/AcaMate/1. View/1. Intro & Login/IntroView.swift +++ b/AcaMate/1. View/1. Intro & Login/IntroView.swift @@ -10,65 +10,67 @@ import Combine struct IntroView: View { @State var cancellables: Set = [] + @Binding var naviState : NaviState var body: some View { - NavigationStack { - VStack(spacing: 0) { - Spacer() - .frame(height: 100) + VStack(spacing: 0) { + Spacer() + .frame(height: 100) + Image("Team_Icon") + .resizable() + .frame(width: 200, height: 200) + .background(.white) + .border(.black) + .padding() + Spacer() + HStack(spacing: 4) { Image("Team_Icon") .resizable() - .frame(width: 200, height: 200) - .background(.white) - .border(.black) - .padding() - Spacer() - HStack(spacing: 4) { - Image("Team_Icon") - .resizable() - .frame(width: 24, height: 24) - Text("STEIN") - .font(.nps(font: .bold, size: 16)) - .foregroundStyle(Color(.Text.detail)) - } - .padding(.bottom,12) - Text("Copyright © Team.Stein") - .font(.nps(font: .regular, size: 14)) + .frame(width: 24, height: 24) + Text("STEIN") + .font(.nps(font: .bold, size: 16)) .foregroundStyle(Color(.Text.detail)) - .padding(.bottom,50) } - .fullView(.Normal.normal) - .onAppear { - printLog("IntroView_onAppear") - loadVersion() - .sink { completion in - switch completion { - case .failure(let error): - printLog(error) - case .finished: break - } - } receiveValue: { version in - switch compareVersion(version.force_ver, currentVersion()){ + .padding(.bottom,12) + Text("Copyright © Team.Stein") + .font(.nps(font: .regular, size: 14)) + .foregroundStyle(Color(.Text.detail)) + .padding(.bottom,50) + } + .fullView(.Normal.normal) + .onAppear { + printLog("IntroView_onAppear") + loadVersion() + .sink { completion in + switch completion { + case .failure(let error): + printLog(error) + case .finished: break + } + } receiveValue: { version in + switch compareVersion(version.force_ver, currentVersion()){ + case .bigger: + printLog("강제 업데이트") + default: + switch compareVersion(version.final_ver, currentVersion()) { case .bigger: - printLog("강제 업데이트") - default: - switch compareVersion(version.final_ver, currentVersion()) { - case .bigger: - if version.choice_update_yn { - printLog("선택 업데이트") - } - else { - printLog("정상 동작") - } - default: - printLog("선택 업데이트 넘어감") + if version.choice_update_yn { + printLog("선택 업데이트") } + else { + printLog("정상 동작") + naviState.set(act: .RESET, path: .Login) + } + default: + printLog("선택 업데이트 넘어감") + naviState.set(act: .MOVE, path: .Login) + } } - .store(in: &cancellables) - - - } + } + .store(in: &cancellables) + + } } @@ -101,15 +103,15 @@ struct IntroView: View { return currentVer } - + private func versionChange(ver: String) -> [Int] { return ver.components(separatedBy: ["."]).map {Int($0) ?? 0} } - - - } -#Preview { - IntroView() -} + + + +//#Preview { +// IntroView(path: $NavigationPath()) +//} diff --git a/AcaMate/1. View/1. Intro & Login/LoginView.swift b/AcaMate/1. View/1. Intro & Login/LoginView.swift index a3a119e..02758fd 100644 --- a/AcaMate/1. View/1. Intro & Login/LoginView.swift +++ b/AcaMate/1. View/1. Intro & Login/LoginView.swift @@ -8,6 +8,8 @@ import SwiftUI struct LoginView: View { + @Binding var naviState : NaviState + var body: some View { VStack(spacing: 0) { Image("Team_Icon") @@ -34,12 +36,18 @@ struct LoginView: View { } } - + Button { + naviState.set(act: .MOVE,path: .Intro) + } label: { + Text("111111111") + } + .padding() } .fullView(.Normal.normal) + } } -#Preview { - LoginView() -} +//#Preview { +// LoginView() +//} diff --git a/AcaMate/4. Model/Navigation.swift b/AcaMate/4. Model/Navigation.swift new file mode 100644 index 0000000..3b974a9 --- /dev/null +++ b/AcaMate/4. Model/Navigation.swift @@ -0,0 +1,47 @@ +// +// Navigation.swift +// AcaMate +// +// Created by Sean Kim on 12/13/24. +// + +import Foundation + + + +struct NaviState: Equatable { + var act: NaviAction + var path: PathName + + static func == (lhs: NaviState, rhs: NaviState) -> Bool { + return lhs.act == rhs.act && lhs.path == rhs.path + } + + mutating func set(act: NaviAction = .ADD, path: PathName = .NONE) { + self.act = act + self.path = path + } +} + +enum NaviAction: Hashable { + /// 한 계층 추가 + case ADD + /// 전체 삭제 후 추가 + case RESET + /// 한 계층 빼기 + case POP + /// 위치로 이동 (path == NONE인 경우 최상단) + case MOVE + /// 아무 동작 안함 + case NONE + + /// FIRST = 가장 메인, MOVE = 그곳으로 +} + +enum PathName: Hashable { + case Intro + case Login + case Main + + case NONE +} diff --git a/AcaMate/5. Modifier/Network.swift b/AcaMate/5. Modifier/Network.swift new file mode 100644 index 0000000..4b776c3 --- /dev/null +++ b/AcaMate/5. Modifier/Network.swift @@ -0,0 +1,27 @@ +// +// Network.swift +// AcaMate +// +// Created by Sean Kim on 12/10/24. +// + +import Network +import Combine + +class NetworkMonitor: ObservableObject { + static let shared = NetworkMonitor() + + private let monitor = NWPathMonitor() + private let queue = DispatchQueue.global(qos: .background) + + @Published var isConnected: Bool = true + + private init() { + monitor.pathUpdateHandler = { [weak self] path in + DispatchQueue.main.async { + self?.isConnected = (path.status == .satisfied) + } + } + monitor.start(queue: queue) + } +} diff --git a/AcaMate/5. Modifier/View.swift b/AcaMate/5. Modifier/View.swift index 3656f7b..285512e 100644 --- a/AcaMate/5. Modifier/View.swift +++ b/AcaMate/5. Modifier/View.swift @@ -6,9 +6,23 @@ // import SwiftUI +import Combine + +struct NetworkModifier: ViewModifier { + @ObservedObject private var networkMonitor = NetworkMonitor.shared + + func body(content: Content) -> some View { + content + .onChange(of: networkMonitor.isConnected) { _ , new in + if new { + + } + } + } +} extension View { - func fullView(_ backColor: Color) -> some View{ + func fullView(_ backColor: Color) -> some View { return self .frame(maxWidth: .infinity, maxHeight: .infinity) .background(backColor) @@ -17,4 +31,10 @@ extension View { func endTextEditing() { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } + + func setNavigaion() -> some View { + self + .navigationBarBackButtonHidden(true) + .toolbar(.hidden, for: .navigationBar) + } } diff --git a/AcaMate/AcaMateApp.swift b/AcaMate/AcaMateApp.swift index 5454b18..812e58b 100644 --- a/AcaMate/AcaMateApp.swift +++ b/AcaMate/AcaMateApp.swift @@ -22,7 +22,7 @@ struct AcaMateApp: App { var body: some Scene { WindowGroup { - IntroView().onOpenURL { url in + NavigationView().onOpenURL { url in if (AuthApi.isKakaoTalkLoginUrl(url)) { _ = AuthController.handleOpenUrl(url: url) }