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

merge :: (#1) Base Domain AppNetwork Setting & Auth Domain Setting #2

Merged
merged 59 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
3c9754e
feat :: Moya, RxMoya init
HongSJae Sep 26, 2023
e0c09ce
feat :: Swiftlint init
HongSJae Sep 26, 2023
56b6399
feat :: Jwt Token
HongSJae Sep 26, 2023
5371cb0
feat :: Jobis API
HongSJae Sep 26, 2023
a1fef7d
fix :: lint upgrade
HongSJae Sep 26, 2023
870a985
feat :: Main 버튼 클릭시 인증 보냄
HongSJae Oct 16, 2023
95124d3
feat :: PresentationAssembly
HongSJae Oct 16, 2023
e728943
feat :: AppDelegate - DI
HongSJae Oct 16, 2023
71ae356
fix :: jwtStore accessGroup name 변경
HongSJae Oct 16, 2023
809dc9d
fix :: TokenDTO Publish
HongSJae Oct 16, 2023
21a4e42
feat :: Auth UseCase
HongSJae Oct 16, 2023
b6a0b74
fix :: JobisAPI errorMap optinaling
HongSJae Oct 16, 2023
f253cf8
fix :: MainFlow - push -> set
HongSJae Oct 16, 2023
7d83a5b
feat :: AuthRepository
HongSJae Oct 16, 2023
d3153fd
feat :: Token, Jobis Error
HongSJae Oct 16, 2023
02d2f1c
feat :: SendAuthCodeRequestQuery
HongSJae Oct 16, 2023
d5b88e0
feat :: Authority, AuthCode Type
HongSJae Oct 16, 2023
7110017
feat :: KeychainAssembly
HongSJae Oct 16, 2023
9d43d75
feat :: Auth API
HongSJae Oct 17, 2023
19fa634
feat :: AuthRemote
HongSJae Oct 17, 2023
8d7a70c
feat :: Base Remote
HongSJae Oct 17, 2023
caaf524
fix :: Main Step import foundation remove
HongSJae Oct 17, 2023
72a8f05
feat :: UseCase, Repository, DataSource Assembly
HongSJae Oct 17, 2023
d72c8a6
feat :: JobisDate 변환 함수
HongSJae Oct 17, 2023
3be32ce
feat :: ReissueAuthorityEntity
HongSJae Oct 17, 2023
945cfaf
feat :: AuthREpositoryImpl
HongSJae Oct 17, 2023
ce381d2
refactoring :: BaseViewController 가독성 올림
HongSJae Oct 17, 2023
c885ce0
feat :: ReissueTokenResponseDTO
HongSJae Oct 17, 2023
756acba
feat :: 잡 파일
HongSJae Oct 17, 2023
e9a927c
feat :: Moya, RxMoya init
HongSJae Sep 26, 2023
39eb7c2
feat :: Swiftlint init
HongSJae Sep 26, 2023
423b131
feat :: Jwt Token
HongSJae Sep 26, 2023
10ef41a
feat :: Jobis API
HongSJae Sep 26, 2023
2bad0d7
fix :: lint upgrade
HongSJae Sep 26, 2023
f255775
feat :: Main 버튼 클릭시 인증 보냄
HongSJae Oct 16, 2023
cd23552
feat :: PresentationAssembly
HongSJae Oct 16, 2023
d99e5a3
feat :: AppDelegate - DI
HongSJae Oct 16, 2023
111aad6
fix :: jwtStore accessGroup name 변경
HongSJae Oct 16, 2023
c9c07c8
fix :: TokenDTO Publish
HongSJae Oct 16, 2023
6e17e36
feat :: Auth UseCase
HongSJae Oct 16, 2023
0ea4d57
fix :: JobisAPI errorMap optinaling
HongSJae Oct 16, 2023
78e813f
fix :: MainFlow - push -> set
HongSJae Oct 16, 2023
10da348
feat :: AuthRepository
HongSJae Oct 16, 2023
8f7a54a
feat :: Token, Jobis Error
HongSJae Oct 16, 2023
1e7560f
feat :: SendAuthCodeRequestQuery
HongSJae Oct 16, 2023
116c746
feat :: Authority, AuthCode Type
HongSJae Oct 16, 2023
e28f7d1
feat :: KeychainAssembly
HongSJae Oct 16, 2023
1adc72b
feat :: Auth API
HongSJae Oct 17, 2023
89db7eb
feat :: AuthRemote
HongSJae Oct 17, 2023
b1a9059
feat :: Base Remote
HongSJae Oct 17, 2023
2b29252
fix :: Main Step import foundation remove
HongSJae Oct 17, 2023
818216b
feat :: UseCase, Repository, DataSource Assembly
HongSJae Oct 17, 2023
aa43bb2
feat :: JobisDate 변환 함수
HongSJae Oct 17, 2023
0229bd4
feat :: ReissueAuthorityEntity
HongSJae Oct 17, 2023
de84c88
feat :: AuthREpositoryImpl
HongSJae Oct 17, 2023
65c9cd5
refactoring :: BaseViewController 가독성 올림
HongSJae Oct 17, 2023
5267c8e
feat :: ReissueTokenResponseDTO
HongSJae Oct 17, 2023
95ec644
feat :: 잡 파일
HongSJae Oct 17, 2023
b56c060
Merge remote-tracking branch 'origin/feature/(#1)-base_domain_appnetw…
HongSJae Oct 17, 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
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public extension TargetDependency.SPM {
static let Then = TargetDependency.external(name: "Then")
static let RxFlow = TargetDependency.external(name: "RxFlow")
static let Swinject = TargetDependency.external(name: "Swinject")
static let Moya = TargetDependency.external(name: "Moya")
static let RxMoya = TargetDependency.external(name: "RxMoya")
}
53 changes: 27 additions & 26 deletions Projects/App/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
import UIKit
import Data
import Swinject
import Then
import Presentation
import Domain
import Core

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

static var container: Container {
let container = Container()
container.register(MainViewModel.self) { _ in
MainViewModel()
}
container.register(MainViewController.self) { resolver in
return MainViewController(resolver.resolve(MainViewModel.self)!)
}
return container
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

static var container = Container()
var assembler: Assembler!

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
assembler = Assembler([
KeychainAssembly(),
DataSourceAssembly(),
RepositoryAssembly(),
UseCaseAssembly(),
PresentationAssembly()
], container: AppDelegate.container)
return true
}

// MARK: UISceneSession Lifecycle

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}


