[♻️] Intro 로직 변경

This commit is contained in:
김선규 2025-03-24 09:03:27 +09:00
parent 48c8f4dfda
commit 45a28e386d
9 changed files with 218 additions and 172 deletions

View File

@ -40,6 +40,8 @@ public let WS_URL: String = "wss://acamate.ipstein.myds.me"
#endif
public let API_HEADER = "iOS_AM_Connect_Key"
// MARK: - TYPEALIAS
typealias VOID_TO_VOID = () -> ()

View File

@ -22,9 +22,9 @@ struct NavigationView: View {
case .NONE:
EmptyView()
case .Intro:
IntroView()
IntroView(appVM: appVM)
case .Login :
LoginView()
LoginView(appVM: appVM)
case .Register(let type, let id):
RegisterView(type: type, snsID: id)
case .SelectAcademy:

View File

@ -9,10 +9,15 @@ import SwiftUI
import Combine
struct IntroView: View {
@EnvironmentObject var appVM: AppViewModel
// @EnvironmentObject var appVM: AppViewModel
@StateObject private var introVM : IntroViewModel
@State var cancellables: Set<AnyCancellable> = []
// @Binding var naviState : NaviState
init(appVM: AppViewModel){
_introVM = StateObject(wrappedValue: IntroViewModel(appVM: appVM))
// self.introVM = IntroViewModel(appVM: appVM)
}
var body: some View {
VStack(spacing: 0) {
@ -39,95 +44,7 @@ struct IntroView: View {
.onAppear {
printLog("IntroView_onAppear")
#if LOCAL
appVM.naviState.set(act: .RESET, path: .Login)
#else
subscribeAlertAction()
loadVersion()
.sink { completion in
switch completion {
case .failure(let error):
printLog(error)
case .finished: break
introVM.appStart()
}
} receiveValue: { version in
@UserDefault(key:"currentVer", defaultValue: "0.0.0") var currentVer
@UserDefault(key:"finalVer", defaultValue: "0.0.0") var finalVer
currentVer = currentVersion()
finalVer = version.final_ver
let compareForce = compareVersion(version.force_ver, currentVer)//currentVersion())
let compareChoice = compareVersion(version.final_ver, currentVer)//currentVersion())
if compareForce == .bigger {
appVM.alertData = SetAlertData().setForceUpdate(
action: appVM.alertAction
)
appVM.showAlert.toggle()
} else if compareChoice == .bigger && version.choice_update_yn {
appVM.alertData = SetAlertData().setSelectUpdate(
action: appVM.alertAction
)
appVM.showAlert.toggle()
} else {
//
appVM.naviState.set(act: .RESET, path: .Login)
// naviState.set(act: .RESET, path: .Login)
}
}
.store(in: &cancellables)
#endif
}
}
private func subscribeAlertAction() {
appVM.alertAction
.compactMap { $0 }
.sink { action in
if action == "updateNow" {
exit(1)
//MARK: - TODO ( )
} else {
appVM.naviState.set(act: .RESET, path: .Login)
}
}.store(in: &cancellables)
}
private func loadVersion() -> Future<VersionData, Error> {
return Future { promise in
let request = APIRequest(path: "/api/v1/in/app/version",
parameters: ["type":"I"],
decoding: APIResponse<VersionData>.self)
APIManager.shared.loadAPIData(request)
.sink { completion in
switch completion {
case .failure(let error):
printLog("\(error)")
promise(.failure(error))
case .finished: break
}
} receiveValue: { data in
guard let apiData = data as? APIResponse<VersionData>, let version = apiData.data else {return}
printLog("\(version.toStringDict())")
promise(.success(version))
}
.store(in: &cancellables)
}
}
private func currentVersion() -> String {
guard let currentVer = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { return "" }
return currentVer
}
private func versionChange(ver: String) -> [Int] {
return ver.components(separatedBy: ["."]).map {Int($0) ?? 0}
}
}

View File

@ -9,8 +9,11 @@ import SwiftUI
import Combine
struct LoginView: View {
@EnvironmentObject var appVM: AppViewModel
@StateObject private var loginVM = LoginViewModel()
// @EnvironmentObject var appVM: AppViewModel
@StateObject private var loginVM: LoginViewModel
init(appVM : AppViewModel) {
_loginVM = StateObject(wrappedValue: LoginViewModel(appVM: appVM))
}
var body: some View {
VStack(spacing: 0) {
@ -25,7 +28,7 @@ struct LoginView: View {
VStack(spacing: 16) {
Button {
// MARK: - TODO,
loginVM.toggleLoading = true
// loginVM.toggleLoading = true
loginVM.loginAction(type: .Kakao)
} label: {
@ -37,7 +40,7 @@ struct LoginView: View {
// appVM.naviState.set(act: .ADD, path: .SelectAcademy(bids: ["AA0000", "AA0001"]))
// loginVM.toggleLoading = true
// loginVM.loginTest(type: .Kakao, id: "TestSNSID1@#")
loginVM.USERPAITEST()
// loginVM.USERPAITEST()
} label: {
@ -51,13 +54,14 @@ struct LoginView: View {
}
.frame(maxWidth: .infinity,maxHeight: .infinity)
.fullDrawView(.Normal.normal)
.onChange(of: loginVM.pathName){ _, new in
appVM.naviState.set(act: .ADD, path: new)
}
.onChange(of: loginVM.toggleLoading) { _, new in
appVM.isLoading = new
}
// .onChange(of: loginVM.pathName){ _, new in
// appVM.naviState.set(act: .ADD, path: new)
// }
//
// .onChange(of: loginVM.toggleLoading) { _, new in
// appVM.isLoading = new
// }
}

View File

@ -82,6 +82,17 @@ struct SetAlertData {
])
}
/// -
func setServerError(action: CurrentValueSubject<String?, Never>) -> AlertData {
return AlertData(title: "시스템 오류", body: "시스템이 정상적이지 않습니다. \n확인 후 다시 시도해주세요.",
button: [
ButtonType(name: "확인", role: .cancel,
function: {
action.send("exit")
})
])
}
///
func setErrorLogin() -> AlertData {
return AlertData(title: "로그인",

View File

@ -16,6 +16,7 @@ class AppViewModel: ObservableObject {
var alertData: AlertData = .init(body: "")
///
let alertAction = CurrentValueSubject<String?, Never>(nil)
}

View File

@ -5,4 +5,161 @@
// Created by TAnine on 3/20/25.
//
import Foundation
import SwiftUI
import Combine
class IntroViewModel: ObservableObject {
var appVM : AppViewModel
private var cancellables = Set<AnyCancellable>()
// @Published var toggleLoading: Bool = false
// @Published var pathName: PathName = .NONE
@UserDefault(key: "header", defaultValue: "headerValue") var headerValue
init(appVM: AppViewModel) {
self.appVM = appVM
}
func appStart() {
//#if LOCAL
// pathName = .Login
//#else
subscribeAlertAction()
searchHeader()
.flatMap { success -> Future<VersionData, Error> in
return self.loadVersion()
}
.sink { completion in
switch completion {
case .failure(let error):
printLog(error)
case .finished: break
}
} receiveValue: { [weak self] version in
guard let self = self else {return}
@UserDefault(key:"currentVer", defaultValue: "0.0.0") var currentVer
@UserDefault(key:"finalVer", defaultValue: "0.0.0") var finalVer
currentVer = currentVersion()
finalVer = version.final_ver
let compareForce = compareVersion(version.force_ver, currentVer)//currentVersion())
let compareChoice = compareVersion(version.final_ver, currentVer)//currentVersion())
if compareForce == .bigger {
appVM.alertData = SetAlertData().setForceUpdate(
action: appVM.alertAction
)
appVM.showAlert.toggle()
} else if compareChoice == .bigger && version.choice_update_yn {
appVM.alertData = SetAlertData().setSelectUpdate(
action: appVM.alertAction
)
appVM.showAlert.toggle()
} else {
//
appVM.naviState.set(act: .RESET, path: .Login)
}
}
.store(in: &cancellables)
}
func searchHeader() -> Future<Bool, Error> {
return Future { [weak self] promise in
guard let self = self else {
promise(.failure(ACA_ERROR("Self 전환 오류")))
return
}
guard let deviceId = UIDevice.current.identifierForVendor?.uuidString,
let bundleId = Bundle.main.bundleIdentifier else {
promise(.failure(ACA_ERROR("번들/디바이스 아이디 조회 불량")))
return
}
let request = APIRequest(path: "/api/v1/in/app",
parameters: ["type": "I", "specific": deviceId, "project": bundleId],
decoding: APIResponse<Header>.self)
APIManager.shared.loadAPIData(request)
.sink { completion in
switch completion {
case .failure(let error):
printLog("최종 에러: \(error)")
promise(.failure(error))
case .finished:
break
}
} receiveValue: { [weak self] response in
guard let self = self else {return}
if let data = response.data {
self.headerValue = data.header
promise(.success(true))
}
else {
promise(.failure(ACA_ERROR("데이터 없음")))
}
}
.store(in: &self.cancellables)
}
//
}
private func subscribeAlertAction() {
appVM.alertAction
.compactMap { $0 }
.sink { [weak self] action in
guard let self = self else {return}
if action == "exit" {
exit(1)
} else if action == "updateNow" {
exit(1)
//MARK: - TODO ( )
} else {
appVM.naviState.set(act: .RESET, path: .Login)
}
}.store(in: &cancellables)
}
private func loadVersion() -> Future<VersionData, Error> {
return Future { [weak self] promise in
guard let self = self else {return}
let request = APIRequest(path: "/api/v1/in/app/version",
headers: [API_HEADER : self.headerValue],
parameters: ["type":"I"],
decoding: APIResponse<VersionData>.self)
APIManager.shared.loadAPIData(request)
.sink { completion in
switch completion {
case .failure(let error):
printLog("\(error)")
promise(.failure(error))
case .finished: break
}
} receiveValue: { versionData in
guard let version = versionData.data else {return}
printLog("\(version.toStringDict())")
promise(.success(version))
}
.store(in: &cancellables)
}
}
private func currentVersion() -> String {
guard let currentVer = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { return "" }
return currentVer
}
private func versionChange(ver: String) -> [Int] {
return ver.components(separatedBy: ["."]).map {Int($0) ?? 0}
}
}

View File

@ -10,74 +10,31 @@ import Combine
class LoginViewModel: ObservableObject {
let appVM: AppViewModel
private var cancellables = Set<AnyCancellable>()
@Published var toggleLoading: Bool = false
@Published var pathName: PathName = .NONE
// @Published var toggleLoading: Bool = false
// @Published var pathName: PathName = .NONE
var bidArray: [String] = []
func USERPAITEST() {
@UserDefault(key: "token", defaultValue: "accToken") var accToken
@UserDefault(key: "refresh", defaultValue: "refreshToken") var refresh
@UserDefault(key: "header", defaultValue: "headerValue") var headerValue
// UIDevice identifierForVendor (UUID)
guard let deviceId = UIDevice.current.identifierForVendor?.uuidString else { return }
guard let bundleId = Bundle.main.bundleIdentifier else { return }
var bidArray: [String] = []
//
let request = APIRequest(path: "/api/v1/in/app",
parameters: ["type": "I", "specific": deviceId, "project": bundleId],
decoding: APIResponse<Header>.self)
//
APIManager.shared.loadAPIData(request)
.sink { completion in
switch completion {
case .failure(let error):
printLog("최종 에러: \(error)")
case .finished:
break
init(appVM: AppViewModel) {
self.appVM = appVM
}
} receiveValue: { response in
// guard let response = response as? APIResponse<Header> else { return }
printLog(response.data?.header)
}
.store(in: &cancellables)
/*
let acc = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJBTVRlc3RFbWFpbDIwMjUwMzE4IiwianRpIjoiMjgwMjIwZDMtYzUwNS00YjFjLTgwMzgtZjBlNGJjYzM4MTE3IiwiZXhwIjoxNzQyMjYzMzgwLCJpc3MiOiJBY2FNYXRlIiwiYXVkIjoiaHR0cHM6L2RldmFjYW1hdGUuaXBzdGVpbi5teWRzLm1lIn0.f6kLKnsWhzlllSuYKxpFNuXuV4vOtJ2ox4IGSnxE67Y"
refresh = "MRo+1HIvaPgECXrvwmGvtUpxSk7Pip7KtGSoWDqmjVA="
let request = APIRequest(path: "/api/v1/in/user",
parameters: ["token": accToken],
decoding: APIResponse<User>.self)
APIManager.shared.loadUserAPIData(request: request)
.sink { completion in
switch completion {
case .failure(let error):
printLog("최종 에러: \(error)")
case .finished:
break
}
} receiveValue: { response in
guard let user = response.data as? User else { return }
printLog("최종 값 : \(user.name), \(user.birth)")
}
.store(in: &cancellables)
*/
}
func loginAction(type: SNSLoginType) {
appVM.isLoading = true
LoginController().login(type)
.flatMap{ snsId in
APIManager.shared.loadAPIData(APIRequest(path: "/api/v1/in/user/login",
headers: [API_HEADER : self.headerValue],
parameters: [
"acctype": "\(type == .Apple ? "ST00": "ST01")",
"sns_id": "\(snsId.snsId)"
"snsId": "\(snsId.snsId)"
],
decoding: APIResponse<User_Token>.self))
.map { response in
@ -85,38 +42,35 @@ class LoginViewModel: ObservableObject {
}
}
.sink { [weak self] completion in
guard let self = self else { return }
// API
switch completion {
case .failure(let error):
self?.toggleLoading = false
self.appVM.isLoading = false
printLog("\(error)")
case .finished:
self?.toggleLoading = false
self.appVM.isLoading = false
}
} receiveValue: { [weak self] response in
guard let self = self else { return }
// let userToken = response.response // as? APIResponse<User_Token> else {return}
let snsId = response.snsId
switch response.response.status.code {
case .success(let code):
if code == "000" {
@UserDefault(key: "token", defaultValue: "accToken") var accToken
@UserDefault(key: "refresh", defaultValue: "refreshToken") var refreshToken
if let token = response.response.data.toStringDict()["token"],
let refresh = response.response.data.toStringDict()["refresh"] {
printLog(token)
printLog(refresh)
accToken = token
refreshToken = refresh
self.pathName = .SelectAcademy
self.accToken = token
self.refresh = refresh
appVM.naviState.set(act: .ADD, path: .SelectAcademy)
}
} else {
//
//
self.pathName = .Register(type, id: "\(snsId)")
appVM.naviState.set(act: .ADD, path: .Register(type, id: "\(snsId)"))
}
case .anything(let apiCode):
// MARK: TO-DO