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

[GWL-268] 로그인 회원가입 연결 및 서버통신 #297

Merged
merged 23 commits into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
51762a0
fix: CircularDepedency 현상 개선
JongPyoAhn Dec 7, 2023
ddcac9a
chore: 중복 Mutipart제거
JongPyoAhn Dec 7, 2023
b5602ba
docs: 주석 제거
JongPyoAhn Dec 7, 2023
55d71b6
chore: MultiPart-Trinet 재결합
JongPyoAhn Dec 7, 2023
2c43ec2
feat: Trinet No Interceptor Upload
JongPyoAhn Dec 7, 2023
30f3178
rename: userBit -> newUserInformation
JongPyoAhn Dec 7, 2023
e907399
rename: userBit-newUserInformation
JongPyoAhn Dec 7, 2023
47062c7
fix: SignUp넘어갈 때, mainThread 에러 수정
JongPyoAhn Dec 7, 2023
e8bcad0
fix: ImageForm데이터 전달 안되는 현상 개선 및 회원가입 완료 시 받아온 토큰값 저장하는 로직 작성
JongPyoAhn Dec 8, 2023
4f5a905
chore: Lint 정상화
JongPyoAhn Dec 8, 2023
58d639e
fix: SignUpGenderBirth에서 SignUpProfile까지 성별벌스 데이터 이동안되는 현상 개선
JongPyoAhn Dec 8, 2023
929172f
Login, SignUp, TabBar Coordinator 연결
JongPyoAhn Dec 9, 2023
5b8e43c
add: Auth모듈 추가
JongPyoAhn Dec 9, 2023
a1375b0
add: Auth모듈에 Token Entity
JongPyoAhn Dec 9, 2023
a55e413
add: Auth모듈에 AuthProvider추가
JongPyoAhn Dec 9, 2023
8695a5a
chore: Token접근제어자 수정
JongPyoAhn Dec 9, 2023
6dd8a37
feat: 로그인 완료 시, 분기처리
JongPyoAhn Dec 9, 2023
d647ec1
fix: Encoder로 인해 액세스토큰이 키체인에 쌍따옴표가 붙어서 저장되는 현상 개선
JongPyoAhn Dec 9, 2023
376e072
Merge branch 'develop' into feature/iOS/GWL-268
WhiteHyun Dec 9, 2023
e9b9603
chore: lint 복구
WhiteHyun Dec 9, 2023
6d010f5
fix: merge conflict
JongPyoAhn Dec 9, 2023
2332606
fix: form-Data 이미지 그린아이에서 튕기는 현상 개선 이유 : fileName
JongPyoAhn Dec 9, 2023
9ff660a
chore: 피드백 반영
JongPyoAhn Dec 9, 2023
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
14 changes: 7 additions & 7 deletions iOS/.swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ only_rules:
- unowned_variable_capture
- custom_rules
- trailing_comma
# - line_length
- line_length

excluded:
- Carthage
Expand All @@ -29,7 +29,7 @@ indentation: 2

trailing_comma:
mandatory_comma: true

line_length:
warning: 150