func application(
_ application: UIApplication,
didDiscardSceneSessions sceneSessions: Set<UISceneSession>
) { }
}

22 changes: 6 additions & 16 deletions Projects/App/Sources/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,20 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
window = UIWindow(windowScene: windowScence)
window?.windowScene = windowScence
window?.backgroundColor = .white

let appFlow = AppFlow(window: window!, container: AppDelegate.container)
self.coordinator.coordinate(flow: appFlow, with: AppStepper())
window?.makeKeyAndVisible()
}

func sceneDidDisconnect(_ scene: UIScene) {

}

func sceneDidBecomeActive(_ scene: UIScene) {

}

func sceneWillResignActive(_ scene: UIScene) {
func sceneDidDisconnect(_ scene: UIScene) { }

}
func sceneDidBecomeActive(_ scene: UIScene) { }

func sceneWillEnterForeground(_ scene: UIScene) {
func sceneWillResignActive(_ scene: UIScene) { }

}
func sceneWillEnterForeground(_ scene: UIScene) { }

func sceneDidEnterBackground(_ scene: UIScene) {

}
func sceneDidEnterBackground(_ scene: UIScene) { }

}
9 changes: 4 additions & 5 deletions Projects/Core/Sources/Base/BaseViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import UIKit
import RxCocoa
import RxSwift

