-
Notifications
You must be signed in to change notification settings - Fork 0
[TDH-31] 로그인 api 및 토큰 저장 처리부 구현 #12
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
base: dev
Are you sure you want to change the base?
Conversation
| } | ||
|
|
||
| struct SsoResponse: Codable { | ||
| let userId: Int64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 특별한 경우가 아니라면 정수 자료형은
Int를 사용하는게 좋습니다.Int는 시스템 아키텍처 종류에 따라Int64,Int32등으로 사용됩니다. - Swift는 type safe한 언어라서, Int64는 Int와 충돌을 일으켜 불필요한 conversion이 필요하게 되는 단점도 있습니다.
|
|
||
| extension LoginApi { | ||
| func loginWithSso(platformType: PlatformType, userAgent: String, accessToken: String, completion: @escaping (SsoResponse?, Error?) -> Void) { | ||
| loginSession.request(Urls.compose(path: Paths.requestSso), method: .post, parameters: ["platformType": platformType, "userAgent": userAgent, "accessToken": accessToken]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
Method 호출부 코드가 너무 길어지면 parameter를 기준으로 적절하게 개행하시면 가독성이 더 높아질 것입니다
| switch response.result { | ||
| case .success(let result): | ||
| completion(result, nil) | ||
| case .failure(let error): | ||
| completion(nil, error) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
completion closure의 parameter type을 Result<SsoResponse, Error>으로 사용하면 코드가 더 깔끔해 질 것 같습니다
|
|
||
|
|
||
| final class TokenManager { | ||
| public static let shared = TokenManager() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
여기서 public이 꼭 필요한가요?
| if let tokenData = UserDefaults.standard.data(forKey: key) { | ||
| let token = try? JSONDecoder().decode(SsoResponse.self, from: tokenData) | ||
| self.token = token | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
guard문을 사용하면 depth가 깊어지지 않고 깔끔하게 코드를 작성할 수 있습니다.
init() {
guard let tokenData = UserDefaults.standard.data(forKey: key) else { return }
token = try? JSONDecoder().decode(SsoResponse.self, from: tokenData)
}| if let data = try? JSONEncoder().encode(token) { | ||
| UserDefaults.standard.set(data, forKey: key) | ||
| UserDefaults.standard.synchronize() | ||
|
|
||
| self.token = token | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
여기도 guard문을 사용하면 더 간단하게 작성할 수 있어 보입니다
|
|
||
| final class TokenManager { | ||
| public static let shared = TokenManager() | ||
| var token: SsoResponse? = nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
아래에 구현 방식들을 보니, token은 computed property로 만들어 사용하는게 더 편해 보이네요
final class TokenManager {
var token: SsoResponse? {
get {
guard let tokenData = UserDefaults.standard.data(forKey: key) else { return nil }
return try? JSONDecoder().decode(SsoResponse.self, from: tokenData)
}
set {
guard let data = try? JSONEncoder().encode(token) else { return }
UserDefaults.standard.set(data, forKey: key)
}
}
}이런 형태의 computed property는 property wrapper를 사용하면 더 간단하게 사용할 수도 있습니다.
final class TokenManager {
@SSOResponse
var token: SsoResponse?
}| } | ||
|
|
||
| extension LoginStore { | ||
| func isLogin() -> Bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
이렇게 parameter가 없고 어떤 값을 반환하기 위해 명사형으로 이름을 작성하게 되는 method들은 readonly property로 작성하면 호출부에서 더 자연스럽게 사용할 수 있습니다.
// 1.
if isLogin() { ... }
// 2.
if isLogin { ... }| return false | ||
| } | ||
|
|
||
| func login(email: String, password: String, completion: @escaping (Result<Bool, Error>) -> Void) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
false를 반환해야 하는 상황에서도 Error를 throw하면 어떨까요?
.success(false)가 반환되는 상황에서는 로그인 할 수 없을텐데요. '성공'한 case로 false라는 값을 반환하는 것 보다 error를 반환하는게 더 자연스럽지 않을까요?
| HStack(spacing: 16) { | ||
| LoginButton(type: .kakao) { | ||
| loginStore.kakaoLogin() | ||
| loginStore.kakaoLogin { result in switch result { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@songmilee
여기 개행이 이상합니다
요약
리뷰 요청 사항