Expand All @@ -43,28 +43,28 @@ custom_rules:
name: "Writing log messages directly to standard out is disallowed"
regex: "(\\bprint|\\bdebugPrint|\\bdump|Swift\\.print|Swift\\.debugPrint|Swift\\.dump)\\s*\\("
match_kinds:
- identifier
- identifier
message: "Don't commit `print(…)`, `debugPrint(…)`, or `dump(…)` as they write to standard out in release. Either log to a dedicated logging system or silence this warning in debug-only scenarios explicitly using `// swiftlint:disable:next no_direct_standard_out_logs`"
severity: error
no_file_literal:
name: "#file is disallowed"
regex: "(\\b#file\\b)"
match_kinds:
- identifier
- identifier
message: "Instead of #file, use #fileID"
severity: error
no_filepath_literal:
name: "#filePath is disallowed"
regex: "(\\b#filePath\\b)"
match_kinds:
- identifier
- identifier
message: "Instead of #filePath, use #fileID."
severity: error
no_unchecked_sendable:
name: "`@unchecked Sendable` is discouraged."
regex: "@unchecked Sendable"
match_kinds:
- attribute.builtin
- typeidentifier
- attribute.builtin
- typeidentifier
message: "Instead of using `@unchecked Sendable`, consider a safe alternative like a standard `Sendable` conformance or using `@preconcurrency import`. If you really must use `@unchecked Sendable`, you can add a `// swiftlint:disable:next no_unchecked_sendable` annotation with an explanation for how we know the type is thread-safe, and why we have to use @unchecked Sendable instead of Sendable. More explanation and suggested safe alternatives are available at https://github.com/airbnb/swift#unchecked-sendable."
severity: error
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public extension TargetDependency {
static let keychain: TargetDependency = .project(target: "Keychain", path: .relativeToCore("Keychain"))
static let cacher: TargetDependency = .project(target: "Cacher", path: .relativeToCore("Cacher"))
static let userInformationManager: TargetDependency = .project(target: "UserInformationManager", path: .relativeToShared("UserInformationManager"))
static let auth: TargetDependency = .project(target: "Auth", path: .relativeToShared("Auth"))

static func feature(_ feature: Feature) -> TargetDependency {
return .project(
Expand Down
5 changes: 0 additions & 5 deletions iOS/Projects/App/WeTri/Sources/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil
)
-> Bool {
let accessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkNWNkN2I2Ni03ZWU2LTQ0NTMtYTczZS0wMjYxMjY4NjFlOTYiLCJ0eXBlIjoiYWNjZXNzIiwiaWF0IjoxNzAxOTYyNzM5LCJleHAiOjE3MDIwNDkxMzl9.Wu-xloayJ2T_sWaL6FCeml7j6UBQZlA7A0vUms3aK9Q".data(using: .utf8)!
Keychain.shared.save(key: Tokens.accessToken, data: accessToken)

let refreshToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkNWNkN2I2Ni03ZWU2LTQ0NTMtYTczZS0wMjYxMjY4NjFlOTYiLCJ0eXBlIjoicmVmcmVzaCIsImlhdCI6MTcwMTk2MjczOSwiZXhwIjoxNzAyMDQ5MTM5fQ.8_R9fb67KO7z5Yu3AGPvD1DIdySDur285JU8C7UEjpg".data(using: .utf8)!
Keychain.shared.save(key: Tokens.refreshToken, data: refreshToken)
return true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved.
//

import Auth
import Coordinator
import LoginFeature
import SignUpFeature
import SplashFeature
import UIKit

Expand Down Expand Up @@ -49,16 +51,27 @@ final class AppCoordinator: AppCoordinating {
}

func showLoginFlow() {
// TODO: LoginCoordinator 연결

let loginCoordinator = LoginCoordinator(
let coordinator = LoginFeatureCoordinator(
navigationController: navigationController,
isMockEnvironment: true,
isMockEnvironment: false,
isMockFirst: true
)
childCoordinators.append(coordinator)
coordinator.finishDelegate = self
coordinator.loginFeatureFinishDelegate = self
coordinator.start()
}

childCoordinators.append(loginCoordinator)
loginCoordinator.start()
func showSignUpFlow(newUserInformation: NewUserInformation) {
let coordinator = SignUpFeatureCoordinator(
navigationController: navigationController,
newUserInformation: newUserInformation,
isMockEnvironment: false
)
childCoordinators.append(coordinator)
coordinator.finishDelegate = self
coordinator.signUpFeatureFinishDelegate = self
coordinator.start()
}

func showTabBarFlow() {
Expand Down Expand Up @@ -90,3 +103,30 @@ extension AppCoordinator: SplashCoordinatorFinishDelegate {
}
}
}

// MARK: SignUpFeatureCoordinatorFinishDelegate

extension AppCoordinator: SignUpFeatureCoordinatorFinishDelegate {
func signUpFeatureCooridnatorDidFinished() {
showTabBarFlow()
}
}

// MARK: LoginFeatureFinishDelegate

extension AppCoordinator: LoginFeatureFinishDelegate {
func loginFeatureCoordinatorDidFinished(initialUser: InitialUser?, token: Token?) {
if let initialUser {
showSignUpFlow(
newUserInformation: NewUserInformation(
mappedUserID: initialUser.mappedUserID,
provider: initialUser.provider
)
)
}

if token != nil {
showTabBarFlow()
}
}
}
11 changes: 11 additions & 0 deletions iOS/Projects/Core/Network/Sources/Foundation/TNEndPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ public extension TNEndPoint {
request.httpBody = body?.data
return request
}

func requestFormData() throws -> URLRequest {
guard let targetURL = URL(string: baseURL)?.appending(path: path).appending(query: query)
else {
throw TNError.invalidURL
}
var request = URLRequest(url: targetURL)
request.httpMethod = method.rawValue
request.allHTTPHeaderFields = headers.dictionary
return request
}
}

private extension URL {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,24 @@ import Foundation

public struct MultipartFormData {
private let boundary: String
private let imageDataList: [Data]

public let multipartItems: [MultipartItem]

public init(multipartItems: [MultipartItem]) {
boundary = UUID().uuidString
public init(
uuid: UUID,
mimeType _: String = "image/png",
imageDataList: [Data]
) {
boundary = "\(uuid.uuidString)"
multipartItems = imageDataList.map { MultipartItem(data: $0, mimeType: .imagePNG) }
self.imageDataList = imageDataList
}

public init(uuid: UUID, multipartItems: [MultipartItem]) {
boundary = uuid.uuidString
self.multipartItems = multipartItems
imageDataList = []
}

public func makeBody() -> Data {
Expand All @@ -27,7 +40,7 @@ public struct MultipartFormData {

for item in multipartItems {
let imageFieldName = "images"
let filename = "image\(UUID().uuidString)"
let filename = "image\(UUID().uuidString)\(item.fileExtension.rawValue)"

body.append(boundaryPrefix)
body.append(#"Content-Disposition: form-data; name="\#(imageFieldName)"; filename="\#(filename)"\#(lineBreak)"#)
Expand All @@ -38,7 +51,6 @@ public struct MultipartFormData {

// insert final boundary
body.append("--\(boundary)--\(lineBreak)")

return body
}
}
Expand Down
14 changes: 13 additions & 1 deletion iOS/Projects/Core/Network/Sources/Multipart/MultipartItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,28 @@

import Foundation

// MARK: - MultipartItem

public struct MultipartItem {
let data: Data
let mimeType: MimeType
let fileExtension: FileExtension

public init(data: Data, mimeType: MimeType) {
public init(data: Data, mimeType: MimeType, fileExtension: FileExtension = .png) {
self.data = data
self.mimeType = mimeType
self.fileExtension = fileExtension
}

public enum MimeType: String {
case imagePNG = "image/png"
}
}

// MARK: - FileExtension

public enum FileExtension: String {
case png = ".png"
case jpg = ".jpg"
case jpeg = ".jpeg"
}
13 changes: 13 additions & 0 deletions iOS/Projects/Core/Network/Sources/Provider/TNProvidable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ public struct TNProvider<T: TNEndPoint>: TNProvidable {
return retriedData
}

public func uploadRequest(_ service: T, successStatusCodeRange range: Range<Int> = 200 ..< 300) async throws -> Data {
guard let multipart = service.multipart else { throw TNError.unknownError }
let (data, response) = try await session.upload(for: service.requestFormData(), from: multipart.makeBody())
try checkStatusCode(response, successStatusCodeRange: range)
return data
}

public func request(_ service: T, completion: @escaping (Data?, URLResponse?, Error?) -> Void) throws {
try session.dataTask(with: service.request(), completionHandler: completion).resume()
}
Expand All @@ -45,6 +52,12 @@ public struct TNProvider<T: TNEndPoint>: TNProvidable {
return data
}

public func requestResponse(_ service: T, successStatusCodeRange range: Range<Int> = 200 ..< 300) async throws -> (Data, URLResponse) {
Copy link
Member

Choose a reason for hiding this comment

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

P3

우리가 처음에 했떤 Request랑 비슷한 것 같은데, 어떤 것이 다른가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

URLResponse에서 Status코드를 꺼내오기 위해서 해당 메소드를 추가했습니다!

let (data, response) = try await session.data(for: service.request(), delegate: nil)
try checkStatusCode(response, successStatusCodeRange: range)
return (data, response)
}

public func request(_ service: T, successStatusCodeRange range: Range<Int> = 200 ..< 300, interceptor: TNRequestInterceptor) async throws -> Data {
let request = try interceptor.adapt(service.request(), session: session)

Expand Down
2 changes: 1 addition & 1 deletion iOS/Projects/Features/Login/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ let project = Project.makeModule(
targets: .feature(
.login,
testingOptions: [.unitTest],
dependencies: [.trinet, .keychain, .combineCocoa, .log, TargetDependency.feature(.signUp)],
dependencies: [.trinet, .keychain, .combineCocoa, .log, .auth],
testDependencies: [],
resources: "Resources/**"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
"mappedUserID": "1233498sdafksdjhfk...",
"provider": "apple"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved.
//

import Auth
import Combine
import Foundation
import Log
Expand All @@ -16,6 +17,7 @@ import Trinet
enum AuthorizationRepositoryError: Error {
case invalidData
case failureDecode
case resonseDecodingError
}

// MARK: - AuthorizationRepository
Expand All @@ -32,19 +34,16 @@ struct AuthorizationRepository: AuthorizationRepositoryRepresentable {
return Future<LoginResponse, Never> { promise in
Task {
do {
guard let token = String(data: authorizationInfo.identityToken, encoding: .utf8),
let authorizationCode = String(data: authorizationInfo.authorizationCode, encoding: .utf8)
else {
return
}
let authorizationInfoRequestDTO = AuthorizationInfoRequestDTO(identityToken: token, authorizationCode: authorizationCode)
let token = String(decoding: authorizationInfo.identityToken, as: UTF8.self)
let authorizationCode = String(decoding: authorizationInfo.authorizationCode, as: UTF8.self)

let data = try await provider.request(.signIn(authorizationInfoRequestDTO))

guard let responseCode = try decoder.decode(Response.self, from: data).code else {
return
let authorizationInfoRequestDTO = AuthorizationInfoRequestDTO(identityToken: token, authorizationCode: authorizationCode)
let (data, response) = try await provider.requestResponse(.signIn(authorizationInfoRequestDTO))
Copy link
Member

Choose a reason for hiding this comment

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

p2
기존에 있던 Trinet Method으로 활용하면 좋을 것 같습니다!

guard let urlResponse = response as? HTTPURLResponse else {
throw AuthorizationRepositoryError.resonseDecodingError
}
switch responseCode {
let statusCode = urlResponse.statusCode
switch statusCode {
case AuthorizationRepositoryResponseCode.token.code:
let token = try decoder.decode(GWResponse<Token>.self, from: data).data
promise(.success((token, nil)))
Expand All @@ -71,7 +70,7 @@ enum AuthorizationRepositoryEndPoint: TNEndPoint {
var path: String {
switch self {
case .signIn:
return "auth/apple/signin"
return "/api/v1/auth/apple/signin"
Copy link
Member

Choose a reason for hiding this comment

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

이부분을 이렇게 쓰면 , api 버전이 높아지면 어떻게 될까요? p3

}
}

Expand All @@ -94,9 +93,7 @@ enum AuthorizationRepositoryEndPoint: TNEndPoint {
}

var headers: TNHeaders {
return .init(headers: [
// TODO: 헤더 설정
])
return .default
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,33 @@
// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved.
//

import Auth
import Foundation

// MARK: - InitialUser

/// 처음 로그인 하는 유저의 Response를 담을 Entity
public struct InitialUser {
/// 처음 로그인 하는지 아닌지
let isFirstLogined: Bool
public let isFirstLogined: Bool

///
let mappedUserID: String
public let mappedUserID: String

/// OAuth 로그인 종류
let provider: AuthProvider
public let provider: AuthProvider

public init(
isFirstLogined: Bool,
mappedUserID: String,
provider: AuthProvider
) {
self.isFirstLogined = isFirstLogined
self.mappedUserID = mappedUserID
self.provider = provider
}
}

// MARK: Codable

extension InitialUser: Codable {}

// MARK: - AuthProvider

enum AuthProvider: String, Codable {
case apple
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved.
//

import Auth
import Combine
import Foundation

Expand Down
Loading