Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
d7acea3
refactor/#112: Convert to Folder로 개선
0Hooni Apr 14, 2025
fd2d10c
refactor/#112: KeyPath → Secrets로 변경
0Hooni Apr 14, 2025
51dcfee
refactor/#112: Extension 위치 이동
0Hooni Apr 14, 2025
226e19c
refactor/#112: 예상 모듈화에 맞게 폴더 구조 변경
0Hooni Apr 14, 2025
1db8dab
refactor/#112: AdminRepository 인터페이스 분리
0Hooni Apr 14, 2025
6ed7c3d
refactor/#112: Repository 인터페이스 분리
0Hooni Apr 14, 2025
0cc4bf9
refactor/#112: Entity 폴더명 임시 수정
0Hooni Apr 14, 2025
cc48b56
refactor/#112: UseCase 인터페이스 분리
0Hooni Apr 14, 2025
448218a
refactor/#112: final, private let 으로 통일
0Hooni Apr 14, 2025
3448cac
refactor/#112: DTO 폴더링
0Hooni Apr 14, 2025
405e9fe
refactor/#112: Presigned 폴더링
0Hooni Apr 14, 2025
0e1fad0
refactor/#112: 클린아키텍처 베이스 폴더링 구조로 변경
0Hooni Apr 14, 2025
e4230f2
refactor/#112: 불필요한 파일 제거 및 Layer에 맞게 폴더링
0Hooni Apr 16, 2025
f76fb70
feat/#113: DIContainer 구현
0Hooni Apr 16, 2025
d62546d
feat/#113: 간단한 의존성 주입을 위한 PropertyWrapper 구현
0Hooni Apr 16, 2025
b99d07c
refactor/#113: KeyChainService 의존성 관리를 위해 DIContainer 적용
0Hooni Apr 16, 2025
aec9f97
refactor/#113: Provider 의존성 대체
0Hooni Apr 16, 2025
54de56d
refactor/#113: MapUseCase 의존성 대체
0Hooni Apr 16, 2025
c25bc34
style/#113: DIContainer lint 에러 수정
0Hooni Apr 16, 2025
de9e70b
refactor/#113: AdminUseCase 의존성 주입
0Hooni Apr 16, 2025
c34ff2e
refactor/#113: MapUseCase 의존성 주입
0Hooni Apr 16, 2025
e67aec7
refactor/#113: UserAPIUseCase 의존성 주입
0Hooni Apr 16, 2025
8c0e3eb
refactor/#113: PopUpAPIUseCase 의존성 주입
0Hooni Apr 16, 2025
e489b14
refactor/#113: CommentAPIUseCase 의존성 주입
0Hooni Apr 16, 2025
d13c2b2
refactor/#113: HomeAPIUseCase 의존성 제거
0Hooni Apr 16, 2025
955d848
refactor/#113: AuthAPIUseCase 의존성 주입
0Hooni Apr 16, 2025
514cad7
refactor/#113: PopUpAPIUseCase 의존성 주입
0Hooni Apr 16, 2025
588b5fe
refactor/#113: SignUpAPIUseCase 의존성 주입
0Hooni Apr 16, 2025
5a75bcf
refactor/#113: MapDirectionRepository 의존성 주입
0Hooni Apr 16, 2025
235a227
remove/#113: 불필요한 의존성 인스턴스 생성 제거
0Hooni Apr 16, 2025
add928b
fix/#113: MapDirectionRepository 의존성 등록
0Hooni Apr 17, 2025
71dd5ac
refactor/#116: HomeAPI 관련 Domain Layer DTO 제거 - 빌드 확인
dongglehada Apr 17, 2025
fa9db31
refactor/#116: PopUpAPI 관련 Domain Layer DTO 제거 - 빌드 확인
dongglehada Apr 17, 2025
c34382d
refactor/#116: HomeAPI 관련 Domain Layer DTO 제거 - 빌드 확인
dongglehada Apr 17, 2025
64bc196
refactor/#116: SortedRequestDTO Home, User 분리 - 빌드 확인
dongglehada Apr 17, 2025
748eaa1
Merge pull request #115 from PopPool/refactor/#113-feature-DI-Contain…
0Hooni Apr 18, 2025
8be3180
refactor/#117: Admin 도메인 레이어 DTO 제거 및 Params 객체 적용
zzangzzangguy Apr 19, 2025
0d32c26
refactor/#117: Map API 관련 DTO제거 빌드테스트 확인
zzangzzangguy Apr 19, 2025
22a0571
refactor/#117: MapPopUpStore 도메인 모델에서 프레임워크 의존성 제거
zzangzzangguy Apr 19, 2025
9edf785
refactor/#117: DTO -> 도메인 모델 변환 로직을 MapDomainModelConverter로 분리
zzangzzangguy Apr 19, 2025
0e85d9b
refactor/#117: Auth API DomainLayer DTO 제거 빌드확인
zzangzzangguy Apr 19, 2025
1f4ce48
refactor/#117: Comment API 레포지토리 인터페이스에서 DTO 파라미터 제거 및 임플에서 매핑 빌드테스트 확인
zzangzzangguy Apr 19, 2025
ca1ddb7
style/#117: Apply SwiftLint autocorrect
github-actions[bot] Apr 20, 2025
15a7366
Merge pull request #117 from PopPool/refactor/#116-Remove-DTOs-from-t…
dongglehada Apr 20, 2025
49fd01b
Merge branch 'refactor/#112-Modulization' into refactor/#117-remove-d…
zzangzzangguy Apr 20, 2025
ab5403d
Merge branch 'refactor/#112-Modulization' of https://github.com/PopPo…
zzangzzangguy Apr 20, 2025
7c88129
Merge branch 'refactor/#117-remove-dtos-domain-layer' of https://gith…
zzangzzangguy Apr 20, 2025
0eb1045
refactor/#117: AdminVC DTO사용 제거 , Params 스타일에 맞도록 네이밍 변경
zzangzzangguy Apr 20, 2025
11a8620
refactor/#117: 팝업레지스터 뷰컨에서 DTO 제거 빌드테스트 확인
zzangzzangguy Apr 20, 2025
9ed3c9e
Merge pull request #120 from PopPool/refactor/#117-remove-dtos-domain…
zzangzzangguy Apr 20, 2025
af70a35
refactor/#112: 모듈화 및 Layer에 파일 이동
0Hooni Apr 20, 2025
3dd9921
chore/#112: 라이브러리 경고 해제를 위한 빌드 설정 변경
0Hooni Apr 20, 2025
a832442
refactor/#112: 인터페이스 접근 제어자를 public으로 수정
0Hooni Apr 20, 2025
8e1998a
chore/#112: 모듈간 필요한 의존성 연결
0Hooni Apr 20, 2025
512dcde
chore/#112: Build phase에 컴파일할 소스 목록 수정
0Hooni Apr 20, 2025
c6795b4
refactor/#112: 구현체에 DomainInterface를 import
0Hooni Apr 20, 2025
c52cfd8
refactor/#112: 외부에서 알도록 Entity 접근제어자를 public으로 변경
0Hooni Apr 20, 2025
147f35f
chore/#112: Infra에 Rx, Kakao 관련 패키지 추가
0Hooni Apr 20, 2025
aa96337
chore/#112: Domain에 필요한 패키지 추가
0Hooni Apr 20, 2025
bf74f1e
refactor/#112: Logger와 연관된 문제 해결
0Hooni Apr 20, 2025
f20aef8
fix/#112: PreSignedService 사용을 DataLayer를 통하도록 수정
0Hooni Apr 20, 2025
01e2cff
remove/#112: 사용하지 않는 Domain 컨버터 제거
0Hooni Apr 20, 2025
907702c
refactor/#112: Secrets 접근제어자 수정
0Hooni Apr 20, 2025
a17463b
refactor/#112: 접근제어자 수정
0Hooni Apr 20, 2025
356d3de
refactor/#112: Provider 관련 접근제어자 수정
0Hooni Apr 20, 2025
23b1911
refactor/#112: SceneDelegate에서 문제되던 접근제어자 수정
0Hooni Apr 20, 2025
57d0a27
fix/#112: PutCommentImageDataRequestDTO 의존성 제거
0Hooni Apr 20, 2025
c36a965
fix/#112: GetPopUpDirectionResponseDTO 잘못된 사용 제거
0Hooni Apr 20, 2025
49f53b7
fix/#112: FindDirectionRepositoryImpl 반환 값 문제 해결
0Hooni Apr 20, 2025
07cc260
refactor/#112: 접근제어자 수정
0Hooni Apr 20, 2025
222a73d
refactor/#112: DomainInterface 의존 추가 및 접근제어자
0Hooni Apr 20, 2025
cfd3762
refactor/#112: 접근 제어자 수정
0Hooni Apr 20, 2025
1e10d7a
refactor/#112: 일부 Extension을 PresentationLayer로 이동
0Hooni Apr 20, 2025
0650a7b
refactor/#112: 빠져있던 import, public 추가
0Hooni Apr 21, 2025
7656442
refactor/#112: LoginService 의존성 흐름 개선
0Hooni Apr 21, 2025
9df71dd
refactor/#112: import, public 추가
0Hooni Apr 21, 2025
5794c3f
refactor/#112: import, public 추가
0Hooni Apr 21, 2025
89b938f
refactor/#112: PreSignedUseCase 생성자 주입
0Hooni Apr 21, 2025
28a24fc
Merge branch 'refactor/#112-Modulization' of https://github.com/PopPo…
0Hooni Apr 21, 2025
604396e
refactor/#112: import, public 추가
0Hooni Apr 21, 2025
5811183
Merge branch 'refactor/#112-Modulization' of https://github.com/PopPo…
0Hooni Apr 21, 2025
eeccce6
refactor/#112: import, public 문제 해결
0Hooni Apr 21, 2025
190941a
refactor/#112: import, public 문제 해결
0Hooni Apr 21, 2025
d845683
remove/#112: InstaComment 관련 코드 제거
0Hooni Apr 21, 2025
0ef0751
Merge branch 'refactor/#112-Modulization' of https://github.com/PopPo…
0Hooni Apr 21, 2025
ecc17d9
refactor/#112 : authorizationCode 접근레벨 Mutation 타입명시
zzangzzangguy Apr 21, 2025
b145fd2
refactor/#112: 패키지 수정 및 접근 제어자 수정
dongglehada Apr 21, 2025
5bc1e72
Merge branch 'refactor/#112-Modulization' of https://github.com/PopPo…
dongglehada Apr 21, 2025
b96570f
fix/#112: 원형복구
dongglehada Apr 21, 2025
bf63396
fix/#112: DIContainer 스레드 에러 해결
0Hooni Apr 21, 2025
6096826
chore/#112: Static library를 사용하도록 하여 @rpath 문제 해결
0Hooni Apr 21, 2025
8e57720
chore/#112: 프레임워크 do not embed로 변경
0Hooni Apr 21, 2025
e5bbed3
chore/#112: 패키지 간소화
0Hooni Apr 21, 2025
1d65ee2
style/#112: Apply SwiftLint autocorrect
github-actions[bot] Apr 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Foundation

