AcaMate_iOS/AcaMate/3. ViewModel/IntroViewModel.swift

166 lines
5.8 KiB
Swift

//
// IntroViewModel.swift
// AcaMate
//
// Created by TAnine on 3/20/25.
//
import SwiftUI
import Combine
class IntroViewModel: ObservableObject {
private let appVM: AppViewModel
private var cancellables = Set<AnyCancellable>()
@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)
appVM.apiManager.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)
appVM.apiManager.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}
}
}