diff --git a/AcaMate.xcodeproj/project.pbxproj b/AcaMate.xcodeproj/project.pbxproj index 66ecf0f..4b689cc 100644 --- a/AcaMate.xcodeproj/project.pbxproj +++ b/AcaMate.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + A73892212D526A9D00659A62 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = A73892202D526A9D00659A62 /* FirebaseAnalytics */; }; + A73892232D526A9D00659A62 /* FirebaseAppCheck in Frameworks */ = {isa = PBXBuildFile; productRef = A73892222D526A9D00659A62 /* FirebaseAppCheck */; }; + A73892252D526A9D00659A62 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = A73892242D526A9D00659A62 /* FirebaseCrashlytics */; }; A771FFF22CFB70D100367DA6 /* KakaoSDK in Frameworks */ = {isa = PBXBuildFile; productRef = A771FFF12CFB70D100367DA6 /* KakaoSDK */; }; A78774722CF586AF002FE2EE /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = A78774712CF586AF002FE2EE /* Alamofire */; }; A7A518CF2CF555E200822D0D /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = A7A518CE2CF555E200822D0D /* README.md */; }; @@ -45,8 +48,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + A73892232D526A9D00659A62 /* FirebaseAppCheck in Frameworks */, A78774722CF586AF002FE2EE /* Alamofire in Frameworks */, + A73892252D526A9D00659A62 /* FirebaseCrashlytics in Frameworks */, A771FFF22CFB70D100367DA6 /* KakaoSDK in Frameworks */, + A73892212D526A9D00659A62 /* FirebaseAnalytics in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -93,6 +99,9 @@ packageProductDependencies = ( A78774712CF586AF002FE2EE /* Alamofire */, A771FFF12CFB70D100367DA6 /* KakaoSDK */, + A73892202D526A9D00659A62 /* FirebaseAnalytics */, + A73892222D526A9D00659A62 /* FirebaseAppCheck */, + A73892242D526A9D00659A62 /* FirebaseCrashlytics */, ); productName = AcaMate; productReference = A7A518BB2CF5558B00822D0D /* AcaMate.app */; @@ -125,6 +134,7 @@ packageReferences = ( A78774702CF586AF002FE2EE /* XCRemoteSwiftPackageReference "Alamofire" */, A771FFF02CFB70D100367DA6 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */, + A738921F2D526A9D00659A62 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, ); preferredProjectObjectVersion = 77; productRefGroup = A7A518BC2CF5558B00822D0D /* Products */; @@ -378,6 +388,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + A738921F2D526A9D00659A62 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 11.8.0; + }; + }; A771FFF02CFB70D100367DA6 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kakao/kakao-ios-sdk"; @@ -397,6 +415,21 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + A73892202D526A9D00659A62 /* FirebaseAnalytics */ = { + isa = XCSwiftPackageProductDependency; + package = A738921F2D526A9D00659A62 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAnalytics; + }; + A73892222D526A9D00659A62 /* FirebaseAppCheck */ = { + isa = XCSwiftPackageProductDependency; + package = A738921F2D526A9D00659A62 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAppCheck; + }; + A73892242D526A9D00659A62 /* FirebaseCrashlytics */ = { + isa = XCSwiftPackageProductDependency; + package = A738921F2D526A9D00659A62 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseCrashlytics; + }; A771FFF12CFB70D100367DA6 /* KakaoSDK */ = { isa = XCSwiftPackageProductDependency; package = A771FFF02CFB70D100367DA6 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */; diff --git a/AcaMate.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/AcaMate.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index cc84473..c602ae4 100644 --- a/AcaMate.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/AcaMate.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,15 @@ { - "originHash" : "48d44fe9560aaa48bc97ae34cdb596f62fa2d739be3dafd4261b95db8f8c86ab", + "originHash" : "3b609245b8d633048f6670834279f82d0601cc0879a2d8c9c86fa0dd25734ea3", "pins" : [ + { + "identity" : "abseil-cpp-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/abseil-cpp-binary.git", + "state" : { + "revision" : "194a6706acbd25e4ef639bcaddea16e8758a3e27", + "version" : "1.2024011602.0" + } + }, { "identity" : "alamofire", "kind" : "remoteSourceControl", @@ -10,6 +19,78 @@ "version" : "5.10.2" } }, + { + "identity" : "app-check", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/app-check.git", + "state" : { + "revision" : "61b85103a1aeed8218f17c794687781505fbbef5", + "version" : "11.2.0" + } + }, + { + "identity" : "firebase-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/firebase-ios-sdk", + "state" : { + "revision" : "075679d6b25b28f4cb167f1d7769b58fb556fb30", + "version" : "11.8.0" + } + }, + { + "identity" : "googleappmeasurement", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleAppMeasurement.git", + "state" : { + "revision" : "be0881ff728eca210ccb628092af400c086abda3", + "version" : "11.7.0" + } + }, + { + "identity" : "googledatatransport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleDataTransport.git", + "state" : { + "revision" : "617af071af9aa1d6a091d59a202910ac482128f9", + "version" : "10.1.0" + } + }, + { + "identity" : "googleutilities", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleUtilities.git", + "state" : { + "revision" : "53156c7ec267db846e6b64c9f4c4e31ba4cf75eb", + "version" : "8.0.2" + } + }, + { + "identity" : "grpc-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/grpc-binary.git", + "state" : { + "revision" : "f56d8fc3162de9a498377c7b6cea43431f4f5083", + "version" : "1.65.1" + } + }, + { + "identity" : "gtm-session-fetcher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/gtm-session-fetcher.git", + "state" : { + "revision" : "3cdb78efb79b4a5383c3911488d8025bfc545b5e", + "version" : "4.3.0" + } + }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, { "identity" : "kakao-ios-sdk", "kind" : "remoteSourceControl", @@ -18,6 +99,42 @@ "branch" : "master", "revision" : "ab4309c1950550add307046ad1e08024c7514603" } + }, + { + "identity" : "leveldb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/leveldb.git", + "state" : { + "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", + "version" : "1.22.5" + } + }, + { + "identity" : "nanopb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/nanopb.git", + "state" : { + "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", + "version" : "2.30910.0" + } + }, + { + "identity" : "promises", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/promises.git", + "state" : { + "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", + "version" : "2.4.0" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "ebc7251dd5b37f627c93698e4374084d98409633", + "version" : "1.28.2" + } } ], "version" : 3 diff --git a/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate b/AcaMate.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate index 8165c44..fb308b4 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 961b9d4..98eb458 100644 --- a/AcaMate/0. Setup/AppDelegate.swift +++ b/AcaMate/0. Setup/AppDelegate.swift @@ -12,10 +12,11 @@ import UserNotifications import KakaoSDKCommon import KakaoSDKAuth +import FirebaseCore -class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate { +class AppDelegate: NSObject, UIApplicationDelegate { @@ -28,6 +29,7 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele } //MARK: - Set Notification + let center = UNUserNotificationCenter.current() let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] center.requestAuthorization(options: authOptions) { granted, error in @@ -47,6 +49,9 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele //MARK: - 네트워크 모니터 초기화 _ = NetworkMonitor.shared + //MARK: - FIREBASE 초기화 + FirebaseApp.configure() + printLog("End Set AppDelegate") return true } @@ -60,6 +65,12 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele } + +} + +extension AppDelegate: UNUserNotificationCenterDelegate { + + // func registerForRemoteNotifications() { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in print("Permission granted: \(granted)") @@ -86,7 +97,7 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele printLog("APNs 등록 실패: \(error)") } - // 앱 켜져있을때 알럿 받으면 (오는게 확인되면 바로 뜨는 곳) + // 앱 켜져있을때 알럿 받으면 직접 로컬로 알림 띄워주는 곳 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions { let userInfo = notification.request.content.userInfo @@ -107,7 +118,7 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele } } - // 수신 받은 Notification을 터치해 앱으로 진입했을 때 호출 + // 수신 받은 Noti를 터치해 앱으로 진입했을 때 호출 (앱 상태 여부 무관) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo if let apsData = userInfo["aps"] as? [AnyHashable: Any] { @@ -117,9 +128,7 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele if let param = alert["parameter"] { printLog(param as? String) } -// viewModel.setBadge() } } } - } diff --git a/AcaMate/2. Common/SwiftUI_Prefix.swift b/AcaMate/0. Setup/SwiftUI_Prefix.swift similarity index 95% rename from AcaMate/2. Common/SwiftUI_Prefix.swift rename to AcaMate/0. Setup/SwiftUI_Prefix.swift index 2c388b4..08b2fb3 100644 --- a/AcaMate/2. Common/SwiftUI_Prefix.swift +++ b/AcaMate/0. Setup/SwiftUI_Prefix.swift @@ -6,7 +6,10 @@ // import SwiftUI // MARK: - ACAMATE -#if DEV +// APPSTORE_URL : https://apps.apple.com/us/app/%EC%95%84%EC%B9%B4%EB%8D%B0%EB%AF%B8%EB%A9%94%EC%9D%B4%ED%8A%B8/id6739448113 +#if DEV && LOCAL +public let API_URL: String = "http://localhost:5144" +#elseif DEV public let API_URL: String = "https://devacamate.ipstein.myds.me" #else public let API_URL: String = "https://acamate.ipstein.myds.me" @@ -16,7 +19,6 @@ public let API_URL: String = "https://acamate.ipstein.myds.me" // MARK: - TYPEALIAS typealias VOID_TO_VOID = () -> () - // MARK: - VARIABLE public var APPSTORE_URL = "https://itunes.apple.com/app/" public var KEYBOARD_UP_HEIGHT: CGFloat = 46.0 @@ -123,6 +125,19 @@ public func jsonToDict(_ input: String) -> [String: Any] { return [:] } +/// JSON 배열의 형태를 Swift의 배열 형태로 변환한다. +public func jsonToSwift(_ input: String) -> T? { + if let data = input.data(using: .utf8) { + do { + let jsonObject = try JSONDecoder().decode(T.self, from: data) + return jsonObject + } catch let error { + printLog("JSON ERROR: \(error))") + } + } + return nil +} + func versionChange(ver: String) -> [Int] { return ver.components(separatedBy: ["."]).map {Int($0) ?? 0} } diff --git a/AcaMate/1. View/10. Common/NavigationView.swift b/AcaMate/1. View/10. Common/NavigationView.swift index 85a8ffb..59435df 100644 --- a/AcaMate/1. View/10. Common/NavigationView.swift +++ b/AcaMate/1. View/10. Common/NavigationView.swift @@ -11,6 +11,8 @@ import Combine /// 이거 위에 다른 뷰들이 위젯 느낌으로 계속 갈아 끼워지는거 struct NavigationView: View { + @EnvironmentObject var appVM: AppViewModel + @State private var naviState : NaviState = .init(act: .NONE, path: .Intro) @State private var history: [PathName] = [.Intro] @@ -45,9 +47,13 @@ struct NavigationView: View { printLog("\(old.path) => \(new.path)") showHistory() } + .onTapGesture { + endTextEditing() + } .fullDrawView(.Normal.normal) .setAlert() .setNetwork() + .loadingView(isLoading: $appVM.isLoading) } /// 경로에 한 단계 추가 diff --git a/AcaMate/1. View/11. Intro & Login/AccountLoginView.swift b/AcaMate/1. View/11. Intro & Login/AccountLoginView.swift new file mode 100644 index 0000000..2a45045 --- /dev/null +++ b/AcaMate/1. View/11. Intro & Login/AccountLoginView.swift @@ -0,0 +1,117 @@ +// +// AccountLoginView.swift +// AcaMate +// +// Created by Sean Kim on 12/14/24. +// + +import SwiftUI + +struct AccountLoginView: View { + @ObservedObject var viewModel: LoginViewModel + @Binding var userId: String + @Binding var password: String + @Binding var isSecure: Bool + @Binding var isSave: Bool + var body: some View { + VStack(spacing: 0) { + ZStack(alignment: .leading) { + if userId.isEmpty { + Text("아이디를 입력하세요.") + .font(.nps(font: .regular, size: 16)) + .foregroundStyle(Color(.Text.border)) + .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24)) + } + CustomTextField(placeholder: "", text: $userId) + .frame(maxWidth: .infinity,maxHeight: 24) + .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24)) + } + .background { + RoundedRectangle(cornerRadius: 24) + .foregroundStyle(.white) + } + .padding(EdgeInsets(top: 0, leading: 12, bottom: 8, trailing: 12)) + + ZStack(alignment: .leading) { + if password.isEmpty { + Text("비밀번호를 입력하세요.") + .font(.nps(font: .regular, size: 16)) + .foregroundStyle(Color(.Text.border)) + .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24)) + } + CustomTextField(placeholder: "", text: $password, isSecure: $isSecure) + .frame(maxWidth: .infinity,maxHeight: 24) + .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24)) + + HStack { + Spacer() + Button { + isSecure.toggle() + } label: { + if password.isEmpty { + Rectangle() + .frame(width: 16, height: 2) + .foregroundStyle(Color(.Text.border)) + .padding(.trailing,24) + } + else { + if isSecure { + Image(systemName: "eye") + .frame(width: 16, height: 16) + .foregroundStyle(Color(.Text.detail)) + .padding(.trailing,24) + } + else { + Image(systemName: "eye.slash") + .frame(width: 16, height: 16) + .foregroundStyle(Color(.Text.detail)) + .padding(.trailing,24) + + } + } + } + } + } + .background { + RoundedRectangle(cornerRadius: 24) + .foregroundStyle(.white) + } + .padding(EdgeInsets(top: 0, leading: 12, bottom: 8, trailing: 12)) + + Button { + isSave.toggle() + } label: { + HStack(alignment: .center, spacing: 4) { + Spacer(minLength: 1) + if isSave { + Image(systemName: "checkmark.square") + .foregroundStyle(Color(.Second.normal)) + .frame(width: 24, height: 24) + } else { + Image(systemName: "square") + .foregroundStyle(Color(.Second.normal)) + .frame(width: 24, height: 24) + } + + Text("로그인 정보 저장") + .font(.nps(font: .regular, size: 16)) + .foregroundStyle(Color(.Text.detail)) + } + } + .padding(EdgeInsets(top: 0, leading: 0, bottom: 24, trailing: 12)) + + Button { + viewModel.loginAction.send(true) + } label: { + Text("로그인") + .font(.nps(font: .bold, size: 24)) + .foregroundStyle(Color(.Text.white)) + .padding(EdgeInsets(top: 8, leading: 48, bottom: 8, trailing: 48)) + .background{ + RoundedRectangle(cornerRadius: 12) + .foregroundStyle(Color(.Second.normal)) + } + } + } + } +} diff --git a/AcaMate/1. View/11. Intro & Login/IntroView.swift b/AcaMate/1. View/11. Intro & Login/IntroView.swift index ab09092..f475baf 100644 --- a/AcaMate/1. View/11. Intro & Login/IntroView.swift +++ b/AcaMate/1. View/11. Intro & Login/IntroView.swift @@ -9,7 +9,8 @@ import SwiftUI import Combine struct IntroView: View { - @EnvironmentObject var alertController: AlertController + @EnvironmentObject var appVM: AppViewModel + @State var cancellables: Set = [] @Binding var naviState : NaviState @@ -17,15 +18,12 @@ struct IntroView: View { VStack(spacing: 0) { Spacer() .frame(height: 100) - Image("Team_Icon") + Image(.Icon.appIcon) .resizable() .frame(width: 200, height: 200) - .background(.white) - .border(.black) - .padding() Spacer() HStack(spacing: 4) { - Image("Team_Icon") + Image(.Icon.teamIcon) .resizable() .frame(width: 24, height: 24) Text("STEIN") @@ -52,32 +50,34 @@ struct IntroView: View { } receiveValue: { version in let compareForce = compareVersion(version.force_ver, currentVersion()) let compareChoice = compareVersion(version.final_ver, currentVersion()) + if compareForce == .bigger { - alertController.alertData = SetAlertData().setForceUpdate( - action: alertController.alertAction + appVM.alertData = SetAlertData().setForceUpdate( + action: appVM.alertAction ) - alertController.showAlert.toggle() + appVM.showAlert.toggle() } else if compareChoice == .bigger && version.choice_update_yn { - alertController.alertData = SetAlertData().setSelectUpdate( - action: alertController.alertAction + appVM.alertData = SetAlertData().setSelectUpdate( + action: appVM.alertAction ) - alertController.showAlert.toggle() + appVM.showAlert.toggle() } else { naviState.set(act: .RESET, path: .Login) } } .store(in: &cancellables) + + } } private func subscribeAlertAction() { - alertController.alertAction + appVM.alertAction .compactMap { $0 } .sink { action in if action == "updateNow" { exit(1) - // MARK: TO-DO - // (앱스토어 이동 로직 넣을 것) + //MARK: - TODO (앱스토어 이동 로직 넣을 것) } else { naviState.set(act: .RESET, path: .Login) } diff --git a/AcaMate/1. View/11. Intro & Login/LoginView.swift b/AcaMate/1. View/11. Intro & Login/LoginView.swift index 18c277f..4909d95 100644 --- a/AcaMate/1. View/11. Intro & Login/LoginView.swift +++ b/AcaMate/1. View/11. Intro & Login/LoginView.swift @@ -6,23 +6,48 @@ // import SwiftUI +import Combine struct LoginView: View { - @EnvironmentObject var alertController: AlertController + @EnvironmentObject var appVM: AppViewModel + @StateObject private var loginVM = LoginViewModel() + @State var cancellables: Set = [] @Binding var naviState : NaviState + @State var selectIdLogin: Bool = false + + @State var userId: String = "" + @State var password: String = "" + @State var isSecure: Bool = true + @State var isSave: Bool = false + var body: some View { VStack(spacing: 0) { - Image("Team_Icon") + Image(.Icon.appIcon) .resizable() - .frame(maxWidth: 200, maxHeight: 200) .frame(width: 200, height: 200) - .background(.white) - .border(.black) - .padding(.bottom, 84) + .padding(.top, 80) /// 앱 아이콘 이미지 - VStack(spacing: 16) { + Button { + // MARK: - TODO, 카카오 계정 로그인 구현 + appVM.isLoading.toggle() + loginAction(type: .Kakao) + } label: { + makeButton(image: Image(.Icon.kakaoIcon),color: Color(.Other.yellow), "카카오 계정으로 시작하기") + } + + Button { + // MARK: - TODO, 애플 계정 로그인 구현 + naviState.set(act: .MOVE, path: .Main) + } label: { + makeButton(image: Image(.Icon.appleIcon), color: Color(.Text.black), "애플 계정으로 시작하기") + } + } + + /* + VStack(spacing: 16) { + Button { // MARK: TO-DO // 카카오 로그인 연동 @@ -70,22 +95,87 @@ struct LoginView: View { .frame(maxWidth: .infinity) /// APPLE 로그인 버튼 } + */ .padding([.leading,.trailing], 28) - /// 버튼 조합 - // 삭제 -// Button { -// alertController.alertData = SetAlertData().setTest() -// alertController.showAlert.toggle() -// // naviState.set(act: .MOVE,path: .Intro) -// -// } label: { -// Text("111111111") -// } - } + .onAppear { + subscribeLoginAction() + } + .frame(maxWidth: .infinity,maxHeight: .infinity) .fullDrawView(.Normal.normal) } + func makeButton(image: Image, color: Color? = nil, _ body: String) -> some View { + return HStack { + image + .resizable() + .frame(width: 32, height: 32) + Spacer(minLength: 12) + Text("\(body)") + .font(.nps(font: .regular, size: 16)) + .foregroundStyle(color == Color(.Text.black) ? Color(.Text.white) : Color(.Text.black)) + Spacer(minLength: 12) + } + .padding(12) + .background { + if let color = color { + RoundedRectangle(cornerRadius: 12) + .foregroundStyle(color) + } + } + } + + private func subscribeLoginAction() { + loginVM.loginAction + .sink { isTapped in + if isTapped { + if userId.isEmpty || password.isEmpty { + appVM.alertData = SetAlertData().setErrorLogin() + appVM.showAlert.toggle() + } + else { + + } + printLog("로그인") + } + } + .store(in: &cancellables) + } + + private func loginAction(type: SNSLoginType) { + LoginController().login(type) + .flatMap{ snsId in + loadAPIData(url: "\(API_URL)", + path: "/api/v1/in/user/login", + parameters: [ + "sns_id": "\(snsId.snsId)", + "acctype": "\(type == .Apple ? "ST00": "ST01")" + ], + decodingType: APIResponse.self) + + } + .sink { completion in + switch completion { + case .failure(let error): + printLog("\(error)") + appVM.isLoading.toggle() + case .finished: + appVM.isLoading.toggle() + } + } receiveValue: { response in + guard let ua = response as? APIResponse else {return} + if let bids = ua.data.toStringDict()["bid"] { + printLog(bids) + if let bidArray: [String] = jsonToSwift(bids) { + printLog(bidArray[0]) + } else { + printLog("JSON 변환 실패") + } + } + } + .store(in: &cancellables) + + } } //#Preview { diff --git a/AcaMate/4. Model/API Response.swift b/AcaMate/2. Model/API Response.swift similarity index 80% rename from AcaMate/4. Model/API Response.swift rename to AcaMate/2. Model/API Response.swift index 890d0bf..aba043f 100644 --- a/AcaMate/4. Model/API Response.swift +++ b/AcaMate/2. Model/API Response.swift @@ -25,5 +25,11 @@ class VersionData: Codable { } +// ---------------- + +class User_Academy: Codable { + let uid: String + let bid: [String] +} diff --git a/AcaMate/4. Model/Alert.swift b/AcaMate/2. Model/Alert.swift similarity index 85% rename from AcaMate/4. Model/Alert.swift rename to AcaMate/2. Model/Alert.swift index 6fcba27..ed1dc65 100644 --- a/AcaMate/4. Model/Alert.swift +++ b/AcaMate/2. Model/Alert.swift @@ -82,5 +82,16 @@ struct SetAlertData { ]) } + /// 로그인 문제 발생 + func setErrorLogin() -> AlertData { + return AlertData(title: "로그인", + body: """ + ID 와 비밀번호가 올바르지 않습니다. + 확인 후 다시 시도해주세요. + """, + button: [ + ButtonType(name: "확인", role: .cancel, function: nil) + ]) + } } diff --git a/AcaMate/4. Model/Navigation.swift b/AcaMate/2. Model/Navigation.swift similarity index 100% rename from AcaMate/4. Model/Navigation.swift rename to AcaMate/2. Model/Navigation.swift diff --git a/AcaMate/4. Model/SNS Data.swift b/AcaMate/2. Model/SNS Data.swift similarity index 100% rename from AcaMate/4. Model/SNS Data.swift rename to AcaMate/2. Model/SNS Data.swift diff --git a/AcaMate/3. ViewModel/AlertViewModel.swift b/AcaMate/3. ViewModel/AlertViewModel.swift new file mode 100644 index 0000000..228379f --- /dev/null +++ b/AcaMate/3. ViewModel/AlertViewModel.swift @@ -0,0 +1,19 @@ +// +// AlertController.swift +// AcaMate +// +// Created by Sean Kim on 12/13/24. +// + +import SwiftUI +import Combine + + +class AlertViewModel2: ObservableObject { + @Published var showAlert: Bool = false + var alertData: AlertData = .init(body: "") + + let alertAction = CurrentValueSubject(nil) + + +} diff --git a/AcaMate/3. ViewModel/AppViewModel.swift b/AcaMate/3. ViewModel/AppViewModel.swift new file mode 100644 index 0000000..39549ca --- /dev/null +++ b/AcaMate/3. ViewModel/AppViewModel.swift @@ -0,0 +1,19 @@ +// +// AppViewModel.swift +// AcaMate +// +// Created by Sean Kim on 12/16/24. +// + +import SwiftUI +import Combine + +class AppViewModel: ObservableObject { + @Published var isLoading: Bool = false + + @Published var showAlert: Bool = false + var alertData: AlertData = .init(body: "") + + let alertAction = CurrentValueSubject(nil) + +} diff --git a/AcaMate/3. ViewModel/LoginViewModel.swift b/AcaMate/3. ViewModel/LoginViewModel.swift new file mode 100644 index 0000000..18694ca --- /dev/null +++ b/AcaMate/3. ViewModel/LoginViewModel.swift @@ -0,0 +1,13 @@ +// +// LoginViewModel.swift +// AcaMate +// +// Created by Sean Kim on 12/14/24. +// + +import SwiftUI +import Combine + +class LoginViewModel: ObservableObject { + let loginAction = CurrentValueSubject(false) +} diff --git a/AcaMate/3. Controller/APIController.swift b/AcaMate/4. Controller/APIController.swift similarity index 100% rename from AcaMate/3. Controller/APIController.swift rename to AcaMate/4. Controller/APIController.swift diff --git a/AcaMate/3. Controller/AlertController.swift b/AcaMate/4. Controller/AlertController.swift similarity index 100% rename from AcaMate/3. Controller/AlertController.swift rename to AcaMate/4. Controller/AlertController.swift diff --git a/AcaMate/3. Controller/KeyController.swift b/AcaMate/4. Controller/KeyController.swift similarity index 100% rename from AcaMate/3. Controller/KeyController.swift rename to AcaMate/4. Controller/KeyController.swift diff --git a/AcaMate/3. Controller/LoginController.swift b/AcaMate/4. Controller/LoginController.swift similarity index 92% rename from AcaMate/3. Controller/LoginController.swift rename to AcaMate/4. Controller/LoginController.swift index 5c082d4..4c66795 100644 --- a/AcaMate/3. Controller/LoginController.swift +++ b/AcaMate/4. Controller/LoginController.swift @@ -12,28 +12,31 @@ import KakaoSDKAuth import KakaoSDKUser import Alamofire +import Foundation -class SNSLogin { +class LoginController { private var cancellables = Set() - func login(type: SNSLoginType){ + func login(_ type: SNSLoginType) -> AnyPublisher { switch type { case .Kakao: - self.checkKakaoToken() - .sink { completion in + return self.checkKakaoToken() + .handleEvents(receiveCompletion: { completion in switch completion { - case .failure(let error): + case .failure(let error) : printLog("KAKAO LOGIN ERROR: \(error)") case .finished: break } - } receiveValue: { snsId in - printLog("로그인 완료 \(snsId)") - } - .store(in: &cancellables) + }) + .eraseToAnyPublisher() +// - case .Apple: break + case .Apple: + return Fail(error: NSError(domain: "Apple login not implemented", code: 1, userInfo: nil)) + .eraseToAnyPublisher() } + } func logout(type: SNSLoginType) { @@ -54,7 +57,7 @@ class SNSLogin { //MARK: - KAKAO LOGIN -extension SNSLogin { +extension LoginController { /// 토큰을 가지고 있나 확인 private func checkKakaoToken() -> Future { return Future { promise in diff --git a/AcaMate/5. Modifier/TextField.swift b/AcaMate/5. Modifier/TextField.swift new file mode 100644 index 0000000..ddaa9d5 --- /dev/null +++ b/AcaMate/5. Modifier/TextField.swift @@ -0,0 +1,65 @@ +// +// UIView.swift +// AcaMate +// +// Created by Sean Kim on 12/14/24. +// + +import SwiftUI +import UIKit + +struct CustomTextField: UIViewRepresentable { + var placeholder: String + @Binding var text: String + + var isSecure: Binding = .constant(false) + + var textColor = UIColor(Color(.Text.detail)) + var font = UIFont(name: "NPS-font-Regular", size: 16) + + // [필수] 초기화 시 UIView 생성 + func makeUIView(context: Context) -> UITextField { + let txf = UITextField() + txf.placeholder = placeholder + txf.isSecureTextEntry = isSecure.wrappedValue + + txf.textColor = textColor + txf.font = font + + txf.translatesAutoresizingMaskIntoConstraints = false + + let height = (font?.lineHeight ?? 10) + 8 + txf.frame.size.height = height + + txf.autocorrectionType = .no + txf.autocapitalizationType = .none + txf.smartInsertDeleteType = .no + txf.textContentType = .oneTimeCode + + txf.delegate = context.coordinator + return txf + } + + // [필수] 스유 상태 변화 따라 UIView 업데이트 + func updateUIView(_ uiView: UITextField, context: Context) { + uiView.text = text + uiView.isSecureTextEntry = isSecure.wrappedValue + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + class Coordinator: NSObject, UITextFieldDelegate { + var parent: CustomTextField + + init(_ parent: CustomTextField) { + self.parent = parent + } + + func textFieldDidChangeSelection(_ textField: UITextField) { + parent.text = textField.text ?? "" + } + } + +} diff --git a/AcaMate/5. Modifier/View.swift b/AcaMate/5. Modifier/View.swift index f5a7b1c..bed4bf6 100644 --- a/AcaMate/5. Modifier/View.swift +++ b/AcaMate/5. Modifier/View.swift @@ -8,28 +8,29 @@ import SwiftUI import Combine + struct NetworkModifier: ViewModifier { @ObservedObject private var networkMonitor = NetworkMonitor.shared - @EnvironmentObject var alertController: AlertController + @EnvironmentObject var appVM: AppViewModel func body(content: Content) -> some View { content .onChange(of: networkMonitor.isConnected) { _ , new in if !new { - alertController.alertData = SetAlertData().setErrorNetwork() - alertController.showAlert.toggle() + appVM.alertData = SetAlertData().setErrorNetwork() + appVM.showAlert.toggle() } } } } struct AlertModifier: ViewModifier { - @EnvironmentObject var controller: AlertController + @EnvironmentObject var appVM: AppViewModel func body(content: Content) -> some View { content - .alert(controller.alertData.title, - isPresented: $controller.showAlert, - presenting: $controller.alertData) { data in + .alert(appVM.alertData.title, + isPresented: $appVM.showAlert, + presenting: $appVM.alertData) { data in let btnCount = data.button.count ForEach(0 ..< btnCount, id: \.self) { index in let btn = data.wrappedValue.button[index] @@ -45,6 +46,32 @@ struct AlertModifier: ViewModifier { } } +struct LoadingModifier: ViewModifier { + @Binding var isLoading: Bool + + func body(content: Content) -> some View { + ZStack { + content + .disabled(isLoading) + .blur(radius: isLoading ? 3:0) + if isLoading { + Color.Text.detail.opacity(0.6) +// Color.Second.normal.opacity(0.3) + .ignoresSafeArea() + ProgressView("Loading...") +// .tint(Color.Text.black) + .tint(Color.Normal.normal) + .scaleEffect(1.5) + .foregroundStyle(Color.Normal.normal) + + .font(.nps(font: .bold, size: 16)) + + .padding() + } + } + } +} + extension View { /// View에 전체적으로 색 입히기 func fullDrawView(_ backColor: Color) -> some View { @@ -64,10 +91,8 @@ extension View { UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) } - func setNavigaion() -> some View { - self - .navigationBarBackButtonHidden(true) - .toolbar(.hidden, for: .navigationBar) + func loadingView(isLoading: Binding) -> some View { + self.modifier(LoadingModifier(isLoading: isLoading)) } func innerShadow (shape: S, color: Color, lineWidth: CGFloat = 6, blur: CGFloat, x: CGFloat, y: CGFloat) -> some View { diff --git a/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/Contents.json index 2305880..5a178b1 100644 --- a/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,6 +1,7 @@ { "images" : [ { + "filename" : "LOGO.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" @@ -12,6 +13,7 @@ "value" : "dark" } ], + "filename" : "LOGO 1.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" @@ -23,6 +25,7 @@ "value" : "tinted" } ], + "filename" : "LOGO 2.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" diff --git a/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO 1.png b/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO 1.png new file mode 100644 index 0000000..38f90a2 Binary files /dev/null and b/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO 1.png differ diff --git a/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO 2.png b/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO 2.png new file mode 100644 index 0000000..38f90a2 Binary files /dev/null and b/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO 2.png differ diff --git a/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO.png b/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO.png new file mode 100644 index 0000000..38f90a2 Binary files /dev/null and b/AcaMate/6. Resources/Assets.xcassets/AppIcon.appiconset/LOGO.png differ diff --git a/AcaMate/6. Resources/Assets.xcassets/Color Folder/Text/Border.colorset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Color Folder/Text/Border.colorset/Contents.json new file mode 100644 index 0000000..5321c93 --- /dev/null +++ b/AcaMate/6. Resources/Assets.xcassets/Color Folder/Text/Border.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.776", + "green" : "0.776", + "red" : "0.776" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/App_Icon.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/App_Icon.imageset/Contents.json new file mode 100644 index 0000000..eee8d7c --- /dev/null +++ b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/App_Icon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "appIcon.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/App_Icon.imageset/appIcon.png b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/App_Icon.imageset/appIcon.png new file mode 100644 index 0000000..141f54d Binary files /dev/null and b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/App_Icon.imageset/appIcon.png differ diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Apple_Icon.imageset/APPLE.png b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Apple_Icon.imageset/APPLE.png new file mode 100644 index 0000000..6038e82 Binary files /dev/null and b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Apple_Icon.imageset/APPLE.png differ diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Apple_Icon.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Apple_Icon.imageset/Contents.json new file mode 100644 index 0000000..687ec46 --- /dev/null +++ b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Apple_Icon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "APPLE.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Contents.json new file mode 100644 index 0000000..6e96565 --- /dev/null +++ b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Kakao_Icon.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Kakao_Icon.imageset/Contents.json new file mode 100644 index 0000000..d0dc9a9 --- /dev/null +++ b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Kakao_Icon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "KAKAO.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Kakao_Icon.imageset/KAKAO.png b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Kakao_Icon.imageset/KAKAO.png new file mode 100644 index 0000000..9c6d857 Binary files /dev/null and b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Kakao_Icon.imageset/KAKAO.png differ diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/MI.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/MI.imageset/Contents.json new file mode 100644 index 0000000..53ec8f8 --- /dev/null +++ b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/MI.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "MI.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/MI.imageset/MI.png b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/MI.imageset/MI.png similarity index 100% rename from AcaMate/6. Resources/Assets.xcassets/Image Folder/MI.imageset/MI.png rename to AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/MI.imageset/MI.png diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Page_Icon.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Page_Icon.imageset/Contents.json new file mode 100644 index 0000000..5c6e62d --- /dev/null +++ b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Page_Icon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "PageIcon.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Page_Icon.imageset/PageIcon.png b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Page_Icon.imageset/PageIcon.png new file mode 100644 index 0000000..49593e9 Binary files /dev/null and b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Page_Icon.imageset/PageIcon.png differ diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Team_Icon.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Team_Icon.imageset/Contents.json new file mode 100644 index 0000000..935211c --- /dev/null +++ b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Team_Icon.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "TeamIcon.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Team_Icon.imageset/1024.png b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Team_Icon.imageset/TeamIcon.png similarity index 100% rename from AcaMate/6. Resources/Assets.xcassets/Image Folder/Team_Icon.imageset/1024.png rename to AcaMate/6. Resources/Assets.xcassets/Image Folder/Icon/Team_Icon.imageset/TeamIcon.png diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Kakao_Icon.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Kakao_Icon.imageset/Contents.json deleted file mode 100644 index 234e650..0000000 --- a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Kakao_Icon.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "filename" : "KakaoIcon.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Kakao_Icon.imageset/KakaoIcon.png b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Kakao_Icon.imageset/KakaoIcon.png deleted file mode 100644 index 6eaf887..0000000 Binary files a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Kakao_Icon.imageset/KakaoIcon.png and /dev/null differ diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/MI.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/MI.imageset/Contents.json deleted file mode 100644 index 3958985..0000000 --- a/AcaMate/6. Resources/Assets.xcassets/Image Folder/MI.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "filename" : "MI.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Team_Icon.imageset/Contents.json b/AcaMate/6. Resources/Assets.xcassets/Image Folder/Team_Icon.imageset/Contents.json deleted file mode 100644 index 94202f5..0000000 --- a/AcaMate/6. Resources/Assets.xcassets/Image Folder/Team_Icon.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "filename" : "1024.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/AcaMate/6. Resources/Images/Icon/APPLE.png b/AcaMate/6. Resources/Images/Icon/APPLE.png new file mode 100644 index 0000000..6038e82 Binary files /dev/null and b/AcaMate/6. Resources/Images/Icon/APPLE.png differ diff --git a/AcaMate/6. Resources/Images/Icon/KAKAO.png b/AcaMate/6. Resources/Images/Icon/KAKAO.png new file mode 100644 index 0000000..9c6d857 Binary files /dev/null and b/AcaMate/6. Resources/Images/Icon/KAKAO.png differ diff --git a/AcaMate/6. Resources/Images/Icon/LOGO.png b/AcaMate/6. Resources/Images/Icon/LOGO.png new file mode 100644 index 0000000..38f90a2 Binary files /dev/null and b/AcaMate/6. Resources/Images/Icon/LOGO.png differ diff --git a/AcaMate/6. Resources/Images/MI.png b/AcaMate/6. Resources/Images/Icon/MI.png similarity index 100% rename from AcaMate/6. Resources/Images/MI.png rename to AcaMate/6. Resources/Images/Icon/MI.png diff --git a/AcaMate/6. Resources/Images/Icon/PageIcon.png b/AcaMate/6. Resources/Images/Icon/PageIcon.png new file mode 100644 index 0000000..49593e9 Binary files /dev/null and b/AcaMate/6. Resources/Images/Icon/PageIcon.png differ diff --git a/AcaMate/6. Resources/Images/Team_Icon.png b/AcaMate/6. Resources/Images/Icon/TeamIcon.png similarity index 100% rename from AcaMate/6. Resources/Images/Team_Icon.png rename to AcaMate/6. Resources/Images/Icon/TeamIcon.png diff --git a/AcaMate/6. Resources/Images/Icon/appIcon.png b/AcaMate/6. Resources/Images/Icon/appIcon.png new file mode 100644 index 0000000..141f54d Binary files /dev/null and b/AcaMate/6. Resources/Images/Icon/appIcon.png differ diff --git a/AcaMate/6. Resources/Images/KakaoIcon.png b/AcaMate/6. Resources/Images/KakaoIcon.png deleted file mode 100644 index 6eaf887..0000000 Binary files a/AcaMate/6. Resources/Images/KakaoIcon.png and /dev/null differ diff --git a/AcaMate/AcaMateApp.swift b/AcaMate/AcaMateApp.swift index f7adeeb..8c2fade 100644 --- a/AcaMate/AcaMateApp.swift +++ b/AcaMate/AcaMateApp.swift @@ -15,7 +15,7 @@ import KakaoSDKAuth struct AcaMateApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var cancellables: Set = [] - var alertController = AlertController() + @StateObject var appVM = AppViewModel() init() { printLog("APP INIT") @@ -29,7 +29,7 @@ struct AcaMateApp: App { _ = AuthController.handleOpenUrl(url: url) } } - .environmentObject(self.alertController) + .environmentObject(self.appVM) } } } diff --git a/AcaMate/GoogleService-Info.plist b/AcaMate/GoogleService-Info.plist new file mode 100644 index 0000000..69fbb6b --- /dev/null +++ b/AcaMate/GoogleService-Info.plist @@ -0,0 +1,30 @@ + + + + + API_KEY + AIzaSyBsdv91LqE7F-ZnOGZ018FjlDR8S6trIyc + GCM_SENDER_ID + 477645655994 + PLIST_VERSION + 1 + BUNDLE_ID + me.myds.ipstein.acamate.AcaMate + PROJECT_ID + acamate-350fd + STORAGE_BUCKET + acamate-350fd.firebasestorage.app + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:477645655994:ios:dd3f8f91d85c5516481783 + + \ No newline at end of file diff --git a/AcaMate/LaunchScreen.storyboard b/AcaMate/LaunchScreen.storyboard index c846eb2..cb28862 100644 --- a/AcaMate/LaunchScreen.storyboard +++ b/AcaMate/LaunchScreen.storyboard @@ -1,5 +1,5 @@ - + @@ -17,42 +17,36 @@ - + - - + + - - + - - - - - - - - - - + + + + + + + + + - + - + +