open class BaseViewController<T>: UIViewController {
public let viewModel: T
open class BaseViewController<ViewModel: BaseViewModel>: UIViewController {
public let viewModel: ViewModel
public var disposeBag = DisposeBag()
let bounds = UIScreen.main.bounds

public init(_ viewModel: T) {
public init(_ viewModel: ViewModel) {
self.viewModel = viewModel
super .init(nibName: nil, bundle: nil)
}
Expand All @@ -23,12 +23,11 @@ open class BaseViewController<T>: UIViewController {
open func addView() { }

open func layout() { }

open func bind() { }

open func attribute() {}


required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
Expand Down
2 changes: 1 addition & 1 deletion Projects/Core/Sources/Base/BaseViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import UIKit
public protocol BaseViewModel {
associatedtype Input
associatedtype Output

func transform(_ input: Input) -> Output
}
48 changes: 48 additions & 0 deletions Projects/Core/Sources/JwtStore/JwtImpl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Foundation

public struct KeychainImpl: Keychain {
public init() {}

private let bundleIdentifier: String = Bundle.main.bundleIdentifier ?? ""
private let appIdentifierPrefix = Bundle.main.infoDictionary!["AppIdentifierPrefix"] as? String ?? ""
private var accessGroup: String {
"\(appIdentifierPrefix)com.team.jobis.JOBIS-DSM-iOS-v2.keychainGroup"
}

public func save(type: KeychainType, value: String) {
let query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: type.rawValue,
kSecValueData: value.data(using: .utf8, allowLossyConversion: false) ?? .init(),
kSecAttrAccessGroup: accessGroup
]
SecItemDelete(query)
SecItemAdd(query, nil)
}

public func load(type: KeychainType) -> String {
let query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: type.rawValue,
kSecReturnData: kCFBooleanTrue!,
kSecMatchLimit: kSecMatchLimitOne,
kSecAttrAccessGroup: accessGroup
]
var dataTypeRef: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
if status == errSecSuccess {
guard let data = dataTypeRef as? Data else { return "" }
return String(data: data, encoding: .utf8) ?? ""
}
return ""
}

public func delete(type: KeychainType) {
let query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: type.rawValue,
kSecAttrAccessGroup: accessGroup
]
SecItemDelete(query)
}
}
12 changes: 12 additions & 0 deletions Projects/Core/Sources/JwtStore/JwtStore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
public enum KeychainType: String {
case accessToken = "ACCESS-TOKEN"
case refreshToken = "REFRESH-TOKEN"
case accessExpiresAt = "ACCESS-EXPIRED-AT"
case refreshExpiresAt = "REFRESH-EXPIRED-AT"
}

public protocol Keychain {
func save(type: KeychainType, value: String)
func load(type: KeychainType) -> String
func delete(type: KeychainType)
}
11 changes: 11 additions & 0 deletions Projects/Core/Sources/JwtStore/KeychainAssembly.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation
import Swinject
public final class KeychainAssembly: Assembly {
public init() {}

public func assemble(container: Container) {
container.register(Keychain.self) { _ in
KeychainImpl()
}
}
}
1 change: 0 additions & 1 deletion Projects/Core/Sources/Steps/MainStep.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Foundation
import RxFlow

public enum MainStep: Step {
Expand Down
14 changes: 14 additions & 0 deletions Projects/Data/Sources/DI/DataSourceAssembly.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation
import Swinject
import Core
import Domain

public final class DataSourceAssembly: Assembly {
public init() {}

public func assemble(container: Container) {
container.register(AuthRemote.self) { resolver in
AuthRemoteImpl(keychainLocal: resolver.resolve(Keychain.self)!)
}
}
}
13 changes: 13 additions & 0 deletions Projects/Data/Sources/DI/RepositoryAssembly.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Foundation
import Swinject
import Domain

public final class RepositoryAssembly: Assembly {
public init() {}

public func assemble(container: Container) {
container.register(AuthRepository.self) { resolver in
AuthRepositoryImpl(authRemote: resolver.resolve(AuthRemote.self)!)
}
}
}
27 changes: 27 additions & 0 deletions Projects/Data/Sources/DI/UseCaseAssembly.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation
import Swinject
import Domain

public final class UseCaseAssembly: Assembly {
public init() {}

public func assemble(container: Container) {
container.register(SendAuthCodeUseCase.self) { resolver in
SendAuthCodeUseCase(
authRepository: resolver.resolve(AuthRepository.self)!
)
}

container.register(VerifyAuthCodeUseCase.self) { resolver in
VerifyAuthCodeUseCase(
authRepository: resolver.resolve(AuthRepository.self)!
)
}

container.register(ReissueTokenUaseCase.self) { resolver in
ReissueTokenUaseCase(
authRepository: resolver.resolve(AuthRepository.self)!
)
}
}
}
17 changes: 17 additions & 0 deletions Projects/Data/Sources/DTO/ReissueTokenResponseDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation
import Domain
import AppNetwork

public struct ReissueTokenResponseDTO: Decodable {
public let authority: AuthorityType

public init(authority: AuthorityType) {
self.authority = authority
}
}

public extension ReissueTokenResponseDTO {
func toDomain() -> ReissueAuthorityEntity {
ReissueAuthorityEntity(authority: authority)
}
}
72 changes: 72 additions & 0 deletions Projects/Data/Sources/DataSource/API/AuthAPI.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import Moya
import Domain
import AppNetwork

public enum AuthAPI {
case verifyAuthCode(email: String, authCode: String)
case sendAuthCode(SendAuthCodeRequestQuery)
case reissueToken
}

extension AuthAPI: JobisAPI {
public typealias ErrorType = JobisError

public var domain: JobisDomain {
.auth
}

public var urlPath: String {
switch self {
case .sendAuthCode, .verifyAuthCode:
return "/code"

case .reissueToken:
return "/reissue"
}
}

public var method: Method {
switch self {
case .sendAuthCode:
return .post

case .verifyAuthCode:
return .patch

case .reissueToken:
return .put
}
}

public var task: Task {
switch self {
case let .sendAuthCode(req):
return .requestJSONEncodable(req)

case let .verifyAuthCode(email, authCode):
return .requestParameters(
parameters: [
"email": email,
"auth_code": authCode
], encoding: URLEncoding.queryString
)

case .reissueToken:
return .requestPlain
}
}

public var jwtTokenType: JwtTokenType {
switch self {
case .reissueToken:
return .refreshToken

default:
return .none
}
}

public var errorMap: [Int: ErrorType]? {
return nil
}
}
Loading