forked from AcaMate/AcaMate_iOS
[✨] 회원가입 화면 추가 및 몇가지 동작 로직 수정
This commit is contained in:
parent
45a28e386d
commit
5a2c237e3a
Binary file not shown.
78
AcaMate/0. Setup/WebView.swift
Normal file
78
AcaMate/0. Setup/WebView.swift
Normal file
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// WebView.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 3/24/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import WebKit
|
||||
|
||||
struct WebView: UIViewControllerRepresentable {
|
||||
@Binding var isLoding: Bool
|
||||
func updateUIViewController(_ uiViewController: WebViewController, context: Context) {
|
||||
}
|
||||
|
||||
func makeUIViewController(context: Context) -> WebViewController {
|
||||
return WebViewController()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class WebViewController: UIViewController, WKUIDelegate {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
webView()
|
||||
}
|
||||
|
||||
func webView() {
|
||||
let url = URL(string: "https://sean-59.github.io/Kakao-Postcode/")!
|
||||
let request = URLRequest(url: url)
|
||||
|
||||
let configuration = WKWebViewConfiguration()
|
||||
let contentController = WKUserContentController()
|
||||
|
||||
contentController.add(self, name: "callBackHandler")
|
||||
configuration.userContentController = contentController
|
||||
|
||||
let webview = WKWebView(frame: view.bounds, configuration: configuration)
|
||||
webview.uiDelegate = self
|
||||
webview.navigationDelegate = self
|
||||
webview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
|
||||
webview.isUserInteractionEnabled = true
|
||||
webview.scrollView.isUserInteractionEnabled = true
|
||||
webview.scrollView.delaysContentTouches = false
|
||||
|
||||
webview.load(request)
|
||||
view.addSubview(webview)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension WebViewController: WKNavigationDelegate {
|
||||
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
|
||||
print("웹뷰 로딩 시작")
|
||||
}
|
||||
|
||||
|
||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
print("웹뷰 로딩 완료")
|
||||
// 여기서 추가 작업(예: 로딩 인디케이터 숨기기)을 수행할 수 있습니다.
|
||||
}
|
||||
}
|
||||
|
||||
extension WebViewController: WKScriptMessageHandler {
|
||||
func userContentController(_ userContentController: WKUserContentController,
|
||||
didReceive message: WKScriptMessage) {
|
||||
if let data = message.body as? [String: Any] {
|
||||
print(data)
|
||||
print(data["jibunAddress"] ?? "jibunAddress 없음")
|
||||
print(data["roadAddress"] ?? "roadAddress 없음")
|
||||
print(data["zonecode"] ?? "zonecode 없음")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,13 +22,13 @@ struct NavigationView: View {
|
|||
case .NONE:
|
||||
EmptyView()
|
||||
case .Intro:
|
||||
IntroView(appVM: appVM)
|
||||
IntroView(appVM)
|
||||
case .Login :
|
||||
LoginView(appVM: appVM)
|
||||
LoginView(appVM)
|
||||
case .Register(let type, let id):
|
||||
RegisterView(type: type, snsID: id)
|
||||
RegisterView(appVM, type: type, snsID: id)
|
||||
case .SelectAcademy:
|
||||
SelectAcademyView()
|
||||
SelectAcademyView(appVM)
|
||||
case .Main:
|
||||
MainView()
|
||||
case .ChatRoom(let id):
|
||||
|
|
|
@ -8,15 +8,14 @@
|
|||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
|
||||
struct IntroView: View {
|
||||
// @EnvironmentObject var appVM: AppViewModel
|
||||
@StateObject private var introVM : IntroViewModel
|
||||
|
||||
@EnvironmentObject var appVM: AppViewModel
|
||||
@StateObject var introVM: IntroViewModel
|
||||
@State var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
init(appVM: AppViewModel){
|
||||
_introVM = StateObject(wrappedValue: IntroViewModel(appVM: appVM))
|
||||
// self.introVM = IntroViewModel(appVM: appVM)
|
||||
init(_ appVM: AppViewModel) {
|
||||
_introVM = StateObject(wrappedValue: IntroViewModel(appVM))
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
|
|
|
@ -8,13 +8,16 @@
|
|||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
|
||||
struct LoginView: View {
|
||||
// @EnvironmentObject var appVM: AppViewModel
|
||||
@StateObject private var loginVM: LoginViewModel
|
||||
init(appVM : AppViewModel) {
|
||||
_loginVM = StateObject(wrappedValue: LoginViewModel(appVM: appVM))
|
||||
@EnvironmentObject var appVM: AppViewModel
|
||||
@StateObject var loginVM: LoginViewModel
|
||||
|
||||
init(_ appVM: AppViewModel) {
|
||||
_loginVM = StateObject(wrappedValue: LoginViewModel(appVM))
|
||||
}
|
||||
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
Spacer().frame(height: 100)
|
||||
|
@ -54,6 +57,9 @@ struct LoginView: View {
|
|||
}
|
||||
.frame(maxWidth: .infinity,maxHeight: .infinity)
|
||||
.fullDrawView(.Normal.normal)
|
||||
.onAppear() {
|
||||
|
||||
}
|
||||
|
||||
// .onChange(of: loginVM.pathName){ _, new in
|
||||
// appVM.naviState.set(act: .ADD, path: new)
|
||||
|
|
|
@ -11,37 +11,146 @@ struct RegisterView: View {
|
|||
@EnvironmentObject var appVM: AppViewModel
|
||||
@StateObject private var topVM = TopViewModel()
|
||||
@StateObject var btnVM = ButtonViewModel()
|
||||
@StateObject var registerVM: RegisterViewModel
|
||||
|
||||
private let responseValue: (SNSLoginType, String)
|
||||
|
||||
init(_ appVM: AppViewModel, type: SNSLoginType, snsID: String) {
|
||||
_registerVM = StateObject(wrappedValue: RegisterViewModel(appVM))
|
||||
self.responseValue.0 = type
|
||||
self.responseValue.1 = snsID
|
||||
}
|
||||
|
||||
|
||||
@State private var scrollOffset: CGPoint = .zero
|
||||
@State private var showWebView = false
|
||||
|
||||
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()
|
||||
}()
|
||||
|
||||
let addressBtnID = UUID()
|
||||
let registerBtnID = UUID()
|
||||
|
||||
|
||||
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])
|
||||
// 이름
|
||||
HStack(spacing: 0){
|
||||
HStack(spacing: 0) {
|
||||
Text("이름")
|
||||
.font(.nps(size: 16))
|
||||
Text("*")
|
||||
.font(.nps(size: 16))
|
||||
.foregroundStyle(Color(.Other.red))
|
||||
}
|
||||
.frame(width: 60, alignment: .leading)
|
||||
Spacer(minLength: 1)
|
||||
CustomTextField(placeholder: "최대 10글자", text: $registerVM.nameText)
|
||||
.frame(maxWidth: .infinity,maxHeight: 48)
|
||||
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(Color(.Normal.light))
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
|
||||
// 생년월일
|
||||
DatePicker("생일", selection: $registerVM.selectDate, displayedComponents: [.date])
|
||||
.datePickerStyle(.compact)
|
||||
.environment(\.locale, Locale(identifier: "ko_KR"))
|
||||
.font(.nps(size: 16))
|
||||
.padding()
|
||||
|
||||
// E-Mail
|
||||
HStack(spacing: 0){
|
||||
Text("이메일")
|
||||
.font(.nps(size: 16))
|
||||
.frame(width: 60, alignment: .leading)
|
||||
Spacer(minLength: 1)
|
||||
CustomTextField(placeholder: "앞부분 입력", text: $registerVM.emailFrontText)
|
||||
.frame(maxWidth: .infinity,maxHeight: 48)
|
||||
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(Color(.Normal.light))
|
||||
}
|
||||
// Spacer(minLength: 1)
|
||||
Text("@")
|
||||
.font(.nps(font: .bold, size: 16))
|
||||
.padding([.leading, .trailing], 4)
|
||||
// Spacer(minLength: 1)
|
||||
CustomTextField(placeholder: "뒷부분 입력", text: $registerVM.emailTailText)
|
||||
.frame(maxWidth: .infinity,maxHeight: 48)
|
||||
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(Color(.Normal.light))
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
|
||||
// Phone
|
||||
HStack(spacing: 0){
|
||||
Text("연락처")
|
||||
.font(.nps(size: 16))
|
||||
.frame(width: 60, alignment: .leading)
|
||||
|
||||
CustomTextField(placeholder: "000", text: $registerVM.nameText)
|
||||
.frame(maxWidth: .infinity,maxHeight: 48)
|
||||
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(Color(.Normal.light))
|
||||
}
|
||||
Text("-")
|
||||
.font(.nps(size: 16))
|
||||
.padding([.leading, .trailing], 4)
|
||||
CustomTextField(placeholder: "0000", text: $registerVM.nameText)
|
||||
.frame(maxWidth: .infinity,maxHeight: 48)
|
||||
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(Color(.Normal.light))
|
||||
}
|
||||
Text("-")
|
||||
.font(.nps(size: 16))
|
||||
.padding([.leading, .trailing], 4)
|
||||
CustomTextField(placeholder: "0000", text: $registerVM.nameText)
|
||||
.frame(maxWidth: .infinity,maxHeight: 48)
|
||||
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
|
||||
.background {
|
||||
RoundedRectangle(cornerRadius: 24)
|
||||
.foregroundStyle(Color(.Normal.light))
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
|
||||
HStack(spacing: 0){
|
||||
Text("연락처")
|
||||
.font(.nps(size: 16))
|
||||
.frame(width: 60, alignment: .leading)
|
||||
Spacer(minLength: 1)
|
||||
SimpleBtnView(vm: btnVM, id: addressBtnID)
|
||||
.padding(EdgeInsets(top: 4, leading: 20, bottom: 4, trailing: 20))
|
||||
|
||||
}
|
||||
.padding()
|
||||
|
||||
// address
|
||||
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.sheet(isPresented: $showWebView) {
|
||||
WebView(isLoding: $showWebView)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
|
||||
}
|
||||
.onAppear {
|
||||
|
@ -49,6 +158,12 @@ struct RegisterView: View {
|
|||
topVM.setLeftBtn(Image(.Icon.left), size: CGPoint(x: 40, y: 40), action: leftAct)
|
||||
topVM.setRightBtn(size: CGPoint(x: 40, y: 40), action: rightAct)
|
||||
|
||||
btnVM.setSize(for: addressBtnID, newWidth: 80, newHeight: 24)
|
||||
btnVM.setText(for: addressBtnID, newText: "주소 입력", newFont: .nps(size: 16))
|
||||
btnVM.setAction(for: addressBtnID) {
|
||||
// self.appVM.isLoading.toggle()
|
||||
self.showWebView.toggle()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,11 @@ import SwiftUI
|
|||
|
||||
struct SelectAcademyView: View {
|
||||
@EnvironmentObject var appVM: AppViewModel
|
||||
@StateObject var saVM = SelectAcademyViewModel()
|
||||
@StateObject var saVM: SelectAcademyViewModel
|
||||
|
||||
init(_ appVM: AppViewModel) {
|
||||
_saVM = StateObject(wrappedValue: SelectAcademyViewModel(appVM))
|
||||
}
|
||||
|
||||
@State private var scrollOffset: CGPoint = .zero
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import Combine
|
|||
|
||||
struct MainView: View {
|
||||
@EnvironmentObject var appVM: AppViewModel
|
||||
@EnvironmentObject var alertController: AlertController
|
||||
@State var cancellables: Set<AnyCancellable> = []
|
||||
// @Binding var naviState : NaviState
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// 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<String?, Never>(nil)
|
||||
|
||||
|
||||
}
|
|
@ -9,6 +9,8 @@ import SwiftUI
|
|||
import Combine
|
||||
|
||||
class AppViewModel: ObservableObject {
|
||||
// public static let shared = AppViewModel()
|
||||
|
||||
@Published var isLoading: Bool = false
|
||||
@Published var showAlert: Bool = false
|
||||
@Published var menuName: MenuName = .Home
|
||||
|
@ -18,5 +20,10 @@ class AppViewModel: ObservableObject {
|
|||
|
||||
/// 항상 최신값을 가지고 있다가 구독자 추가 되면 그 즉시 값을 전달하고 이후 업데이트 되는 값을 계속 보내주는 역할을 함
|
||||
let alertAction = CurrentValueSubject<String?, Never>(nil)
|
||||
var apiManager: APIManager = APIManager()
|
||||
|
||||
// private init() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
}
|
||||
|
|
|
@ -6,9 +6,17 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
final class ChatVM: ObservableObject {
|
||||
@Published var vm: ChatViewModel?
|
||||
}
|
||||
|
||||
class ChatViewModel: ObservableObject {
|
||||
private let appVM: AppViewModel
|
||||
|
||||
@Published var messages: [ChatMesage] = []
|
||||
init(_ appVM: AppViewModel) {
|
||||
self.appVM = appVM
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
|
||||
class IntroViewModel: ObservableObject {
|
||||
var appVM : AppViewModel
|
||||
private let 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) {
|
||||
init(_ appVM: AppViewModel) {
|
||||
self.appVM = appVM
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ class IntroViewModel: ObservableObject {
|
|||
decoding: APIResponse<Header>.self)
|
||||
|
||||
|
||||
APIManager.shared.loadAPIData(request)
|
||||
appVM.apiManager.loadAPIData(request)
|
||||
.sink { completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
|
@ -133,7 +133,7 @@ class IntroViewModel: ObservableObject {
|
|||
parameters: ["type":"I"],
|
||||
decoding: APIResponse<VersionData>.self)
|
||||
|
||||
APIManager.shared.loadAPIData(request)
|
||||
appVM.apiManager.loadAPIData(request)
|
||||
.sink { completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
|
||||
class LoginViewModel: ObservableObject {
|
||||
let appVM: AppViewModel
|
||||
private let appVM: AppViewModel
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
// @Published var toggleLoading: Bool = false
|
||||
|
@ -22,7 +22,8 @@ class LoginViewModel: ObservableObject {
|
|||
|
||||
var bidArray: [String] = []
|
||||
|
||||
init(appVM: AppViewModel) {
|
||||
|
||||
init(_ appVM: AppViewModel) {
|
||||
self.appVM = appVM
|
||||
}
|
||||
|
||||
|
@ -30,7 +31,7 @@ class LoginViewModel: ObservableObject {
|
|||
appVM.isLoading = true
|
||||
LoginController().login(type)
|
||||
.flatMap{ snsId in
|
||||
APIManager.shared.loadAPIData(APIRequest(path: "/api/v1/in/user/login",
|
||||
self.appVM.apiManager.loadAPIData(APIRequest(path: "/api/v1/in/user/login",
|
||||
headers: [API_HEADER : self.headerValue],
|
||||
parameters: [
|
||||
"acctype": "\(type == .Apple ? "ST00": "ST01")",
|
||||
|
|
31
AcaMate/3. ViewModel/RegisterViewModel.swift
Normal file
31
AcaMate/3. ViewModel/RegisterViewModel.swift
Normal file
|
@ -0,0 +1,31 @@
|
|||
//
|
||||
// RegisterViewModel.swift
|
||||
// AcaMate
|
||||
//
|
||||
// Created by TAnine on 3/24/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
class RegisterViewModel: ObservableObject {
|
||||
private let appVM: AppViewModel
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
init(_ appVM: AppViewModel) {
|
||||
self.appVM = appVM
|
||||
}
|
||||
|
||||
@State var selectDate: Date = {
|
||||
let calendar = Calendar.current
|
||||
return calendar.date(byAdding: .year, value: -12, to: Date()) ?? Date()
|
||||
}()
|
||||
|
||||
@State var nameText: String = ""
|
||||
@State var emailFrontText: String = ""
|
||||
@State var emailTailText: String = ""
|
||||
@State var phoneArray: [Int] = []
|
||||
@State var addressText: String = ""
|
||||
|
||||
|
||||
}
|
|
@ -9,8 +9,13 @@ import SwiftUI
|
|||
import Combine
|
||||
|
||||
class SelectAcademyViewModel: ObservableObject {
|
||||
private var appVM: AppViewModel
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
init(_ appVM: AppViewModel) {
|
||||
self.appVM = appVM
|
||||
}
|
||||
|
||||
@Published var academyCode: String = ""
|
||||
@Published var academyList: [AcademyName] = []
|
||||
@Published var selectNum: Int = -1
|
||||
|
@ -23,7 +28,7 @@ class SelectAcademyViewModel: ObservableObject {
|
|||
parameters: ["token": token, "refresh": refresh],
|
||||
decoding: APIResponse<[AcademyName]>.self)
|
||||
|
||||
APIManager.shared.loadAPIData(request)
|
||||
appVM.apiManager.loadAPIData(request)
|
||||
.sink { completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
|
|
|
@ -8,18 +8,18 @@
|
|||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
import Alamofire
|
||||
|
||||
public class APIManager {
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
public static let shared = APIManager()
|
||||
// public static let shared = APIManager()
|
||||
|
||||
@UserDefault(key: "refresh", defaultValue: "refreshToken") var refresh
|
||||
@UserDefault(key: "token", defaultValue: "accToken") var accToken
|
||||
|
||||
private init(cancellables: Set<AnyCancellable> = Set<AnyCancellable>()) {
|
||||
self.cancellables = cancellables
|
||||
}
|
||||
// private init(cancellables: Set<AnyCancellable> = Set<AnyCancellable>()) {
|
||||
// self.cancellables = cancellables
|
||||
// }
|
||||
|
||||
public func loadAPIData<T: APIResponseProtocol>(_ request: APIRequest<T>) -> Future<T, Error> {
|
||||
let encoding: ParameterEncoding = (request.method == .get) ? URLEncoding.default : JSONEncoding.default
|
||||
|
@ -58,7 +58,7 @@ public class APIManager {
|
|||
parameters: ["refresh": refresh],
|
||||
decoding: APIResponse<Access>.self)
|
||||
|
||||
APIManager.shared.loadAPIData(request)
|
||||
APIManager().loadAPIData(request)
|
||||
.sink { completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
|
@ -105,7 +105,7 @@ public class APIManager {
|
|||
self.accToken = (response as! Access).access
|
||||
var updateRequest = request
|
||||
updateRequest.parameters["token"] = self.accToken
|
||||
return APIManager.shared.loadAPIData(updateRequest)
|
||||
return APIManager().loadAPIData(updateRequest)
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
|
|
@ -29,7 +29,7 @@ struct AcaMateApp: App {
|
|||
_ = AuthController.handleOpenUrl(url: url)
|
||||
}
|
||||
}
|
||||
.environmentObject(self.appVM)
|
||||
.environmentObject(appVM)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user