Skip to content

Commit

Permalink
fix: 투표 진행 화면에서 투표 진행 횟수 이슈를 수정해요 (#150)
Browse files Browse the repository at this point in the history
* fix: UserDefaultsManager Codable Type 저장하도록 구조 정리
- UserDefaultsWrapper VoteOption Case 추가
- SignUpIntroduceViewReactor backgroundColor 수정
- Tuist Storage Module VoteDomain 의존성 추가
- VotePresentationAssembly VoteProcessViewController injection주입 코드 수정
- VoteProcessViewReactor 비즈니스 로직 코드 리펙토링

* fix: VoteProcessViewController TableViewSelected 클릭시 화면전환 로직 이슈 수정
- VoteProcessViewReactor voteCount State 값 추가
- VoteBeginViewController 추가
- VoteBeginViewController UI Cofigure

* fix: 투표 조회 API UseCase, Repository Common 모듈로 폴더 변경
- VoteProcessViewReactor 비즈니스 로직 리펙토링
- VoteMainViewReactor 투표 조회 API 로직 추가
- VoteHomeViewController 투표 화면 및 친구 초대 화면 전환 로직 추가
- GlobalState VoteResponseEntity Parameter 추가
- VoteEndpoint 투표 조회 Path 제거
- CommonEndPoint 투표 조회 Path 추가

* feat: NotificationViewReactor fetchVoteOptionUseCase 의존성 주입 코드 추가
- NotificationPresentationAssembly NotificationViewReactor FetchVoteOptionUseCase 추가

* fix: 만료된 토큰으로 API 요청시 AccessToken 재발급 API 로직 구현
- WSNetworkMonitor Response Body 값 출력하도록 리펙토링
- 로그인시 AccessToken, RefreshToken 값 받도록 Entity 추가

* fix: NotificationViewReactor 투표지 조회 API 추가
- NotificationEndPoint updateNotification HTTP Method patch로 수정
- SceneDelegate 투표지 조회에 따라 화면 전환 로직 분기 처리
- WSNetworkService timeout Property 추가

* feat: VoteBeginViewController Profile 조회 API 추가
- Profile조회 API Common Modular 추가
- UserDefaultsManger grade, classNumber 제거
- ProfileRepositoryProtocol fetchUserProfileItems Method 제거
- ProfileDomain UserProfileEntity, UseCase 제거

* fix: Tuist CFBundleDisplayName Wespot으로 수정
- CFBundleShortVersionString 1.2.0으로 수정
  • Loading branch information
Do-hyun-Kim authored Oct 16, 2024
1 parent 9d8caf9 commit 115d462
Show file tree
Hide file tree
Showing 50 changed files with 665 additions and 413 deletions.
17 changes: 13 additions & 4 deletions 24th-App-Team-1-iOS/App/Sources/Applications/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Storage
import DesignSystem

import LoginFeature
import CommonDomain
import LoginDomain
import LoginService
import VoteFeature
Expand Down Expand Up @@ -73,8 +74,10 @@ public class SceneDelegate: UIResponder, UISceneDelegate {
window = UIWindow(windowScene: scene)

let accessToken = KeychainManager.shared.get(type: .accessToken)
let refreshToken = KeychainManager.shared.get(type: .refreshToken)

if accessToken == nil { // accessToken 값이 없으면 (회원가입 안됨)

if accessToken == nil || refreshToken == nil { // accessToken 값이 없으면 (회원가입 안됨)
let signInViewController = DependencyContainer.shared.injector.resolve(SignInViewController.self)
window?.rootViewController = UINavigationController(rootViewController: signInViewController)

Expand Down Expand Up @@ -132,9 +135,15 @@ extension SceneDelegate {
topViewController.navigationController?.pushViewController(notificationViewController, animated: true)
}

NotificationCenter.default.addObserver(forName: .showVoteProccessController, object: nil, queue: .main) { _ in
let voteProcessViewController = DependencyContainer.shared.injector.resolve(VoteProcessViewController.self)
topViewController.navigationController?.pushViewController(voteProcessViewController, animated: true)
NotificationCenter.default.addObserver(forName: .showVoteProccessController, object: nil, queue: .main) { notification in
let voteOption = notification.userInfo?["voteOption"] as? VoteResponseEntity
if !(voteOption?.response.isEmpty ?? true) {
let voteProcessViewController = DependencyContainer.shared.injector.resolve(VoteProcessViewController.self, argument: voteOption)
topViewController.navigationController?.pushViewController(voteProcessViewController, animated: true)
} else {
let voteBeginViewController = DependencyContainer.shared.injector.resolve(VoteBeginViewController.self)
topViewController.navigationController?.pushViewController(voteBeginViewController, animated: true)
}
}

NotificationCenter.default.addObserver(forName: .showVoteInventoryViewController, object: nil, queue: .main) { _ in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ struct DomainAssembly: Assembly {
}

container.register(FetchVoteOptionsUseCaseProtocol.self) { resolver in
let repository = resolver.resolve(VoteRepositoryProtocol.self)!
return FetchVoteOptionsUseCase(voteRepository: repository)
let repository = resolver.resolve(CommonRepositoryProtocol.self)!
return FetchVoteOptionsUseCase(commonRepository: repository)
}

container.register(CreateVoteUseCaseProtocol.self) { resolver in
Expand Down Expand Up @@ -116,8 +116,8 @@ struct DomainAssembly: Assembly {

// Profile
container.register(FetchUserProfileUseCaseProtocol.self) { resolver in
let repository = resolver.resolve(ProfileRepositoryProtocol.self)!
return FetchUserProfileUseCase(profileRepository: repository)
let repository = resolver.resolve(CommonRepositoryProtocol.self)!
return FetchUserProfileUseCase(commonRepository: repository)
}

container.register(UpdateUserProfileUseCaseProtocol.self) { resolver in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation
import AllFeature
import AllDomain
import CommonDomain

import Swinject

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Foundation
import NotificationFeature
import CommonDomain
import NotificationDomain

import Swinject
Expand All @@ -18,9 +19,11 @@ struct NotificationPresentationAssembly: Assembly {
container.register(NotificationViewReactor.self) { resolver in
let fetchUserNotificationItemUseCase = resolver.resolve(FetchUserNotificationItemUseCaseProtocol.self)!
let updateUserNotificationItemUseCase = resolver.resolve(UpdateUserNotificationItemUseCaseProtocol.self)!
let fetchVoteOptionUseCase = resolver.resolve(FetchVoteOptionsUseCaseProtocol.self)!
return NotificationViewReactor(
fetchUserNotificationItemsUseCase: fetchUserNotificationItemUseCase,
updateUserNotifcationItemUseCase: updateUserNotificationItemUseCase
updateUserNotifcationItemUseCase: updateUserNotificationItemUseCase,
fetchVoteOptionUseCase: fetchVoteOptionUseCase
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation
import VoteFeature
import VoteDomain
import CommonDomain

import Swinject

Expand Down Expand Up @@ -42,7 +43,8 @@ struct VoteMainPresentationAssembly: Assembly {
struct VoteHomePresentationAssembly: Assembly {
func assemble(container: Container) {
container.register(VoteHomeViewReactor.self) { resolver in
return VoteHomeViewReactor()
let fetchVoteOptionsUseCase = resolver.resolve(FetchVoteOptionsUseCaseProtocol.self)!
return VoteHomeViewReactor(fetchVoteOptionUseCase: fetchVoteOptionsUseCase)
}

container.register(VoteHomeViewController.self) { resovler in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,14 @@ import Swinject

struct VotePresentationAssembly: Assembly {
func assemble(container: Container) {
container.register(VoteProcessViewReactor.self) { (resolver, voteResponseEntity: VoteResponseEntity?, voteOptionStub: [CreateVoteItemReqeuest], processCount: Int) in
container.register(VoteProcessViewReactor.self) { (resolver, voteResponseEntity: VoteResponseEntity?) in
let createVoteUseCase = resolver.resolve(CreateVoteUseCaseProtocol.self)!
let createUserReportUseCase = resolver.resolve(CreateReportUserUseCaseProtocol.self)!
let fetchVoteOptionsUseCase = resolver.resolve(FetchVoteOptionsUseCaseProtocol.self)!
return VoteProcessViewReactor(
createVoteUseCase: createVoteUseCase,
createUserReportUseCase: createUserReportUseCase,
fetchVoteOptionsUseCase: fetchVoteOptionsUseCase,
voteResponseEntity: voteResponseEntity,
voteOptionStub: voteOptionStub,
processCount: processCount
voteResponseEntity: voteResponseEntity
)
}

Expand All @@ -36,13 +33,12 @@ struct VotePresentationAssembly: Assembly {

return VoteProcessViewReactor(
createVoteUseCase: createVoteUseCase,
createUserReportUseCase: createUserReportUseCase,
fetchVoteOptionsUseCase: fetchVoteOptionsUseCase
createUserReportUseCase: createUserReportUseCase
)
}

container.register(VoteProcessViewController.self) { (resolver, voteResponseEntity: VoteResponseEntity?, voteOptionStub: [CreateVoteItemReqeuest], processCount: Int) in
let reactor = resolver.resolve(VoteProcessViewReactor.self, arguments: voteResponseEntity, voteOptionStub, processCount)!
container.register(VoteProcessViewController.self) { (resolver, voteResponseEntity: VoteResponseEntity?) in
let reactor = resolver.resolve(VoteProcessViewReactor.self, argument: voteResponseEntity)!

return VoteProcessViewController(reactor: reactor)
}
Expand All @@ -52,5 +48,16 @@ struct VotePresentationAssembly: Assembly {

return VoteProcessViewController(reactor: reactor)
}

container.register(VoteBeginViewReactor.self) { resolver in
let fetchUserProfileUseCase = resolver.resolve(FetchUserProfileUseCaseProtocol.self)!
return VoteBeginViewReactor(fetchUserProfileUseCase: fetchUserProfileUseCase)
}

container.register(VoteBeginViewController.self) { resolver in
let reactor = resolver.resolve(VoteBeginViewReactor.self)!

return VoteBeginViewController(reactor: reactor)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public final class WSNetworkMonitor: EventMonitor {
}


public func request(_ request: DataRequest, didParseResponse response: DataResponse<Data?, AFError>) {
public func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value, AFError>) {
WSLogger.debug(category: Network.default, message: "✅Response WSNetwork LOG✅")
WSLogger.debug(category: Network.default, message: "URL : \((request.request?.url?.absoluteString ?? ""))")
WSLogger.debug(category: Network.default, message: "Results : \((response.result))")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum CommonEndPoint: WSNetworkEndPoint {
return accessToken
}

case fetchUserProfile
// 비속어 검색 API
case createProfanityCheck(Encodable)
// 프로필 캐릭터 정보 API
Expand All @@ -28,9 +29,13 @@ public enum CommonEndPoint: WSNetworkEndPoint {
case createUserReport(Encodable)
/// 사용자 프로필 수정 API
case updateUserProfile(Encodable)
/// 질문지 조회 API
case fetchVoteOptions

public var path: String {
switch self {
case .fetchUserProfile:
return "/users/me"
case .createProfanityCheck:
return "/check-profanity"
case .fetchCharacters:
Expand All @@ -41,11 +46,15 @@ public enum CommonEndPoint: WSNetworkEndPoint {
return "/reports"
case .updateUserProfile:
return "/users/me"
case .fetchVoteOptions:
return "votes/options"
}
}

public var method: HTTPMethod {
switch self {
case .fetchUserProfile:
return .get
case .createProfanityCheck:
return .post
case .fetchCharacters:
Expand All @@ -56,6 +65,8 @@ public enum CommonEndPoint: WSNetworkEndPoint {
return .post
case .updateUserProfile:
return .put
case .fetchVoteOptions:
return .get
}
}

Expand All @@ -71,6 +82,8 @@ public enum CommonEndPoint: WSNetworkEndPoint {
return .requestBody(body)
case let .updateUserProfile(body):
return .requestBody(body)
default:
return .none
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public enum NotificationEndPoint: WSNetworkEndPoint {
case .fetchNotificationItems:
return .get
case .updateNotification:
return .put
return .patch
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ public enum VoteEndPoint: WSNetworkEndPoint {

/// 반 친구 조회 API
case fetchClassMates
/// 질문지 조회 API
case fetchVoteOptions
/// 투표 하기 API
case addVotes(Encodable)
/// 투표 결과 전체 조회하기
Expand All @@ -40,8 +38,6 @@ public enum VoteEndPoint: WSNetworkEndPoint {
switch self {
case .fetchClassMates:
return "/users/classmates"
case .fetchVoteOptions:
return "/votes/options"
case .addVotes:
return "/votes"
case .fetchResultVotes:
Expand All @@ -61,8 +57,6 @@ public enum VoteEndPoint: WSNetworkEndPoint {
switch self {
case .fetchClassMates:
return .get
case .fetchVoteOptions:
return .get
case .addVotes:
return .post
case .fetchResultVotes:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import RxSwift
import RxCocoa

public final class WSNetworkInterceptor: RequestInterceptor {

private var retryLimit = 2
private let disposeBag = DisposeBag()

public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, any Error>) -> Void) {
public func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
var urlRequest = urlRequest

guard let accessToken = KeychainManager.shared.get(type: .accessToken) else {
Expand All @@ -33,35 +33,34 @@ public final class WSNetworkInterceptor: RequestInterceptor {

public func retry(_ request: Request, for session: Session, dueTo error: any Error, completion: @escaping (RetryResult) -> Void) {

let refreshToken = KeychainManager.shared.get(type: .refreshToken)
guard let response = request.task?.response as? HTTPURLResponse else {
completion(.doNotRetryWithError(error))
return
}

guard let statusCode = request.response?.statusCode,
request.retryCount < retryLimit else { return completion(.doNotRetry) }

if request.retryCount < retryLimit {
if statusCode == 401 {
guard let refreshToken = KeychainManager.shared.get(type: .refreshToken) else {
return completion(.doNotRetryWithError(WSNetworkError.default(message: "리프레쉬 토큰을 찾을 수 없습니다.")))
}

let body = ReissueToken(token: refreshToken)
let endPoint = ReissueEndPoint.createReissueToken(body: body)
WSNetworkService().request(endPoint: endPoint)
.asObservable()
.decodeMap(AccessToken.self)
.logErrorIfDetected(category: Network.error)
.subscribe { token in
KeychainManager.shared.set(value: token.accessToken, type: .accessToken)
KeychainManager.shared.set(value: token.refreshToken, type: .refreshToken)
} onError: { error in
completion(.doNotRetryWithError(error))
}
.disposed(by: disposeBag)




}
guard response.statusCode == 401 else {
completion(.doNotRetry)
return
}

guard let refreshToken = KeychainManager.shared.get(type: .refreshToken) else {
return completion(.doNotRetryWithError(WSNetworkError.default(message: "리프레쉬 토큰을 찾을 수 없습니다.")))
}

let body = ReissueToken(token: refreshToken)
let endPoint = ReissueEndPoint.createReissueToken(body: body)
WSNetworkService().request(endPoint: endPoint)
.asObservable()
.decodeMap(AccessToken.self)
.logErrorIfDetected(category: Network.error)
.subscribe { token in
KeychainManager.shared.set(value: token.accessToken, type: .accessToken)
KeychainManager.shared.set(value: token.refreshToken, type: .refreshToken)
} onError: { error in
completion(.doNotRetryWithError(error))
}
.disposed(by: disposeBag)

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import Foundation

import Alamofire
import RxSwift
import CommonDomain

public final class WSNetworkService: WSNetworkServiceProtocol {

Expand All @@ -18,7 +17,7 @@ public final class WSNetworkService: WSNetworkServiceProtocol {
let networkMonitor: WSNetworkMonitor = WSNetworkMonitor()
let networkConfigure: URLSessionConfiguration = URLSessionConfiguration.af.default
let interceptor = WSNetworkInterceptor()
networkConfigure.timeoutIntervalForRequest = 60
let networkSession: Session = Session(
configuration: networkConfigure,
interceptor: interceptor,
Expand Down
3 changes: 2 additions & 1 deletion 24th-App-Team-1-iOS/Core/Storage/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ let project = Project
targets: [
.core(module: .Storage, dependencies: [
.shared(module: .ThirdPartyLib),
.domain(module: .LoginDomain)
.domain(module: .LoginDomain),
.domain(module: .VoteDomain)
])
]
)
Loading

0 comments on commit 115d462

Please sign in to comment.