Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔀 :: [#75] 로그인 버튼 API 연결 #88

Merged
merged 46 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
23a0e1f
:bug: :: [#75] LoginViewModel / pull용
uuuunseo Nov 17, 2023
56d9d24
:recycle: :: [#75] LoginView / Service import 지우기
uuuunseo Nov 17, 2023
25bb171
:recycle: :: [#75] LoginFeature / FakeAuthRepository 삭제
uuuunseo Nov 19, 2023
4266794
Merge branch 'master' of https://github.com/GSM-MSG/Bitgouel-iOS into…
uuuunseo Nov 19, 2023
6eae329
:heavy_minus_sign: :: [#75] Tuist / Remove Swinject
uuuunseo Nov 19, 2023
3ed2532
:heavy_plus_sign: :: [#75] Tuist / add Needle
uuuunseo Nov 19, 2023
33287e9
:heavy_plus_sign: :: [#75] ThirdPartyLib / swinject needle로 수정
uuuunseo Nov 20, 2023
e64e1db
:heavy_plus_sign: :: [#75] Tuist / add Needle
uuuunseo Nov 20, 2023
f5d5d80
:recycle: :: [#75] LoginFeature / Component 수정
uuuunseo Nov 20, 2023
f28f799
:bug: :: [#75] 충돌해결
uuuunseo Nov 20, 2023
ce1c3ba
:fire: :: [#75] RootView 삭제
uuuunseo Nov 20, 2023
b690c8d
:sparkles: :: [#75] LoginFeature / LoginFactory추가
uuuunseo Nov 20, 2023
d02fc09
:recycle: :: [#75] Auth / LoginUseCaseImpl 살리기
uuuunseo Nov 20, 2023
b1c7b22
:sparkles: :: [#75] LoginViewModel / loginFailed change emailHelpMessage
uuuunseo Nov 21, 2023
6c06727
:sparkles: :: [#75] DI / AppComponent+Auth 추가
uuuunseo Nov 22, 2023
9a28740
:recycle: :: [#75] SceneFlow / SceneFlow 수정
uuuunseo Nov 23, 2023
cbffd75
:recycle: :: [#75] DI / AppComponent 수정
uuuunseo Nov 23, 2023
40270b0
:recycle: :: [#75] RootFeature / RootFeature 수정
uuuunseo Nov 23, 2023
11cf7ee
:memo: :: [#75] NeedleRunScript 추가
uuuunseo Nov 23, 2023
53567d3
:sparkles: :: [#75] BaseFeature / AppState 추가
uuuunseo Nov 23, 2023
9071408
:fire: :: [#75] Extensions / eraseToAny 삭제
uuuunseo Nov 23, 2023
dc8332e
:fire: :: [#75] githooks / pre-commit 삭제
uuuunseo Nov 24, 2023
979b7c5
:sparkles: :: [#75] Extensions / eraseToAnyView 추가
uuuunseo Nov 24, 2023
069c10e
:recycle: :: [#75] Scripts / NeedleRunScript 수정
uuuunseo Nov 24, 2023
c476b43
:recycle: :: [#75] Tuist / Needle Script 적용
uuuunseo Nov 24, 2023
5b360a3
:recycle: :: [#75] RootView / AppState -> SceneState로 수정
uuuunseo Nov 24, 2023
291113e
:green_heart: :: [#75] 트러블 슈팅
uuuunseo Nov 24, 2023
6015160
:green_heart: :: [#75] 오류 해결
uuuunseo Nov 27, 2023
258643e
:recycle: :: [#75] Info.plist / 삭제된 UISceneDelegateClassName 되돌리기
uuuunseo Nov 27, 2023
97f55aa
:recycle: :: [#75] LoginViewModel / LoginFailed 변수명 isLoginFailed로 수정
uuuunseo Nov 27, 2023
de9570b
:fire: :: [#75] LoginViewModel / isLoginFailed 삭제
uuuunseo Nov 27, 2023
ab3dc2c
:recycle: :: [#75] AuthDataSource / DataSource InterFace 추가
uuuunseo Nov 27, 2023
0fb5c4c
:rewind: :: [#75] DI / AppComponent + Auth 되돌리기
uuuunseo Nov 28, 2023
d199f2a
:fire: :: [#75] BitgouelApp / Keychain 삭제
uuuunseo Nov 28, 2023
2fbd06e
:recycle: :: [#75] Application / trailing 공백 삭제
uuuunseo Nov 28, 2023
cc98091
:recycle: :: [#75] BaseFeature / View+eraseToAnyView 위치 수정
uuuunseo Nov 28, 2023
294df6a
:recycle: :: [#75] LoginView / 필요없는 Task 삭제
uuuunseo Nov 28, 2023
93b1593
Update App/Sources/Application/DI/Auth/AppComponent+Auth.swift
uuuunseo Nov 28, 2023
08c198d
:green_heart: :: [#75] 트러블 슈팅
uuuunseo Dec 1, 2023
31b94ed
Merge branch '75-connect_auth_api' of https://github.com/GSM-MSG/Bitg…
uuuunseo Dec 1, 2023
121e069
:rewind: :: [#75] Info.plist / UISceneDelegateClassName추가
uuuunseo Dec 2, 2023
bcbad7e
:bug: :: [#75] BaseURL 안 불러와지는 오류 해결
uuuunseo Dec 3, 2023
ac3f167
:recycle: :: [#75] AppComponent+Auth / 오타수정
uuuunseo Dec 3, 2023
4b73952
:recycle: :: [#75] Utils / View+eraseToAnyView Utils로 옮기기
uuuunseo Dec 3, 2023
cf13b32
:green_heart: :: [#75] 트러블 슈팅
uuuunseo Dec 3, 2023
225baa6
:recycle: :: [#75] Info.plist / Allow Arbitrary Loads 설정 수정
uuuunseo Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion App/Sources/Application/BitgouelApp.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import SwiftUI
import Service

@main
struct BitgouelApp: App {
init() {
registerProviderFactories()
}

var body: some Scene {
WindowGroup {
LoginView(viewModel: LoginViewModel())
AppComponent().makeRootView()
}
}
}
25 changes: 25 additions & 0 deletions App/Sources/Application/DI/AppComponent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import NeedleFoundation
import SwiftUI
import Service

public final class AppComponent: BootstrapComponent {
public func makeRootView() -> some View {
rootComponent.makeView()
}

var rootComponent: RootComponent {
RootComponent(parent: self)
}

public var keychain: Keychain {
shared {
KeychainImpl()
}
}
}

public extension AppComponent {
var loginFactory: any LoginFactory {
LoginComponent(parent: self)
}
}
61 changes: 61 additions & 0 deletions App/Sources/Application/DI/Auth/AppComponent+Auth.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import NeedleFoundation
import Service

public extension AppComponent {
var localAuthDataSource: any LocalAuthDataSource {
shared {
LocalAuthDataSourceImpl(keychain: keychain)
}
}

var remoteAuthDataSource: any RemoteAuthDataSource {
shared {
RemoteAuthDataSourceImpl(keychian: keychain)
}
}

var authRepository: any AuthRepository {
shared {
AuthRepositoryImpl(
remoteAuthDataSource: remoteAuthDataSource,
localAuthDataSource: localAuthDataSource
)
}
}

var loginUseCase: any LoginUseCase {
shared {
LoginUseCaseImpl(authRepository: authRepository)
}
}

var reissueTokenUseCase: any ReissueTokenUseCase {
shared {
ReissueTokenUseCaseImpl(authRepository: authRepository)
}
}

var logoutUseCase: any LogoutUseCase {
shared {
LogoutUseCaseImpl(authRepository: authRepository)
}
}

var withdrawUseCase: any WithdrawalUseCase {
shared {
WithdrawalUseCaseImpl(authRepository: authRepository)
}
}
uuuunseo marked this conversation as resolved.
Show resolved Hide resolved

var studentSignupUseCase: any StudentSignupUseCase {
shared {
StudentSignupUseCaseImpl(authRepository: authRepository)
}
}

var teacherSignupUseCase: any TeacherSignupUseCase {
shared {
TeacherSignupUseCaseImpl(authRepository: authRepository)
}
}
}
6 changes: 0 additions & 6 deletions App/Sources/Application/DI/RemoveMe1.swift

This file was deleted.

100 changes: 100 additions & 0 deletions App/Sources/Application/NeedleGenerated.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@


import NeedleFoundation
import Service
import SwiftUI

// swiftlint:disable unused_declaration
private let needleDependenciesHash : String? = nil

// MARK: - Traversal Helpers

private func parent1(_ component: NeedleFoundation.Scope) -> NeedleFoundation.Scope {
return component.parent
}

// MARK: - Providers

#if !NEEDLE_DYNAMIC

private class RootDependency3944cc797a4a88956fb5Provider: RootDependency {
var loginFactory: any LoginFactory {
return appComponent.loginFactory
}
private let appComponent: AppComponent
init(appComponent: AppComponent) {
self.appComponent = appComponent
}
}
/// ^->AppComponent->RootComponent
private func factory264bfc4d4cb6b0629b40f47b58f8f304c97af4d5(_ component: NeedleFoundation.Scope) -> AnyObject {
return RootDependency3944cc797a4a88956fb5Provider(appComponent: parent1(component) as! AppComponent)
}
private class LoginDependencyf4e78d0ad57be469bfd9Provider: LoginDependency {
var loginUseCase: any LoginUseCase {
return appComponent.loginUseCase
}
private let appComponent: AppComponent
init(appComponent: AppComponent) {
self.appComponent = appComponent
}
}
/// ^->AppComponent->LoginComponent
private func factoryd6018e98563de75a2ba4f47b58f8f304c97af4d5(_ component: NeedleFoundation.Scope) -> AnyObject {
return LoginDependencyf4e78d0ad57be469bfd9Provider(appComponent: parent1(component) as! AppComponent)
}

#else
extension RootComponent: Registration {
public func registerItems() {
keyPathToName[\RootDependency.loginFactory] = "loginFactory-any LoginFactory"
}
}
extension LoginComponent: Registration {
public func registerItems() {
keyPathToName[\LoginDependency.loginUseCase] = "loginUseCase-any LoginUseCase"
}
}
extension AppComponent: Registration {
public func registerItems() {

localTable["keychain-Keychain"] = { [unowned self] in self.keychain as Any }
localTable["localAuthDataSource-any LocalAuthDataSource"] = { [unowned self] in self.localAuthDataSource as Any }
localTable["remoteAuthDataSource-any RemoteAuthDataSource"] = { [unowned self] in self.remoteAuthDataSource as Any }
localTable["authRepository-any AuthRepository"] = { [unowned self] in self.authRepository as Any }
localTable["loginUseCase-any LoginUseCase"] = { [unowned self] in self.loginUseCase as Any }
localTable["reissueTokenUseCase-any ReissueTokenUseCase"] = { [unowned self] in self.reissueTokenUseCase as Any }
localTable["logoutUseCase-any LogoutUseCase"] = { [unowned self] in self.logoutUseCase as Any }
localTable["withdrawUseCase-any WithdrawalUseCase"] = { [unowned self] in self.withdrawUseCase as Any }
localTable["studentSignupUseCase-any StudentSignupUseCase"] = { [unowned self] in self.studentSignupUseCase as Any }
localTable["teacherSignupUseCase-any TeacherSignupUseCase"] = { [unowned self] in self.teacherSignupUseCase as Any }
localTable["loginFactory-any LoginFactory"] = { [unowned self] in self.loginFactory as Any }
}
}


#endif

private func factoryEmptyDependencyProvider(_ component: NeedleFoundation.Scope) -> AnyObject {
return EmptyDependencyProvider(component: component)
}

// MARK: - Registration
private func registerProviderFactory(_ componentPath: String, _ factory: @escaping (NeedleFoundation.Scope) -> AnyObject) {
__DependencyProviderRegistry.instance.registerDependencyProviderFactory(for: componentPath, factory)
}

#if !NEEDLE_DYNAMIC

@inline(never) private func register1() {
registerProviderFactory("^->AppComponent->RootComponent", factory264bfc4d4cb6b0629b40f47b58f8f304c97af4d5)
registerProviderFactory("^->AppComponent->LoginComponent", factoryd6018e98563de75a2ba4f47b58f8f304c97af4d5)
registerProviderFactory("^->AppComponent", factoryEmptyDependencyProvider)
}
#endif

public func registerProviderFactories() {
#if !NEEDLE_DYNAMIC
register1()
#endif
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 BaseFeature에 있는건 좀 어색한거같네요

Copy link
Contributor Author

@uuuunseo uuuunseo Dec 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RootFeature의 Extensions으로 빼봤는데 어떤가요...?!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feature에 있는거 자체가 좀 별로인거같아요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그럼 어디에 있는 게 좋을까요ㅠㅠ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Utils/Extensions/View/View+eraseToAnyView.swift
이런식으로 빼거나 더 레이어 높이려면
Shared/Utils/Extensions/View/View+eraseToAnyView.swift
로 하는게 괜찮을거같네요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정했어요!

cf13b32

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import SwiftUI

public extension View {
func eraseToAnyView() -> AnyView {
AnyView(self)
}
}
2 changes: 0 additions & 2 deletions App/Sources/Feature/BaseFeature/Flow/SceneFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@ import Foundation

public enum SceneFlow: String, RawRepresentable {
case login
case CommonSignup
case StudentSignup
}
9 changes: 9 additions & 0 deletions App/Sources/Feature/BaseFeature/Sources/SceneState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

public final class SceneState: ObservableObject {
@Published public var sceneFlow: SceneFlow

init(sceneFlow: SceneFlow) {
self.sceneFlow = sceneFlow
}
}
6 changes: 6 additions & 0 deletions App/Sources/Feature/LoginFeature/Interface/LoginFactory.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import SwiftUI

public protocol LoginFactory {
associatedtype SomeView: View
func makeView() -> SomeView
}
17 changes: 17 additions & 0 deletions App/Sources/Feature/LoginFeature/Sources/LoginComponent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import SwiftUI
import NeedleFoundation
import Service

public protocol LoginDependency: Dependency {
var loginUseCase: any LoginUseCase { get }
}

public final class LoginComponent: Component<LoginDependency>, LoginFactory {
public func makeView() -> some View {
LoginView(
viewModel: .init(
loginUseCase: dependency.loginUseCase
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@ struct LoginView: View {
case email
case password
}

@FocusState private var focusField: FocusField?
@StateObject var viewModel: LoginViewModel

init(
viewModel: LoginViewModel
) {
_viewModel = StateObject(wrappedValue: viewModel)
}

var body: some View {
VStack(spacing: 0) {
HStack {
Text("빛고을\n직업교육\n혁신지구")
.bitgouelFont(.title1)

Spacer()
}
.frame(height: 108)
.padding(.top, 53)
.padding(.leading, 28)

VStack {
BitgouelTextField(
"이메일",
Expand All @@ -38,7 +38,7 @@ struct LoginView: View {
}
.textContentType(.emailAddress)
.focused($focusField, equals: .email)

SecureBitgouelTextField(
"비밀번호",
text: $viewModel.password,
Expand All @@ -51,21 +51,24 @@ struct LoginView: View {
}
.padding(.top, 80)
.padding(.horizontal, 28)

Spacer()

VStack(spacing: 0) {
BitgouelButton(
text: "로그인"
text: "로그인",
action: {
viewModel.login()
}
)
.cornerRadius(8)
.disabled(viewModel.isFormEmpty)
.padding(.horizontal, 28)

Text("또는")
.bitgouelFont(.caption, color: .greyscale(.g7))
.padding(.top, 8)

baekteun marked this conversation as resolved.
Show resolved Hide resolved
Text("회원가입")
.bitgouelFont(.text3, color: .primary(.p5))
.padding(.top, 2)
Expand Down
Loading
Loading