Skip to content

Commit 43acf1d

Browse files
authored
feat - 데모로그인 추가 (#54)
* feat(Login): 테스터 로그인 체험하기 버튼 추가 * feat(1.0.22): 버전 업데이트
1 parent 40c7d6c commit 43acf1d

5 files changed

Lines changed: 110 additions & 4 deletions

File tree

KillingPart.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@
434434
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
435435
CODE_SIGN_ENTITLEMENTS = KillingPart/KillingPart.entitlements;
436436
CODE_SIGN_STYLE = Automatic;
437-
CURRENT_PROJECT_VERSION = 21;
437+
CURRENT_PROJECT_VERSION = 22;
438438
DEAD_CODE_STRIPPING = YES;
439439
DEVELOPMENT_TEAM = GQ89YG5G9R;
440440
ENABLE_APP_SANDBOX = YES;
@@ -459,7 +459,7 @@
459459
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
460460
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
461461
MACOSX_DEPLOYMENT_TARGET = 14.0;
462-
MARKETING_VERSION = 1.0.21;
462+
MARKETING_VERSION = 1.0.22;
463463
PRODUCT_BUNDLE_IDENTIFIER = com.killingpoint.killingpart;
464464
PRODUCT_NAME = "$(TARGET_NAME)";
465465
REGISTER_APP_GROUPS = YES;
@@ -479,7 +479,7 @@
479479
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
480480
CODE_SIGN_ENTITLEMENTS = KillingPart/KillingPart.entitlements;
481481
CODE_SIGN_STYLE = Automatic;
482-
CURRENT_PROJECT_VERSION = 21;
482+
CURRENT_PROJECT_VERSION = 22;
483483
DEAD_CODE_STRIPPING = YES;
484484
DEVELOPMENT_TEAM = GQ89YG5G9R;
485485
ENABLE_APP_SANDBOX = YES;
@@ -504,7 +504,7 @@
504504
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
505505
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
506506
MACOSX_DEPLOYMENT_TARGET = 14.0;
507-
MARKETING_VERSION = 1.0.21;
507+
MARKETING_VERSION = 1.0.22;
508508
PRODUCT_BUNDLE_IDENTIFIER = com.killingpoint.killingpart;
509509
PRODUCT_NAME = "$(TARGET_NAME)";
510510
REGISTER_APP_GROUPS = YES;

KillingPart/Models/AuthModel.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,13 @@ struct AuthLoginResponse: Decodable {
4141
let refreshToken: String
4242
let isNew: Bool
4343
}
44+
45+
extension AuthLoginResponse {
46+
func withIsNew(_ isNew: Bool) -> AuthLoginResponse {
47+
AuthLoginResponse(
48+
accessToken: accessToken,
49+
refreshToken: refreshToken,
50+
isNew: isNew
51+
)
52+
}
53+
}

KillingPart/Services/AuthService.swift

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ protocol AuthServicing {
99

1010
@MainActor
1111
func loginWithApple() async throws -> AppleAuthPayload
12+
13+
@MainActor
14+
func loginWithTester() async throws -> AuthLoginResponse
1215
}
1316

1417
struct AppleAuthPayload {
@@ -29,6 +32,7 @@ enum AuthServiceError: LocalizedError {
2932
case missingAppleAuthorizationCode
3033
case invalidAppleIdentityTokenEncoding
3134
case invalidAppleAuthorizationCodeEncoding
35+
case testLoginFailed(underlying: Error)
3236

3337
var errorDescription: String? {
3438
switch self {
@@ -50,6 +54,16 @@ enum AuthServiceError: LocalizedError {
5054
return "애플 authorization code를 가져오지 못했어요."
5155
case .invalidAppleIdentityTokenEncoding, .invalidAppleAuthorizationCodeEncoding:
5256
return "애플 로그인 인증값 인코딩에 실패했어요."
57+
case .testLoginFailed(let underlying):
58+
if
59+
let apiError = underlying as? APIClientError,
60+
case .serverError(_, let message) = apiError,
61+
let message,
62+
!message.isEmpty
63+
{
64+
return message
65+
}
66+
return "체험하기 로그인에 실패했어요. 다시 시도해 주세요."
5367
}
5468
}
5569
}
@@ -58,6 +72,17 @@ final class AuthService: NSObject, AuthServicing {
5872
private var appleLoginContinuation: CheckedContinuation<AppleAuthPayload, Error>?
5973
private var applePresentationAnchor: ASPresentationAnchor?
6074
private var appleAuthorizationController: ASAuthorizationController?
75+
private let apiClient: APIClienting
76+
private let tokenStore: TokenStoring
77+
78+
init(
79+
apiClient: APIClienting = APIClient.shared,
80+
tokenStore: TokenStoring = TokenStore.shared
81+
) {
82+
self.apiClient = apiClient
83+
self.tokenStore = tokenStore
84+
super.init()
85+
}
6186

6287
func loginWithKakao() async throws -> String {
6388
let appKey = (Bundle.main.object(forInfoDictionaryKey: "KAKAO_NATIVE_APP_KEY") as? String ?? "")
@@ -93,6 +118,29 @@ final class AuthService: NSObject, AuthServicing {
93118
}
94119
}
95120

121+
func loginWithTester() async throws -> AuthLoginResponse {
122+
do {
123+
let request = APIRequest(
124+
path: "/oauth2/test",
125+
method: .get,
126+
requiresAuthorization: false
127+
)
128+
let response = try await apiClient.request(
129+
request,
130+
responseType: AuthLoginResponse.self
131+
)
132+
let normalizedResponse = response.withIsNew(true)
133+
134+
tokenStore.save(
135+
accessToken: normalizedResponse.accessToken,
136+
refreshToken: normalizedResponse.refreshToken
137+
)
138+
return normalizedResponse
139+
} catch {
140+
throw AuthServiceError.testLoginFailed(underlying: error)
141+
}
142+
}
143+
96144
private func loginWithKakaoTalk() async throws -> String {
97145
try await withCheckedThrowingContinuation { continuation in
98146
UserApi.shared.loginWithKakaoTalk { oauthToken, error in

KillingPart/ViewModels/LoginViewModel.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ final class LoginViewModel: ObservableObject {
55
enum SocialLoginProvider {
66
case kakao
77
case apple
8+
case tester
89
}
910

1011
@Published var isLoading = false
@@ -94,6 +95,24 @@ final class LoginViewModel: ObservableObject {
9495
}
9596
}
9697

98+
func loginWithTester() {
99+
guard startSocialLogin(for: .tester) else { return }
100+
101+
Task {
102+
defer { finishSocialLogin() }
103+
104+
do {
105+
_ = try await authService.loginWithTester()
106+
isNewUser = true
107+
onLoginSuccess?(true)
108+
} catch let socialError as AuthServiceError {
109+
loginErrorMessage = socialError.errorDescription
110+
} catch {
111+
loginErrorMessage = "로그인 중 오류가 발생했어요. 다시 시도해 주세요."
112+
}
113+
}
114+
}
115+
97116
func resetState() {
98117
isLoading = false
99118
loginErrorMessage = nil

KillingPart/Views/Screens/Auth/LoginView.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,35 @@ struct LoginView: View {
5959
action: viewModel.loginWithApple
6060
)
6161
}
62+
63+
Button(action: viewModel.loginWithTester) {
64+
ZStack {
65+
Text("체험하기(Demo)")
66+
.font(AppFont.paperlogy5Medium(size: 14))
67+
.opacity(
68+
viewModel.isLoading
69+
&& viewModel.activeSocialLoginProvider == .tester ? 0 : 1
70+
)
71+
72+
if viewModel.isLoading
73+
&& viewModel.activeSocialLoginProvider == .tester {
74+
ProgressView()
75+
.tint(.white)
76+
}
77+
}
78+
.foregroundStyle(.white)
79+
.padding(.horizontal, AppSpacing.l)
80+
.padding(.vertical, AppSpacing.s)
81+
.background(Color.white.opacity(0.16))
82+
.clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
83+
.overlay {
84+
RoundedRectangle(cornerRadius: 14, style: .continuous)
85+
.stroke(Color.white.opacity(0.28), lineWidth: 1)
86+
}
87+
}
88+
.buttonStyle(.plain)
89+
.disabled(viewModel.isLoading)
90+
.accessibilityLabel("체험하기")
6291
}
6392
.padding(.horizontal, horizontalPadding)
6493
.padding(.bottom, bottomPadding)

0 commit comments

Comments
 (0)