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

[Feat] #197 - 토큰 재발급 정상 작동하도록 수정 / 플그 미등록 비활동 유저 자동로그인 처리 / 스플래시 이미지 변경 #200

Merged
merged 4 commits into from
Apr 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion SOPT-iOS/Projects/Core/Sources/Enum/ServiceType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public enum ServiceType {
case .attendance: return ""
case .member: return "https://playground.sopt.org/members"
case .notice: return ""
case .crew: return "https://playground.sopt.org/group"
case .crew: return "https://playground.sopt.org/group?utm_source=playground_group&utm_medium=app_button&utm_campaign=app"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ extension UserDefaultKeyList.Auth {
return UserType.visitor
}

guard appAccessToken != "" else {
return UserType.unregisteredInactive
}

return getUserActivation()
? UserType.active
: UserType.inactive
Expand Down
12 changes: 11 additions & 1 deletion SOPT-iOS/Projects/Data/Sources/Repository/MainRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,19 @@ public class MainRepository {
}

extension MainRepository: MainRepositoryInterface {
public func getUserMainInfo() -> AnyPublisher<Domain.UserMainInfoModel?, Error> {
public func getUserMainInfo() -> AnyPublisher<Domain.UserMainInfoModel?, Never> {
userService.getUserMainInfo()
.map { $0.toDomain() }
.catch({ error in
Copy link
Member

Choose a reason for hiding this comment

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

withError로 임시 처리를 했지만 결국 Error 타입을 제대로 정의해서 핸들링 하는 것이 맞다고 생각해요!
레포지토리에서 APIError 열거형을 사용하여 네트워크 에러가 발생한경우를 잡아내고 플그 미등록 유저인 경우도 이 열거형을 통해 구분하는 것이 맞을까요? 아니면 APIError가 아닌 새로운 열거형을 생성해서 에러 처리를 하는 것이 좋을까요?

var model: UserMainInfoModel?
if let error = error as? APIError,
case .tokenReissuanceFailed = error {
model = UserMainInfoModel(withError: false)
} else {
model = UserMainInfoModel(withError: true)
}
return Just(model)
})
Comment on lines +31 to +40
Copy link
Member

Choose a reason for hiding this comment

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

👍🏻

.eraseToAnyPublisher()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ extension SignInRepository: SignInRepositoryInterface {
authService.signIn(token: token)
.catch ({ error in
guard
let error = error as? SOPTAPPError,
let error = error as? APIError,
case .network(let statusCode) = error,
statusCode == 400
else {
return self.userService.reissuance()
}

// NOTE: (@준호) 플그 미등록 + 비활동 유저의 경우 임시로 accessToken 빈 스트링 부여
// 자동로그인 시 활용하기 위함
UserDefaultKeyList.Auth.appAccessToken = ""
Comment on lines +41 to +43
Copy link
Contributor

Choose a reason for hiding this comment

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

👍🏻이제 잘 동작하겠군요

return Fail(error: error).eraseToAnyPublisher()
})
.map { entity in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ import Core
import Combine

public protocol MainRepositoryInterface {
func getUserMainInfo() -> AnyPublisher<UserMainInfoModel?, Error>
func getUserMainInfo() -> AnyPublisher<UserMainInfoModel?, Never>
Copy link
Member

Choose a reason for hiding this comment

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

에러 핸들링을 하게 된다면 여기에 Never로 적힌 것도 새로 정의한 Error로 바꾸는게 맞을까요?

func getServiceState() -> AnyPublisher<ServiceStateModel, Error>
}
1 change: 0 additions & 1 deletion SOPT-iOS/Projects/Domain/Sources/UseCase/MainUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public class DefaultMainUseCase {
extension DefaultMainUseCase: MainUseCase {
public func getUserMainInfo() {
repository.getUserMainInfo()
.replaceError(with: UserMainInfoModel.init(withError: true))
.sink { event in
print("MainUseCase: \(event)")
} receiveValue: { [weak self] userMainInfoModel in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ extension MainVC {
}

private func bindViews() {
// FIXME: - 디버깅을 위한 임시 바인딩
naviBar.rightButton.publisher(for: .touchUpInside)
.withUnretained(self)
.sink { owner, _ in
Expand Down Expand Up @@ -217,7 +216,7 @@ extension MainVC: UICollectionViewDelegate {
return
}

var needOfficialProject = service == .project && viewModel.userType == .visitor
let needOfficialProject = service == .project && viewModel.userType == .visitor
let serviceDomainURL = needOfficialProject
? ExternalURL.SOPT.project
: service.serviceDomainLink
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class SplashVC: UIViewController, SplashViewControllable {
// MARK: - UI Components

private let logoImage = UIImageView().then {
$0.image = DSKitAsset.Assets.splashLogo.image.withRenderingMode(.alwaysOriginal)
$0.image = DSKitAsset.Assets.imgLogoBig.image.withRenderingMode(.alwaysOriginal)
$0.contentMode = .scaleAspectFit
}

Expand All @@ -57,7 +57,7 @@ extension SplashVC {

private enum Metric {
static let logoWidth = 184.adjusted
static let topInset = 151.adjustedH + 137.adjustedH + 5.adjustedH
static let topInset = 151.adjustedH + 137.adjustedH
}

private func setUI() {
Expand Down Expand Up @@ -143,7 +143,7 @@ extension SplashVC {
let nextVC = factory.makeSignInVC().viewController
nextVC.modalPresentationStyle = .fullScreen
nextVC.modalTransitionStyle = .crossDissolve
self.present(nextVC, animated: true)
self.present(nextVC, animated: false)
}

private func presentNetworkAlertVC() {
Expand Down
4 changes: 4 additions & 0 deletions SOPT-iOS/Projects/Modules/Network/Sources/API/AuthAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,8 @@ extension AuthAPI: BaseAPI {
return .requestParameters(parameters: bodyParameters ?? [:], encoding: parameterEncoding)
}
}

public var validationType: ValidationType {
return .none
}
}
8 changes: 8 additions & 0 deletions SOPT-iOS/Projects/Modules/Network/Sources/API/UserAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,12 @@ extension UserAPI: BaseAPI {
return .requestPlain
}
}

public var validationType: ValidationType {
switch self {
case .reissuance:
return .none
default : return .successCodes
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// APIError.swift
// Network
//
// Created by Junho Lee on 2023/04/21.
// Copyright © 2023 SOPT-iOS. All rights reserved.
//

import Foundation

public enum APIError: Error, Equatable {
case network(statusCode: Int)
case unknown
case tokenReissuanceFailed

init(error: Error, statusCode: Int? = 0) {
guard let statusCode else { self = .unknown ; return }

self = .network(statusCode: statusCode)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class AlamoInterceptor: RequestInterceptor {
completion(.retry)
} else {
print("토큰 갱신 실패: ", request.request?.url)
completion(.doNotRetryWithError(error))
completion(.doNotRetryWithError(APIError.tokenReissuanceFailed))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ extension BaseAPI {
public var headers: [String: String]? {
return HeaderType.jsonWithToken.value
}

public var validationType: ValidationType {
return .successCodes
}
}

public enum HeaderType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,6 @@ import Core
import Alamofire
import Moya


public enum SOPTAPPError: Error {
case network(statusCode: Int)
case unknown

init(error: Error, statusCode: Int? = 0) {
guard let statusCode else { self = .unknown ; return }

self = .network(statusCode: statusCode)
}
}


open class BaseService<Target: TargetType> {

typealias API = Target
Expand All @@ -38,9 +25,15 @@ open class BaseService<Target: TargetType> {
lazy var provider = self.defaultProvider

private lazy var defaultProvider: MoyaProvider<API> = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 10
configuration.timeoutIntervalForResource = 10
configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
let interceptor = AlamoInterceptor()
let session = Session(configuration: configuration, interceptor: interceptor)
let provider = MoyaProvider<API>(
endpointClosure: endpointClosure,
session: DefaultAlamofireManager.shared,
session: session,
plugins: [NetworkLoggerPlugin(verbose: true)]
)
return provider
Expand Down Expand Up @@ -96,7 +89,14 @@ extension BaseService {
promise(.failure(error))
}
case .failure(let error):
promise(.failure(error))
if case MoyaError.underlying(let error, _) = error,
case AFError.requestRetryFailed(let retryError, _) = error,
let retryError = retryError as? APIError,
retryError == APIError.tokenReissuanceFailed {
promise(.failure(retryError))
} else {
promise(.failure(error))
}
}
}
}.eraseToAnyPublisher()
Expand All @@ -118,7 +118,7 @@ extension BaseService {
case 400...599:
// NOTE: (@승호) 여기에서 서버와 에러 처리 핸들링 해서 Error도 json Decode 해야 함
// 임시로 Error 처리
throw SOPTAPPError(error: NSError(domain: "임시에러", code: -1001), statusCode: response.statusCode)
throw APIError(error: NSError(domain: "임시에러", code: -1001), statusCode: response.statusCode)
default: break
}
} catch let error {
Expand Down