/// 의존성 주입 컨테이너
///
/// 이 컨테이너는 타입 기반으로 의존성을 등록하고 어디서든 안전하게 꺼내 쓸 수 있도록 도와줍니다.
///
/// 앱 시작 시점에 필요한 구현체를 `register(_:_: )`를 통해 등록하고,
/// 이후에는 `resolve(_:)` 메서드를 통해 원하는 타입의 인스턴스를 꺼낼 수 있습니다.
///
/// ## 등록 예시
/// ```swift
/// DIContainer.register(SampleProtocol.self) {
/// SampleImpl()
/// }
/// ```
///
/// ## 사용 예시
/// ```swift
/// // DIContainer의 resolve 메서드를 사용하는 방식
/// let sample: SampleProtocol = DIContainer.resolve(SampleProtocol.self)
/// ```
public final class DIContainer {
private static let container = DIContainer()

private var registrations: [ObjectIdentifier: () -> Any] = [:]

private let resolveQueue = DispatchQueue(label: "resolveQueue")

private init() {}

/// 의존성을 등록합니다.
/// - Parameters:
/// - type: 등록할 프로토콜 또는 클래스 타입
/// - implementation: 해당 타입에 대응되는 구현체를 생성하는 클로저
public static func register<T>(
_ type: T.Type,
_ implementation: @escaping () -> T
) {
container.register(type, implementation)
}

/// 의존성을 꺼내옵니다.
/// - Parameter type: 요청할 타입
/// - Returns: 등록된 타입의 인스턴스
public static func resolve<T>(_ type: T.Type) -> T {
return container.resolve(type)
}

private func register<T>(
_ type: T.Type,
_ implementation: @escaping () -> T
) {
let key = ObjectIdentifier(type)
registrations[key] = { implementation() }
}

private func resolve<T>(_ type: T.Type) -> T {
let key = ObjectIdentifier(type)

guard let registration = registrations[key],
let instance = registration() as? T
else { fatalError("\(type) does not registered") }

return instance
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Foundation

/// 의존성 자동 주입을 위한 프로퍼티 래퍼
///
/// 사용하는 곳에서 `@Dependency`만 붙이면 등록된 구현체가 자동으로 주입됩니다.
///
/// Swift의 프로퍼티 래퍼 특성상 `var`로 선언해야 하지만, 실제 인스턴스는 외부에서 변경할 수 없도록 `private(set)`으로 보호되어 불변성을 유지합니다.
///
/// 사용 예시:
/// ```swift
/// class MyViewModel {
/// @Dependency var sample: SampleProtocol
///
/// func run() {
/// sample.doSomething()
/// }
/// }
/// ```
@propertyWrapper
public final class Dependency<T> {
/// DIContainer에서 꺼내온 실제 인스턴스
public private(set) var wrappedValue: T

/// DIContainer로부터 자동으로 인스턴스를 꺼내와 초기화합니다.
public init() {
self.wrappedValue = DIContainer.resolve(T.self)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
//
// Date+.swift
// Poppool
//
// Created by SeoJunYoung on 11/30/24.
//

import Foundation

extension Optional where Wrapped == Date {
public extension Optional where Wrapped == Date {
/// `yyyy. MM. dd` 형식으로 날짜를 문자열로 변환합니다.
/// - Parameter defaultString: 날짜가 nil일 경우 반환할 기본 문자열 (기본값: 빈 문자열 "")
/// - Returns: 형식화된 날짜 문자열 또는 기본 문자열
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
//
// Reactive+.swift
// MomsVillage
//
// Created by SeoJunYoung on 8/26/24.
//

import UIKit

import RxCocoa
import RxSwift

extension Reactive where Base: UIViewController {
public extension Reactive where Base: UIViewController {

var viewDidLoad: ControlEvent<Void> {
let source = self.methodInvoked(#selector(Base.viewDidLoad)).map( { _ in })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import UIKit

extension Optional where Wrapped == String {
public extension Optional where Wrapped == String {
/// ISO 8601 형식의 문자열을 `Date`로 변환하는 메서드
func toDate() -> Date? {
guard let self = self else { return nil } // 옵셔널 해제
Expand Down Expand Up @@ -41,7 +41,7 @@ extension String {
}
extension String {
/// ISO 8601 형식의 문자열을 `Date`로 변환하는 메서드
func toDate() -> Date? {
public func toDate() -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import UIKit

// UIImage를 색상으로 생성하는 Helper Extension
extension UIImage {
public extension UIImage {
convenience init(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
UIGraphicsBeginImageContext(size)
UIGraphicsGetCurrentContext()?.setFillColor(color.cgColor)
Expand All @@ -19,7 +19,7 @@ extension UIImage {
}
}

extension UIImage {
public extension UIImage {
func isBright(threshold: CGFloat = 0.5) -> Bool? {
guard let cgImage = self.cgImage else { return nil }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import UIKit

extension UIImageView {
public extension UIImageView {
func setPPImage(path: String?) {
guard let path = path else {
self.image = UIImage(named: "image_default")
return
}
let imageURLString = KeyPath.popPoolS3BaseURL + path
let imageURLString = Secrets.popPoolS3BaseURL + path
if let cenvertimageURL = imageURLString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
ImageLoader.shared.loadImage(with: cenvertimageURL, defaultImage: UIImage(named: "image_default"), imageQuality: .origin) { [weak self] image in
DispatchQueue.main.async {
Expand All @@ -22,7 +22,7 @@ extension UIImageView {
completion()
return
}
let imageURLString = KeyPath.popPoolS3BaseURL + path
let imageURLString = Secrets.popPoolS3BaseURL + path
if let cenvertimageURL = imageURLString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
let imageURL = URL(string: cenvertimageURL)
ImageLoader.shared.loadImage(with: cenvertimageURL, defaultImage: UIImage(named: "image_default"), imageQuality: .origin) { [weak self] image in
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
//
// Logger.swift
// MomsVillage
//
// Created by SeoJunYoung on 8/9/24.
//

import Foundation

struct Logger {
enum Level {
public struct Logger {
public enum Level {
case info
case debug
case network
Expand Down Expand Up @@ -55,12 +48,10 @@ struct Logger {
static var isShowLine: Bool = false
static var isShowLog: Bool = true

static private let noInputText = "Input is not found"

static func log(
public static func log(
message: Any,
category: Level,
fileName: String = noInputText,
fileName: String = "Input is not found",
line: Int? = nil
) {
if isShowLog {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import Foundation

enum KeyPath {
static var kakaoAuthAppKey: String {
public enum Secrets {
public static var kakaoAuthAppKey: String {
return getValue(forKey: "KAKAO_AUTH_APP_KEY")
}

static var popPoolBaseURL: String {
public static var popPoolBaseURL: String {
return getValue(forKey: "POPPOOL_BASE_URL")
}

static var popPoolS3BaseURL: String {
public static var popPoolS3BaseURL: String {
return getValue(forKey: "POPPOOL_S3_BASE_URL")
}

static var popPoolAPIKey: String {
public static var popPoolAPIKey: String {
return getValue(forKey: "POPPOOL_API_KEY")
}

static var naverMapClientID: String {
public static var naverMapClientID: String {
return getValue(forKey: "NAVER_MAP_CLIENT_ID")
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
//
// KeyChainService.swift
// MomsVillage
//
// Created by SeoJunYoung on 9/2/24.
//

import Foundation
import Security

import RxSwift

final class KeyChainService {
public final class KeyChainService {

// KeyChain에서 발생할 수 있는 오류를 정의
enum KeyChainError: Error {
Expand All @@ -22,10 +15,12 @@ final class KeyChainService {
// KeyChain 서비스 이름
private let service = "keyChain"

public init() { }

/// KeyChain에서 특정 타입의 토큰을 가져오는 메서드
/// - Parameter type: 가져오려는 토큰의 타입 (`accessToken` 또는 `refreshToken`)
/// - Returns: 가져온 토큰을 담은 `Single<String>`
func fetchToken(type: TokenType) -> Result<String, Error> {
public func fetchToken(type: TokenType) -> Result<String, Error> {
// 1. query 작성
let keyChainQuery: NSDictionary = [
kSecClass: kSecClassGenericPassword,
Expand Down Expand Up @@ -67,7 +62,7 @@ final class KeyChainService {
/// - Parameter type: 저장하려는 토큰의 타입 (`accessToken` 또는 `refreshToken`)
/// - Parameter value: 저장할 토큰의 값
/// - Returns: 완료 시 `Completable`
func saveToken(type: TokenType, value: String) -> Result<Void, Error> {
public func saveToken(type: TokenType, value: String) -> Result<Void, Error> {
// allowLossyConversion은 인코딩 과정에서 손실이 되는 것을 허용할 것인지 설정
guard let convertValue = value.data(using: .utf8, allowLossyConversion: false) else {
return .failure(KeyChainError.dataConversionError(message: "Failed to convert value to Data."))
Expand Down Expand Up @@ -103,7 +98,7 @@ final class KeyChainService {
/// KeyChain에서 특정 타입의 토큰을 삭제하는 메서드
/// - Parameter type: 삭제하려는 토큰의 타입 (`accessToken` 또는 `refreshToken`)
/// - Returns: 완료 시 `Completable`
func deleteToken(type: TokenType) -> Result<Void, Error> {
public func deleteToken(type: TokenType) -> Result<Void, Error> {
// 1. query 작성
let keyChainQuery: NSDictionary = [
kSecClass: kSecClassGenericPassword,
Expand All @@ -128,7 +123,7 @@ final class KeyChainService {
}
}

enum TokenType: String {
public enum TokenType: String {
case accessToken // 액세스 토큰
case refreshToken // 리프레시 토큰
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ import Foundation

import RxSwift

final class UserDefaultService {
public final class UserDefaultService {

public init() { }

/// Userdefault 데이터 저장 메서드
/// - Parameters:
/// - key: 저장하는 데이터의 키 값 i.e) 유저 id 등
/// - value: 저장하는 데이터 값 i.e) access token 등
/// - to: 로컬 데이터베이스 타입 - DatabaseType
/// - Returns: 별도 안내 없음
func save(key: String, value: String) {
public func save(key: String, value: String) {
UserDefaults.standard.set(value, forKey: key)
}

Expand All @@ -27,7 +29,7 @@ final class UserDefaultService {
/// - value: 저장하는 데이터 값 i.e) access token 등
/// - to: 로컬 데이터베이스 타입 - DatabaseType
/// - Returns: 별도 안내 없음
func save(key: String, value: [String]) {
public func save(key: String, value: [String]) {
UserDefaults.standard.set(value, forKey: key)
}

Expand All @@ -36,7 +38,7 @@ final class UserDefaultService {
/// - key: 찾는 데이터의 키 값 i.e) 유저 id 등
/// - from: 로컬 데이터베이스 타입 - DatabaseType
/// - Returns: 찾은 데이터 - String 타입
func fetch(key: String) -> String? {
public func fetch(key: String) -> String? {
if let token = UserDefaults.standard.string(forKey: key) {
return token
}
Expand All @@ -48,7 +50,7 @@ final class UserDefaultService {
/// - key: 찾는 데이터의 키 값 i.e) 유저 id 등
/// - from: 로컬 데이터베이스 타입 - DatabaseType
/// - Returns: 찾은 데이터 - String 타입
func fetchArray(key: String) -> [String]? {
public func fetchArray(key: String) -> [String]? {
if let token = UserDefaults.standard.array(forKey: key) as? [String] {
return token
}
Expand All @@ -60,7 +62,7 @@ final class UserDefaultService {
/// - key: 삭제하는 데이터의 키 값 i.e) 유저 id 등
/// - from: 로컬 데이터베이스 타입 - DatabaseType
/// - Returns: 별도 안내 없음
func delete(key: String) {
public func delete(key: String) {
UserDefaults.standard.removeObject(forKey: key)
}
}
Loading