-
Notifications
You must be signed in to change notification settings - Fork 0
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
Network [#55] BaseURL 설정 및 네트워크 세팅 #56
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { | |
NSAttributedString.Key.foregroundColor: UIColor.donBlack | ||
] | ||
|
||
KakaoSDK.initSDK(appKey: Bundle.main.object(forInfoDictionaryKey: Config.Keys.Plist.nativeAppKey) as? String ?? "") | ||
KakaoSDK.initSDK(appKey: Config.nativeAppKey) | ||
return true | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 코드 패치에 대한 간단한 코드 리뷰를 도와드리겠습니다. 버그 위험 및 개선 제안 사항을 언급하도록 하겠습니다:
버그 위험:
개선 제안:
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,20 +19,18 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { | |
self.window?.rootViewController = SplashViewController() | ||
self.window?.makeKeyAndVisible() | ||
|
||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.0) { | ||
// let navigationController = UINavigationController(rootViewController: LoginViewController(viewModel: LoginViewModel())) | ||
// let navigationController = UINavigationController(rootViewController: DontBeTabBarController()) | ||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.0) { | ||
if loadUserData()?.isSocialLogined == true && loadUserData()?.isJoinedApp == true && loadUserData()?.isOnboardingFinished == true { | ||
let navigationController = UINavigationController(rootViewController: DontBeTabBarController()) | ||
self.window?.rootViewController = navigationController | ||
} else if loadUserData()?.isJoinedApp == false { | ||
let navigationController = UINavigationController(rootViewController: LoginViewController(viewModel: LoginViewModel())) | ||
let navigationController = UINavigationController(rootViewController: LoginViewController(viewModel: LoginViewModel(networkProvider: SocialLoginService()))) | ||
self.window?.rootViewController = navigationController | ||
} else if loadUserData()?.isOnboardingFinished == false { | ||
let navigationController = UINavigationController(rootViewController: OnboardingViewController()) | ||
self.window?.rootViewController = navigationController | ||
} else { | ||
let navigationController = UINavigationController(rootViewController: LoginViewController(viewModel: LoginViewModel())) | ||
let navigationController = UINavigationController(rootViewController: LoginViewController(viewModel: LoginViewModel(networkProvider: SocialLoginService()))) | ||
self.window?.rootViewController = navigationController | ||
} | ||
self.window?.makeKeyAndVisible() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아래는 코드 패치입니다. 지적해야 할 버그 위험 또는 개선 제안이 있다면 환영합니다: @@ -19,20 +19,18 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
코드 리뷰를 진행하겠습니다.
이 코드 패치를 통해 일부 버그 위험을 해결하고 코드 구조를 개선했습니다. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,13 @@ | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>NSAppTransportSecurity</key> | ||
<dict> | ||
<key>NSAllowsArbitraryLoads</key> | ||
<true/> | ||
</dict> | ||
<key>BASE_URL</key> | ||
<string>$(BASE_URL)</string> | ||
<key>UIUserInterfaceStyle</key> | ||
<string>Light</string> | ||
<key>LSApplicationQueriesSchemes</key> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 코드 패치에서는 향상사항:
문제점:
요약:
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// | ||
// BaseResponse.swift | ||
// DontBe-iOS | ||
// | ||
// Created by 변희주 on 1/14/24. | ||
// | ||
|
||
import Foundation | ||
|
||
struct BaseResponse<T: Decodable>: Decodable { | ||
let status: Int | ||
let success: Bool | ||
let message: String | ||
let data: T? | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 코드 패치는 큰 결함이 없어 보입니다. 다만, 한 가지 개선점을 제안드릴게요. 굳이 struct BaseResponse<T>: Decodable where T: Decodable {
let status: Int
let success: Bool
let message: String
let data: T?
} 이와 같이 수정하면 현재의 코드와 동일한 동작을 하지만, |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ enum Config { | |
enum Keys { | ||
enum Plist { | ||
static let nativeAppKey = "NATIVE_APP_KEY" | ||
static let baseURL = "BASE_URL" | ||
} | ||
} | ||
|
||
|
@@ -21,3 +22,19 @@ enum Config { | |
return dictionary | ||
}() | ||
} | ||
|
||
extension Config { | ||
static let nativeAppKey: String = { | ||
guard let key = Config.infoDictionary[Keys.Plist.nativeAppKey] as? String else { | ||
fatalError("Base URL is not set in plist for this configuration") | ||
} | ||
return key | ||
}() | ||
|
||
static let baseURL: String = { | ||
guard let key = Config.infoDictionary[Keys.Plist.baseURL] as? String else { | ||
fatalError("Base URL is not set in plist for this configuration") | ||
} | ||
return key | ||
}() | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 코드 패치는 주의해야 할 부분은 개선 사항으로는 아래는 개선된 코드의 예시입니다: extension Config {
static var nativeAppKey: String? {
return Config.infoDictionary[Keys.Plist.nativeAppKey] as? String
}
static var baseURL: String? {
return Config.infoDictionary[Keys.Plist.baseURL] as? String
}
} 이렇게 구현하면 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,23 @@ | |
|
||
import UIKit | ||
|
||
enum NetworkError { | ||
enum NetworkError: Int, Error, CustomStringConvertible { | ||
var description: String { self.errorDescription } | ||
case responseError | ||
case badRequestError = 400 | ||
case unautohorizedError = 401 | ||
case notFoundError = 404 | ||
case internalServerError = 500 | ||
case unknownError | ||
|
||
var errorDescription: String { | ||
switch self { | ||
case .responseError: return "REQUEST_ERROR" | ||
case .badRequestError: return "BAD_REQUEST_ERROR" | ||
case .unautohorizedError: return "UNAUTHORIZED_ERROR" | ||
case .notFoundError: return "NOT_FOUND_ERROR" | ||
case .internalServerError: return "SERVER_ERROR" | ||
case .unknownError: return "UNKNOWN_ERROR" | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3 |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// | ||
// SocialLoginRequestDTO.swift | ||
// DontBe-iOS | ||
// | ||
// Created by 변희주 on 1/14/24. | ||
// | ||
|
||
import Foundation | ||
|
||
struct SocialLoginRequestDTO: Encodable { | ||
let socialPlatform: String | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// | ||
// SocialLoginResponseDTO.swift | ||
// DontBe-iOS | ||
// | ||
// Created by 변희주 on 1/14/24. | ||
// | ||
|
||
import Foundation | ||
|
||
// MARK: - SocilLoginResponseDTO | ||
struct SocialLoginResponseDTO: Decodable { | ||
let nickName: String | ||
let memberId: Int | ||
let accessToken, refreshToken: String | ||
let memberProfileUrl: String | ||
let isNewUser: Bool | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// | ||
// KakaoLoginService.swift | ||
// DontBe-iOS | ||
// | ||
// Created by 변희주 on 1/14/24. | ||
// | ||
|
||
import Foundation | ||
import Foundation | ||
|
||
protocol SocialLoginServiceType { | ||
func makeRequestURL(accessToken: String) -> URLRequest | ||
func postData(accessToken: String) async throws -> BaseResponse<SocialLoginResponseDTO>? | ||
func parseData(data: Data) -> BaseResponse<SocialLoginResponseDTO>? | ||
} | ||
|
||
final class SocialLoginService: SocialLoginServiceType { | ||
|
||
func makeRequestURL(accessToken: String) -> URLRequest { | ||
|
||
let baseURL = Config.baseURL | ||
|
||
let urlString = "\(baseURL)/auth" | ||
|
||
// URL 생성 | ||
guard let url = URL(string: urlString) else { | ||
fatalError("Failed to create URL") | ||
} | ||
|
||
// URLRequest 생성 | ||
var request = URLRequest(url: url) | ||
request.httpMethod = "POST" | ||
|
||
// 헤더 추가 | ||
let header = ["Content-Type": "application/json", | ||
"Authorization": "Bearer \(accessToken)"] | ||
header.forEach { | ||
request.addValue($0.value, forHTTPHeaderField: $0.key) | ||
} | ||
|
||
// 리퀘스트 바디 설정 | ||
let requestBody = SocialLoginRequestDTO(socialPlatform: "KAKAO") | ||
do { | ||
let jsonData = try JSONEncoder().encode(requestBody) | ||
request.httpBody = jsonData | ||
} catch { | ||
print("Failed to encode request body: \(error)") | ||
} | ||
|
||
return request | ||
} | ||
|
||
func postData(accessToken: String) async throws -> BaseResponse<SocialLoginResponseDTO>? { | ||
do { | ||
let request = self.makeRequestURL(accessToken: accessToken) | ||
let (data, response) = try await URLSession.shared.data(for: request) | ||
|
||
guard let httpResponse = response as? HTTPURLResponse else { | ||
throw NetworkError.responseError | ||
} | ||
|
||
switch httpResponse.statusCode { | ||
case 200..<300: | ||
return parseData(data: data) | ||
case 400: | ||
throw NetworkError.badRequestError | ||
case 401: | ||
throw NetworkError.unautohorizedError | ||
case 404: | ||
throw NetworkError.notFoundError | ||
case 500: | ||
throw NetworkError.internalServerError | ||
default: | ||
throw NetworkError.unknownError | ||
} | ||
} catch { | ||
throw error | ||
} | ||
} | ||
|
||
func parseData(data: Data) -> BaseResponse<SocialLoginResponseDTO>? { | ||
do { | ||
let jsonDecoder = JSONDecoder() | ||
let result = try jsonDecoder.decode(BaseResponse<SocialLoginResponseDTO>.self, from: data) | ||
return result | ||
} catch { | ||
print(error) | ||
return 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.
해당 코드 패치에는 다음과 같은 변경 사항이 있습니다:
파일 추가:
SocialLoginService.swift
,BaseResponse.swift
,SocialLoginResponseDTO.swift
,SocialLoginRequestDTO.swift
파일이 소스에 추가되었습니다.그룹 추가:
SocialLogin
그룹이Network
그룹 안에 추가되었습니다.DTO
와Service
그룹이SocialLogin
그룹 안에 추가되었습니다.수정 사항 및 개선 제안은 제공하지 않았습니다.