diff --git a/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/tanine.xcuserdatad/UserInterfaceState.xcuserstate b/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/tanine.xcuserdatad/UserInterfaceState.xcuserstate index 7a79d16..fe267db 100644 Binary files a/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/tanine.xcuserdatad/UserInterfaceState.xcuserstate and b/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/tanine.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/AcaMate/1. View/10. Common/NavigationView.swift b/AcaMate/1. View/10. Common/NavigationView.swift index 1421d2f..640b49c 100644 --- a/AcaMate/1. View/10. Common/NavigationView.swift +++ b/AcaMate/1. View/10. Common/NavigationView.swift @@ -25,6 +25,8 @@ struct NavigationView: View { IntroView() case .Login : LoginView() + case .Register(let type, let id): + RegisterView(type: type, snsID: id) case .SelectAcademy(let bids): SelectAcademyView(bids: bids) case .Main: diff --git a/AcaMate/1. View/11. Intro & Login/LoginView.swift b/AcaMate/1. View/11. Intro & Login/LoginView.swift index a288d0f..a7c2941 100644 --- a/AcaMate/1. View/11. Intro & Login/LoginView.swift +++ b/AcaMate/1. View/11. Intro & Login/LoginView.swift @@ -34,7 +34,9 @@ struct LoginView: View { Button { // MARK: - TODO, 애플 계정 로그인 구현 - appVM.naviState.set(act: .ADD, path: .SelectAcademy(bids: ["AA0000", "AA0001"])) +// appVM.naviState.set(act: .ADD, path: .SelectAcademy(bids: ["AA0000", "AA0001"])) + loginVM.toggleLoading = true + loginVM.loginTest(type: .Apple, id: "12345678") } label: { makeButton(image: Image(.Logo.appleIcon), color: Color(.Text.black), "애플 계정으로 시작하기") @@ -47,9 +49,9 @@ struct LoginView: View { } .frame(maxWidth: .infinity,maxHeight: .infinity) .fullDrawView(.Normal.normal) - .onChange(of: loginVM.navigateToAcademy, { _, _ in - appVM.naviState.set(act: .ADD, path: .SelectAcademy(bids: loginVM.bidArray)) - }) + .onChange(of: loginVM.pathName){ _, new in + appVM.naviState.set(act: .ADD, path: new) + } .onChange(of: loginVM.toggleLoading) { _, new in appVM.isLoading = new diff --git a/AcaMate/1. View/11. Intro & Login/RegisterView.swift b/AcaMate/1. View/11. Intro & Login/RegisterView.swift new file mode 100644 index 0000000..474c0a6 --- /dev/null +++ b/AcaMate/1. View/11. Intro & Login/RegisterView.swift @@ -0,0 +1,59 @@ +// +// RegisterView.swift +// AcaMate +// +// Created by TAnine on 2/20/25. +// + +import SwiftUI + +struct RegisterView: View { + @EnvironmentObject var appVM: AppViewModel + @StateObject private var topVM = TopViewModel() + + @State private var scrollOffset: CGPoint = .zero + + let type: SNSLoginType + let snsID: String + + @State private var selectDate: Date = { + let calendar = Calendar.current + return calendar.date(byAdding: .year, value: -12, to: Date()) ?? Date() + }() + + var body: some View { + // MARK: TO-DO + // 회원가입 뷰 만들기 + // 이름, 번호, 이메일, 주소, 생년월일 + + + VStack(spacing: 0) { + TopView(topVM: topVM) + + OffsetObservableScrollView(showsIndicators: false, scrollOffset: $scrollOffset) { proxy in + + DatePicker("생년월일 입력", selection: $selectDate, displayedComponents: [.date]) + .datePickerStyle(.compact) + .environment(\.locale, Locale(identifier: "ko_KR")) + .font(.nps(size: 16)) + .padding() + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + .onAppear { + topVM.titleName = "회원가입" + topVM.setLeftBtn(Image(.Icon.left), size: CGPoint(x: 40, y: 40), action: leftAct) + topVM.setRightBtn(size: CGPoint(x: 40, y: 40), action: rightAct) + + } + } + + func leftAct() { + printLog("왼쪽 버튼 클릭") + appVM.naviState.set(act: .POP) + } + func rightAct() { + printLog("오른쪽 버튼 클릭") + } +} + diff --git a/AcaMate/1. View/12. Main/124. Calendar/CalendarView.swift b/AcaMate/1. View/12. Main/124. Calendar/CalendarView.swift index d88540b..e7482c2 100644 --- a/AcaMate/1. View/12. Main/124. Calendar/CalendarView.swift +++ b/AcaMate/1. View/12. Main/124. Calendar/CalendarView.swift @@ -26,7 +26,6 @@ struct CalendarView: View { topVM.setLeftBtn(size: CGPoint(x: 40, y: 40), action: leftAct) topVM.setRightBtn(size: CGPoint(x: 40, y: 40), action: rightAct) - } } diff --git a/AcaMate/2. Model/API Response.swift b/AcaMate/2. Model/API Response.swift index 42cafe1..7b93331 100644 --- a/AcaMate/2. Model/API Response.swift +++ b/AcaMate/2. Model/API Response.swift @@ -13,10 +13,56 @@ class APIResponse: Codable { } class Status: Codable { - let code: String + let code: APICode let message: String } +enum APICode: Codable { + case success + case inputErr + case outputErr + case networkErr + case unknownErr + case anything(String) + + init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + let rawValue = try container.decode(String.self) + switch rawValue { + case "000": + self = .success + case "001": + self = .inputErr + case "002": + self = .outputErr + case "003": + self = .networkErr + case "999": + self = .unknownErr + default: + self = .anything(rawValue) + } + } + + func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + switch self { + case .success: + try container.encode("000") + case .inputErr: + try container.encode("001") + case .outputErr: + try container.encode("002") + case .networkErr: + try container.encode("003") + case .unknownErr: + try container.encode("999") + case .anything(let value): + try container.encode(value) + } + } +} + // /api/v1/in/app/version ---------------- class VersionData: Codable { diff --git a/AcaMate/2. Model/Navigation.swift b/AcaMate/2. Model/Navigation.swift index 0bc2e6c..aa6735a 100644 --- a/AcaMate/2. Model/Navigation.swift +++ b/AcaMate/2. Model/Navigation.swift @@ -42,6 +42,7 @@ enum NaviAction: Hashable { enum PathName: Hashable { case Intro case Login + case Register(_ type: SNSLoginType, id: String) case SelectAcademy(bids: [String]) case Main case ChatRoom(id: String) diff --git a/AcaMate/3. ViewModel/LoginViewModel.swift b/AcaMate/3. ViewModel/LoginViewModel.swift index 8e599ed..4f7ee4e 100644 --- a/AcaMate/3. ViewModel/LoginViewModel.swift +++ b/AcaMate/3. ViewModel/LoginViewModel.swift @@ -11,10 +11,54 @@ import Combine class LoginViewModel: ObservableObject { private var cancellables = Set() - @Published var toggleLoading: Bool = false - @Published var navigateToAcademy: Bool = false - @Published var bidArray: [String] = [] + @Published var toggleLoading: Bool = false + @Published var pathName: PathName = .NONE + + var bidArray: [String] = [] + + func loginTest(type: SNSLoginType, id: String) { + loadAPIData(url: "\(API_URL)", + path: "/api/v1/in/user/login", + parameters: [ + "acctype": "\(type == .Apple ? "ST00": "ST01")", + "sns_id": "\(id)" + ], + decodingType: APIResponse.self) + .sink { [weak self] completion in + // API 자체적으로 내보내는 에러는 여기서 거를거고 + switch completion { + case .failure(let error): + self?.toggleLoading = false + printLog("\(error)") + case .finished: + self?.toggleLoading = false + } + } receiveValue: { [weak self] response in + guard let self = self else { return } + guard let userAcademy = response as? APIResponse else {return} + switch userAcademy.status.code { + case .success: + if let bids = userAcademy.data.toStringDict()["bid"] { + printLog(bids) + if let bidArray: [String] = jsonToSwift(bids) { + self.pathName = .SelectAcademy(bids: bidArray) + } else { + printLog("JSON 변환 실패") + } + } + case .anything(let apiCode): + // MARK: TO-DO + // 회원가입 로직 + printLog("\(apiCode) : 로그인 정보 없음") + self.pathName = .Register(type, id: "\(id)") + default: + // 그외에 서버에서 처리를 하다가 문제가 생겨서 발생하는 에러는 여기로 보낼거임 + printLog("ERROR") + } + } + .store(in: &cancellables) + } func loginAction(type: SNSLoginType) { LoginController().login(type) @@ -38,14 +82,11 @@ class LoginViewModel: ObservableObject { } } receiveValue: { [weak self] response in guard let self = self else { return } - guard let ua = response as? APIResponse else {return} - if let bids = ua.data.toStringDict()["bid"] { + guard let userAcademy = response as? APIResponse else {return} + if let bids = userAcademy.data.toStringDict()["bid"] { printLog(bids) if let bidArray: [String] = jsonToSwift(bids) { - // 정상 적으로 학원 ID를 불러 온거니까 이제 여기서 할 걸 정해야 함 - printLog("GOOD") - self.navigateToAcademy = true - self.bidArray = bidArray + self.pathName = .SelectAcademy(bids: bidArray) } else { printLog("JSON 변환 실패") } diff --git a/AcaMate/3. ViewModel/SelectAcademyViewModel.swift b/AcaMate/3. ViewModel/SelectAcademyViewModel.swift index 1246ebe..8d50b13 100644 --- a/AcaMate/3. ViewModel/SelectAcademyViewModel.swift +++ b/AcaMate/3. ViewModel/SelectAcademyViewModel.swift @@ -17,7 +17,7 @@ class SelectAcademyViewModel: ObservableObject { func loadAcademy(bids: [String]) { loadAPIData(url: "\(API_URL)", - path: "/api/v1/in/member/academy", + path: "/api/v1/in/user/academy", method: .post, parameters: ["bids": bids], decodingType: APIResponse<[AcademyName]>.self) diff --git a/AcaMate/5. Manager/WebSocketManager.swift b/AcaMate/5. Manager/WebSocketManager.swift index 5afc0d5..29dce4f 100644 --- a/AcaMate/5. Manager/WebSocketManager.swift +++ b/AcaMate/5. Manager/WebSocketManager.swift @@ -17,9 +17,7 @@ class WebSocketManager: ObservableObject ,WebSocketDelegate { @Published var receivedMessage: [String] = [] init() { -// guard let url = URL(string: "wss://devacamate.ipstein.myds.me/chatHub?transport=webSockets") else { return } guard let url = URL(string: "\(WS_URL)/chatHub?transport=webSockets") else { return } -// guard let url = URL(string: "\(API_URL)/chatHub?transport=websockets3") else { return } var request = URLRequest(url: url) request.timeoutInterval = 5 request.setValue("application/json", forHTTPHeaderField: "Content-Type")