forked from AcaMate/AcaMate_iOS
[♻️] Intro 로직 변경
This commit is contained in:
parent
48c8f4dfda
commit
45a28e386d
Binary file not shown.
|
@ -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 = () -> ()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
}
|
||||
} 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)
|
||||
|
||||
|
||||
introVM.appStart()
|
||||
}
|
||||
}
|
||||
.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}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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: "로그인",
|
||||
|
|
|
@ -16,6 +16,7 @@ class AppViewModel: ObservableObject {
|
|||
|
||||
var alertData: AlertData = .init(body: "")
|
||||
|
||||
/// 항상 최신값을 가지고 있다가 구독자 추가 되면 그 즉시 값을 전달하고 이후 업데이트 되는 값을 계속 보내주는 역할을 함
|
||||
let alertAction = CurrentValueSubject<String?, Never>(nil)
|
||||
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user