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

SOPT 세미나 4차 과제 #8

Open
wants to merge 21 commits into
base: develop
Choose a base branch
from
Open

SOPT 세미나 4차 과제 #8

wants to merge 21 commits into from

Conversation

LaonCoder
Copy link
Collaborator

@LaonCoder LaonCoder commented Nov 8, 2024

1️⃣ What is this PR?

2️⃣ Description

1) 4차 과제 진행

  • 앱스토어 )
    • 앱스토어 하단 탭바 구현
    • 서버 페이지 내 로그인, 유저 등록, 유저 정보 변경 내 취미 조회, 다른 사용자 취미 조회 기능 구현

3️⃣ To Reviewers

1. 토큰 활용

  • Interceptor를 통해 header에 토큰 정보를 담아 전송하도록 구현했습니다.
    (token refresh api가 따로 존재하지는 않아서, 토큰 재발급 기능은 구현하지 않았습니다.)
    let authenticator = UserAuthenticator()
    let credential = UserAuthCredential(accessToken: TokenManager.shared.getAccessToken() ?? "",
                                        expiredAt: Date(timeIntervalSinceNow: 60 * 120))
    let interceptor = AuthenticationInterceptor(authenticator: authenticator,
                                                credential: credential)
    
  • 토큰은 KeyChain을 통해 관리합니다.
    • UserDefaults는 비교적 보안에 취약하기 때문에, 암호화된 데이터베이스인 KeyChain을 사용했습니다.
      final class TokenManager {
          // ...
      
          // 토큰 저장
          func setAccessToken(_ token: String) {
              guard let data = token.data(using: .utf8) else { return }
              
              let query = [
                  kSecClass as String: kSecClassGenericPassword,
                  kSecAttrAccount as String: Const.accessTokenKey,
                  kSecValueData as String: data
              ] as CFDictionary
              
              SecItemDelete(query)  // Keychain은 Key 중복이 발생하면, 저장할 수 없기 때문에 먼저 Delete
      
              let status = SecItemAdd(query, nil)
              assert(status == noErr, "Access Token 저장 실패")
          }
      }
      
  • KeyChain의 경우, 앱 삭제 이후에도 데이터가 남아있기 때문에, 재설치 시 KeyChain에 저장된 토큰 값을 제거해주어야 합니다.
    • 재설치 시 기존 토큰 값을 제거하지 않으면, 앱 삭제 후 재설치 했을 때 자동 로그인이 되는 상황이 발생할 수 있습니다.
      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
          
          // 앱 삭제 후 재설치하는 경우, 토큰 초기화 (KeyChain에 저장된 토큰 제거)
          if TokenManager.shared.isNewUser {
              TokenManager.shared.clearTokens()
              TokenManager.shared.isNewUser = false
          }
          
          return true
      }
      

2. 기타

  • 유저 정보 조회 api가 별도로 존재하지 않아서, 유저 정보 변경, 로그인 시 delegate를 통해 홈 뷰컨에도 데이터가 전달되도록 구현했습니다.
    • 혹시 더 좋은 방법 있을까요? 위 방법을 사용하지 않으면 사용자 정보를 로컬에서 관리해야 할 것 같더라고요..
    protocol UserInfoEditControllerDelegate: AnyObject {
        func didEditUserInfo(newHobby: String)
    }
    

4️⃣ ScreenShots

week4_assignment.mp4

- Info.plist 세팅 및 xcconfig 파일 추가
- NetworkTestController 추가
- ServerHomeController 내 유저 등록 기능까지 구현
- NetworkError, UserService 등 네트워킹 관련 클래스 추가
- ProfileCell, PlainCell 추가
- ServerHomeController 초기 구현
- 로그인 실패 시 로그인 실패 팝업 노출되도록 구현
- 로그인 페이지 UI 개선
- plainCell의 경우, PlainCellTag로 구분할 수 있도록 수정
- plainCell, plainCellWithRightArrow 통합
- profileCell, ProfilePlaceholderCell 구분
- logout 섹션을 별도로 구현하여, 맨 아래에 로그아웃 셀 위치하도록 수정
- 회원가입 페이지 내부 UI 레이아웃 수정
- MyHobbyViewController 제거 후, ServerHomeController에서 사용자 취미 plain 셀로 노출하도록 변경
- PlainCell 내부 코드 수정
- showAlert extension 추가
- UserInfEditController 추가
- UserService 클래스 내 코드 정리
- DTO 파일 분리
- Foundation / Feature / Infrastructure로 폴더 구조 정리
- UserAuthenticator, UserAuthCredential, TokenManager 구현
- token 담아서 보내는 로직 interceptor에서 처리하도록 변경
- 모달 클릭 시 키보드 내려가도록 구현
@LaonCoder LaonCoder requested review from codeJiwon, sozohoy, Sangwook123 and sem-git and removed request for codeJiwon November 9, 2024 14:16
Comment on lines +148 to +149
case .failure:
let networkError = self.handleStatusCode(statusCode, data: Data())
Copy link

Choose a reason for hiding this comment

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

실패 시 Data() 라는 빈 데이터를 넘기는 방법을 사용하셨는데,
response.data를 옵셔널 바인딩하는 방법은 어떻게 생각하시는지 궁금합니다 ..!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

리팩토링 해보겠습니다!

Copy link

@sem-git sem-git left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants