diff --git a/RunLog/Project.swift b/RunLog/Project.swift deleted file mode 100644 index c56bbec..0000000 --- a/RunLog/Project.swift +++ /dev/null @@ -1,41 +0,0 @@ -import ProjectDescription - -let project = Project( - name: "RunLog", - organizationName: "ESTSOFTiOSTEAM1", - targets: [ - .target( - name: "RunLog", - destinations: [.iPhone], - product: .app, - bundleId: "com.ESTSOFTiOSTEAM1.IEEE.RunLog", - deploymentTargets: .iOS("17.0"), - infoPlist: .file(path: "RunLog/InfoPlists/RunLog-info.plist"), - sources: ["RunLog/Sources/**"], - resources: ["RunLog/Resources/**"], - dependencies: [ - .external(name: "SnapKit"), - .external(name: "Then"), - .external(name: "Moya"), - .external(name: "CombineMoya"), - .external(name: "NVActivityIndicatorView"), - .external(name: "NVActivityIndicatorViewExtended"), - ], - coreDataModels: [ - .coreDataModel("RunLog/Sources/Data/DTO/DTOs.xcdatamodeld") - ] - ), - .target( - name: "RpTest", - destinations: [.iPhone], - product: .unitTests, - bundleId: "com.ESTSOFTiOSTEAM1.IEEE.RpTest", - deploymentTargets: .iOS("17.0"), - infoPlist: .file(path: "RpTest/InfoPlists/RpTest-info.plist"), - sources: ["RpTest/Sources/**"], - dependencies: [ - .target(name: "RunLog") - ] - ) - ] -) diff --git a/RunLog/RunLog/InfoPlists/RunLog-Info.plist b/RunLog/Projects/App/InfoPlists/Info.plist similarity index 80% rename from RunLog/RunLog/InfoPlists/RunLog-Info.plist rename to RunLog/Projects/App/InfoPlists/Info.plist index af15092..0bc8451 100644 --- a/RunLog/RunLog/InfoPlists/RunLog-Info.plist +++ b/RunLog/Projects/App/InfoPlists/Info.plist @@ -6,6 +6,8 @@ $(API_KEY) CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + RunLog CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -41,20 +43,6 @@ Dark UIApplicationSupportsIndirectInputEvents - UIAppFonts - - NanumMyeongjo-Regular.ttf - RacingSansOne-Regular.ttf - Pretendard-Black.otf - Pretendard-Bold.otf - Pretendard-ExtraBold.otf - Pretendard-ExtraLight.otf - Pretendard-Light.otf - Pretendard-Medium.otf - Pretendard-Regular.otf - Pretendard-SemiBold.otf - Pretendard-Thin.otf - UIApplicationSceneManifest UIApplicationSupportsMultipleScenes @@ -92,12 +80,7 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UILaunchScreen - - UIColorName - - UIImageName - - + UILaunchStoryboardName + LaunchScreen \ No newline at end of file diff --git a/RunLog/Projects/App/Project.swift b/RunLog/Projects/App/Project.swift new file mode 100644 index 0000000..8e2b1c2 --- /dev/null +++ b/RunLog/Projects/App/Project.swift @@ -0,0 +1,16 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let project = Project.app( + name: Module.app.name, + organizationName: Module.organizationName, + infoPlist: .file(path: "InfoPlists/info.plist"), + dependencies: [ + Module.inject, + Module.domain, + Module.data, + Module.presentation, + Module.util, + ].map(\.project), + resources: .default +) diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AccentColor.colorset/Contents.json b/RunLog/Projects/App/Resources/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AccentColor.colorset/Contents.json rename to RunLog/Projects/App/Resources/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/1024.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/1024.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/1024.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/1024.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/114.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/114.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/114.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/114.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/120.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/120.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/120.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/120.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/180.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/180.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/180.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/180.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/29.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/29.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/29.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/29.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/40.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/40.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/40.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/40.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/57.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/57.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/57.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/57.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/58.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/58.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/58.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/58.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/60.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/60.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/60.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/60.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/80.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/80.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/80.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/80.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/87.png b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/87.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/87.png rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/87.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json rename to RunLog/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Contents.json b/RunLog/Projects/App/Resources/Assets.xcassets/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Contents.json rename to RunLog/Projects/App/Resources/Assets.xcassets/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Splash/Contents.json b/RunLog/Projects/App/Resources/Assets.xcassets/Splash/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Splash/Contents.json rename to RunLog/Projects/App/Resources/Assets.xcassets/Splash/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Splash/ScreenBackground.colorset/Contents.json b/RunLog/Projects/App/Resources/Assets.xcassets/Splash/ScreenBackground.colorset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Splash/ScreenBackground.colorset/Contents.json rename to RunLog/Projects/App/Resources/Assets.xcassets/Splash/ScreenBackground.colorset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Splash/splashImage.imageset/Contents.json b/RunLog/Projects/App/Resources/Assets.xcassets/Splash/splashImage.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Splash/splashImage.imageset/Contents.json rename to RunLog/Projects/App/Resources/Assets.xcassets/Splash/splashImage.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Splash/splashImage.imageset/splashImage.png b/RunLog/Projects/App/Resources/Assets.xcassets/Splash/splashImage.imageset/splashImage.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Splash/splashImage.imageset/splashImage.png rename to RunLog/Projects/App/Resources/Assets.xcassets/Splash/splashImage.imageset/splashImage.png diff --git a/RunLog/RunLog/Sources/App/Launch Screen.storyboard b/RunLog/Projects/App/Resources/LaunchScreen.storyboard similarity index 100% rename from RunLog/RunLog/Sources/App/Launch Screen.storyboard rename to RunLog/Projects/App/Resources/LaunchScreen.storyboard diff --git a/RunLog/RunLog/Sources/App/AppDelegate.swift b/RunLog/Projects/App/Sources/AppDelegate.swift similarity index 96% rename from RunLog/RunLog/Sources/App/AppDelegate.swift rename to RunLog/Projects/App/Sources/AppDelegate.swift index dd4e6b7..baf048f 100644 --- a/RunLog/RunLog/Sources/App/AppDelegate.swift +++ b/RunLog/Projects/App/Sources/AppDelegate.swift @@ -4,6 +4,9 @@ // // Created by 김도연 on 3/13/25. // +import RLDomain +import RLData +import RLInject import UIKit @@ -13,7 +16,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. registerDependencies() - + UIFont.registerFonts() return true } diff --git a/RunLog/RunLog/Sources/App/SceneDelegate.swift b/RunLog/Projects/App/Sources/SceneDelegate.swift similarity index 98% rename from RunLog/RunLog/Sources/App/SceneDelegate.swift rename to RunLog/Projects/App/Sources/SceneDelegate.swift index dda3825..6ff1393 100644 --- a/RunLog/RunLog/Sources/App/SceneDelegate.swift +++ b/RunLog/Projects/App/Sources/SceneDelegate.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/13/25. // +import RLPresentation +import RLUtil import UIKit diff --git a/RunLog/RpTest/InfoPlists/RpTest-Info.plist b/RunLog/Projects/App/Tests/InfoPlists/RpTest-Info.plist similarity index 100% rename from RunLog/RpTest/InfoPlists/RpTest-Info.plist rename to RunLog/Projects/App/Tests/InfoPlists/RpTest-Info.plist diff --git a/RunLog/RpTest/Sources/DayLogUseCaseTest.swift b/RunLog/Projects/App/Tests/Sources/DayLogUseCaseTest.swift similarity index 100% rename from RunLog/RpTest/Sources/DayLogUseCaseTest.swift rename to RunLog/Projects/App/Tests/Sources/DayLogUseCaseTest.swift diff --git a/RunLog/RpTest/Sources/DoubleTest.swift b/RunLog/Projects/App/Tests/Sources/DoubleTest.swift similarity index 100% rename from RunLog/RpTest/Sources/DoubleTest.swift rename to RunLog/Projects/App/Tests/Sources/DoubleTest.swift diff --git a/RunLog/RpTest/Sources/MediaUseCaseTests.swift b/RunLog/Projects/App/Tests/Sources/MediaUseCaseTests.swift similarity index 100% rename from RunLog/RpTest/Sources/MediaUseCaseTests.swift rename to RunLog/Projects/App/Tests/Sources/MediaUseCaseTests.swift diff --git a/RunLog/RpTest/Sources/RpTest.swift b/RunLog/Projects/App/Tests/Sources/RpTest.swift similarity index 100% rename from RunLog/RpTest/Sources/RpTest.swift rename to RunLog/Projects/App/Tests/Sources/RpTest.swift diff --git a/RunLog/RpTest/Sources/TestCoreDataContainer.swift b/RunLog/Projects/App/Tests/Sources/TestCoreDataContainer.swift similarity index 100% rename from RunLog/RpTest/Sources/TestCoreDataContainer.swift rename to RunLog/Projects/App/Tests/Sources/TestCoreDataContainer.swift diff --git a/RunLog/Projects/Data/Project.swift b/RunLog/Projects/Data/Project.swift new file mode 100644 index 0000000..0268789 --- /dev/null +++ b/RunLog/Projects/Data/Project.swift @@ -0,0 +1,18 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let project = Project.framework( + name: Module.data.name, + organizationName: Module.organizationName, + infoPlist: .default, + dependencies: [ + Module.inject.project, + Module.domain.project, + Module.util.project, + .external(name: "Moya"), + .external(name: "CombineMoya"), + ], + coreDataModels: [ + .coreDataModel("Sources/DTOs/DTOs.xcdatamodeld") + ] +) diff --git a/RunLog/RunLog/Sources/Data/DTO/DTOs.xcdatamodeld/DTOs.xcdatamodel/contents b/RunLog/Projects/Data/Sources/DTOs/DTOs.xcdatamodeld/DTOs.xcdatamodel/contents similarity index 100% rename from RunLog/RunLog/Sources/Data/DTO/DTOs.xcdatamodeld/DTOs.xcdatamodel/contents rename to RunLog/Projects/Data/Sources/DTOs/DTOs.xcdatamodeld/DTOs.xcdatamodel/contents diff --git a/RunLog/RunLog/Sources/Data/DTO/DataMapper.swift b/RunLog/Projects/Data/Sources/DTOs/DataMapper.swift similarity index 99% rename from RunLog/RunLog/Sources/Data/DTO/DataMapper.swift rename to RunLog/Projects/Data/Sources/DTOs/DataMapper.swift index 989d1d3..74e8677 100644 --- a/RunLog/RunLog/Sources/Data/DTO/DataMapper.swift +++ b/RunLog/Projects/Data/Sources/DTOs/DataMapper.swift @@ -4,6 +4,7 @@ // // Created by 신승재 on 3/18/25. // +import RLDomain import Foundation import CoreData diff --git a/RunLog/Projects/Data/Sources/DataContainer/CoreDataContainer.swift b/RunLog/Projects/Data/Sources/DataContainer/CoreDataContainer.swift new file mode 100644 index 0000000..8e9686b --- /dev/null +++ b/RunLog/Projects/Data/Sources/DataContainer/CoreDataContainer.swift @@ -0,0 +1,33 @@ +// +// CoreDataContainer.swift +// RunLog +// +// Created by 신승재 on 3/20/25. +// + +import CoreData + +public final class CoreDataContainer { + + public init() {} + + lazy var persistentContainer: NSPersistentContainer = { + guard let modelURL = Bundle.module.url(forResource: "DTOs", withExtension: "momd"), + let model = NSManagedObjectModel(contentsOf: modelURL) else { + fatalError("Failed to load Core Data model named DTOs") + } + + let container = NSPersistentContainer(name: "DTOs", managedObjectModel: model) + container.loadPersistentStores { _, error in + if let error = error as NSError? { + fatalError("Unresolved Core Data error: \(error), \(error.userInfo)") + } + } + return container + }() + + public var context: NSManagedObjectContext { + return persistentContainer.viewContext + } + +} diff --git a/RunLog/RunLog/Sources/Data/Impl/AppConfigRepositoryImpl.swift b/RunLog/Projects/Data/Sources/Impls/AppConfigRepositoryImpl.swift similarity index 90% rename from RunLog/RunLog/Sources/Data/Impl/AppConfigRepositoryImpl.swift rename to RunLog/Projects/Data/Sources/Impls/AppConfigRepositoryImpl.swift index 7ecf3a8..928c3cc 100644 --- a/RunLog/RunLog/Sources/Data/Impl/AppConfigRepositoryImpl.swift +++ b/RunLog/Projects/Data/Sources/Impls/AppConfigRepositoryImpl.swift @@ -4,18 +4,19 @@ // // Created by 김도연 on 3/19/25. // +import RLDomain import Foundation import CoreData -final class AppConfigRepositoryImpl: AppConfigRepository { +public final class AppConfigRepositoryImpl: AppConfigRepository { private let context: NSManagedObjectContext - init(context: NSManagedObjectContext) { + public init(context: NSManagedObjectContext) { self.context = context } - func createAppConfig(_ config: AppConfig) async throws { + public func createAppConfig(_ config: AppConfig) async throws { // print("Impl: ", #function) try await context.perform { [weak self] in @@ -41,7 +42,7 @@ final class AppConfigRepositoryImpl: AppConfigRepository { } } - func readAppConfig() async throws -> AppConfig { + public func readAppConfig() async throws -> AppConfig { // print("Impl: ", #function) return try await context.perform { [weak self] in @@ -65,7 +66,7 @@ final class AppConfigRepositoryImpl: AppConfigRepository { } - func updateAppConfig(_ config: AppConfig) async throws { + public func updateAppConfig(_ config: AppConfig) async throws { // print("Impl: ", #function) return try await context.perform { [weak self] in @@ -96,7 +97,7 @@ final class AppConfigRepositoryImpl: AppConfigRepository { } } - func deleteAppConfig() async throws { + public func deleteAppConfig() async throws { // print("Impl: ", #function) return try await context.perform { [weak self] in diff --git a/RunLog/RunLog/Sources/Data/Impl/DayLogRepositoryImpl.swift b/RunLog/Projects/Data/Sources/Impls/DayLogRepositoryImpl.swift similarity index 82% rename from RunLog/RunLog/Sources/Data/Impl/DayLogRepositoryImpl.swift rename to RunLog/Projects/Data/Sources/Impls/DayLogRepositoryImpl.swift index f2b554e..2be3803 100644 --- a/RunLog/RunLog/Sources/Data/Impl/DayLogRepositoryImpl.swift +++ b/RunLog/Projects/Data/Sources/Impls/DayLogRepositoryImpl.swift @@ -4,20 +4,20 @@ // // Created by 신승재 on 3/18/25. // - +import RLDomain import Foundation import CoreData -final class DayLogRepositoryImpl: DayLogRepository { +public final class DayLogRepositoryImpl: DayLogRepository { private let context: NSManagedObjectContext - init(context: NSManagedObjectContext) { + public init(context: NSManagedObjectContext) { self.context = context } - func createDayLog(_ dayLog: DayLog) async throws { + public func createDayLog(_ dayLog: DayLog) async throws { print("Impl: ", #function) try await context.perform { @@ -29,7 +29,7 @@ final class DayLogRepositoryImpl: DayLogRepository { let existing = try self.context.fetch(fetchRequest) if !existing.isEmpty { - throw CoreDataError.modelAlreadyExist + throw DataError.modelAlreadyExist } let data = DataMapper.toDTO(dayLog, context: self.context) @@ -38,7 +38,7 @@ final class DayLogRepositoryImpl: DayLogRepository { } } - func readDayLog(date: Date) async throws -> DayLog { + public func readDayLog(date: Date) async throws -> DayLog { print("Impl: ", #function) return try await context.perform { @@ -49,17 +49,17 @@ final class DayLogRepositoryImpl: DayLogRepository { ) guard let data = try self.context.fetch(fetchRequest).first else { - throw CoreDataError.modelNotFound + throw DataError.modelNotFound } guard let model = DataMapper.toEntity(data) else { - throw CoreDataError.conversionError + throw DataError.conversionError } return model } } - func readAllDayLogs() async throws -> [DayLog] { + public func readAllDayLogs() async throws -> [DayLog] { print("Impl: ", #function) return try await context.perform { @@ -72,7 +72,7 @@ final class DayLogRepositoryImpl: DayLogRepository { } } - func updateDayLog(_ dayLog: DayLog) async throws { + public func updateDayLog(_ dayLog: DayLog) async throws { print("Impl: ", #function) try await context.perform { @@ -83,7 +83,7 @@ final class DayLogRepositoryImpl: DayLogRepository { ) guard let data = try self.context.fetch(fetchRequest).first else { - throw CoreDataError.modelNotFound + throw DataError.modelNotFound } data.trackImage = dayLog.trackImage @@ -100,7 +100,7 @@ final class DayLogRepositoryImpl: DayLogRepository { } } - func deleteDayLog(date: Date) async throws { + public func deleteDayLog(date: Date) async throws { print("Impl: ", #function) try await context.perform { @@ -111,7 +111,7 @@ final class DayLogRepositoryImpl: DayLogRepository { ) guard let data = try self.context.fetch(fetchRequest).first else { - throw CoreDataError.modelNotFound + throw DataError.modelNotFound } self.context.delete(data) diff --git a/RunLog/RunLog/Sources/Data/DistanceManager.swift b/RunLog/Projects/Data/Sources/Managers/DistanceManager.swift similarity index 84% rename from RunLog/RunLog/Sources/Data/DistanceManager.swift rename to RunLog/Projects/Data/Sources/Managers/DistanceManager.swift index 4c5eb4a..9ac447e 100644 --- a/RunLog/RunLog/Sources/Data/DistanceManager.swift +++ b/RunLog/Projects/Data/Sources/Managers/DistanceManager.swift @@ -11,26 +11,26 @@ import CoreLocation /// 사용자가 움직인 거리를 측정하는 매니저 -final class DistanceManager { +public final class DistanceManager { // MARK: - Singleton - static let shared = DistanceManager() + public static let shared = DistanceManager() private init() { bind() } // MARK: - Input - enum Input { + public enum Input { case requestDistance(previous: CLLocation, current: CLLocation) } - let input = PassthroughSubject() + public let input = PassthroughSubject() // MARK: - Output - enum Output { + public enum Output { case responseDistance(Double) } - let output = PassthroughSubject() + public let output = PassthroughSubject() // MARK: - Properties private var cancellables = Set() diff --git a/RunLog/RunLog/Sources/Data/DrawingManager.swift b/RunLog/Projects/Data/Sources/Managers/DrawingManager.swift similarity index 86% rename from RunLog/RunLog/Sources/Data/DrawingManager.swift rename to RunLog/Projects/Data/Sources/Managers/DrawingManager.swift index 6b50f68..418daed 100644 --- a/RunLog/RunLog/Sources/Data/DrawingManager.swift +++ b/RunLog/Projects/Data/Sources/Managers/DrawingManager.swift @@ -9,27 +9,27 @@ import Foundation import MapKit import Combine -final class DrawingManager: NSObject, MKMapViewDelegate { +public final class DrawingManager: NSObject, MKMapViewDelegate { // MARK: - Singleton - static let shared = DrawingManager() + public static let shared = DrawingManager() private override init() { super.init() bind() } // MARK: - Input - enum Input { + public enum Input { case requestLine(CLLocation, CLLocation) // 단일 경로 - 운동중 화면 case requestFullRoutePolyline([CLLocation]) // 전체 경로 - 섹션 종료 후 사진 새로 만들때 } - let input = PassthroughSubject() + public let input = PassthroughSubject() // MARK: - Output - enum Output { + public enum Output { case responsePolyline(MKPolyline) } - let output = PassthroughSubject() + public let output = PassthroughSubject() // MARK: - Properties private var cancellables = Set() @@ -68,7 +68,7 @@ final class DrawingManager: NSObject, MKMapViewDelegate { } // MARK: - 폴리라인 스타일 적용 - func mapView(_ mapView: MKMapView, rendererFor overlay: any MKOverlay) -> MKOverlayRenderer { + public func mapView(_ mapView: MKMapView, rendererFor overlay: any MKOverlay) -> MKOverlayRenderer { guard let polyline = overlay as? MKPolyline else { return MKOverlayRenderer() } diff --git a/RunLog/RunLog/Sources/Data/LocationManager.swift b/RunLog/Projects/Data/Sources/Managers/LocationManager.swift similarity index 93% rename from RunLog/RunLog/Sources/Data/LocationManager.swift rename to RunLog/Projects/Data/Sources/Managers/LocationManager.swift index 348878c..951c9e0 100644 --- a/RunLog/RunLog/Sources/Data/LocationManager.swift +++ b/RunLog/Projects/Data/Sources/Managers/LocationManager.swift @@ -11,10 +11,10 @@ import CoreLocation import Combine /// 사용자의 위치 정보를 받아오는 매니저 -final class LocationManager: NSObject, CLLocationManagerDelegate { +public final class LocationManager: NSObject, CLLocationManagerDelegate { // MARK: - Singleton - static let shared = LocationManager() + public static let shared = LocationManager() private override init() { super.init() setupLocationManager() @@ -27,18 +27,18 @@ final class LocationManager: NSObject, CLLocationManagerDelegate { // MARK: - Input - enum Input { + public enum Input { case requestCurrentLocation case requestCityName(CLLocation) // 도시이름을 요청 } - let input = PassthroughSubject() + public let input = PassthroughSubject() // MARK: - Output - enum Output { + public enum Output { case locationUpdate(CLLocation) // 현재위치(CLLocatio)를 제공 case responseCityName(CLPlacemark) // 도시이름(String)을 제공 } - let output = PassthroughSubject() + public let output = PassthroughSubject() // MARK: - Properties private var cancellables = Set() @@ -82,7 +82,7 @@ final class LocationManager: NSObject, CLLocationManagerDelegate { extension LocationManager { /// 사용자의 위치를 받아오는 Delegate 함수 - func locationManager( + public func locationManager( _ manager: CLLocationManager, didUpdateLocations locations: [CLLocation] ) { @@ -130,7 +130,7 @@ extension LocationManager { extension LocationManager { // MARK: - 권한 정보가 바뀌면 실행 - func locationManager( + public func locationManager( _ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus ) { diff --git a/RunLog/RunLog/Sources/Data/PedometerManager.swift b/RunLog/Projects/Data/Sources/Managers/PedometerManager.swift similarity index 88% rename from RunLog/RunLog/Sources/Data/PedometerManager.swift rename to RunLog/Projects/Data/Sources/Managers/PedometerManager.swift index d1e9fdd..6a102dc 100644 --- a/RunLog/RunLog/Sources/Data/PedometerManager.swift +++ b/RunLog/Projects/Data/Sources/Managers/PedometerManager.swift @@ -10,27 +10,27 @@ import Combine import CoreMotion /// 사용자가 걸은 걸음수를 받아오는 매니저 -final class PedometerManager { +public final class PedometerManager { // MARK: - Singleton - static let shared = PedometerManager() + public static let shared = PedometerManager() private init() { bind() } // MARK: - Input - enum Input { + public enum Input { case requestPedometerStart case requestPedometerStop } - let input = PassthroughSubject() + public let input = PassthroughSubject() // MARK: - Output - enum Output { + public enum Output { case responseSteps(Int) } - let output = PassthroughSubject() + public let output = PassthroughSubject() // MARK: - Properties private var cancellables = Set() diff --git a/RunLog/RunLog/Sources/Data/Network/API.swift b/RunLog/Projects/Data/Sources/Network/API.swift similarity index 100% rename from RunLog/RunLog/Sources/Data/Network/API.swift rename to RunLog/Projects/Data/Sources/Network/API.swift diff --git a/RunLog/RunLog/Sources/Data/Network/Error.swift b/RunLog/Projects/Data/Sources/Network/Error.swift similarity index 100% rename from RunLog/RunLog/Sources/Data/Network/Error.swift rename to RunLog/Projects/Data/Sources/Network/Error.swift diff --git a/RunLog/RunLog/Sources/Data/Network/NetworkProtocol.swift b/RunLog/Projects/Data/Sources/Network/NetworkProtocol.swift similarity index 100% rename from RunLog/RunLog/Sources/Data/Network/NetworkProtocol.swift rename to RunLog/Projects/Data/Sources/Network/NetworkProtocol.swift diff --git a/RunLog/RunLog/Sources/Data/Network/OpenWeather/OpenWeatherEndpoint.swift b/RunLog/Projects/Data/Sources/Network/OpenWeather/OpenWeatherEndpoint.swift similarity index 100% rename from RunLog/RunLog/Sources/Data/Network/OpenWeather/OpenWeatherEndpoint.swift rename to RunLog/Projects/Data/Sources/Network/OpenWeather/OpenWeatherEndpoint.swift diff --git a/RunLog/RunLog/Sources/Data/Network/OpenWeather/OpenWeatherModel.swift b/RunLog/Projects/Data/Sources/Network/OpenWeather/OpenWeatherModel.swift similarity index 100% rename from RunLog/RunLog/Sources/Data/Network/OpenWeather/OpenWeatherModel.swift rename to RunLog/Projects/Data/Sources/Network/OpenWeather/OpenWeatherModel.swift diff --git a/RunLog/RunLog/Sources/Data/Network/OpenWeather/OpenWeatherService.swift b/RunLog/Projects/Data/Sources/Network/OpenWeather/OpenWeatherService.swift similarity index 93% rename from RunLog/RunLog/Sources/Data/Network/OpenWeather/OpenWeatherService.swift rename to RunLog/Projects/Data/Sources/Network/OpenWeather/OpenWeatherService.swift index e29dd20..f6de4f6 100644 --- a/RunLog/RunLog/Sources/Data/Network/OpenWeather/OpenWeatherService.swift +++ b/RunLog/Projects/Data/Sources/Network/OpenWeather/OpenWeatherService.swift @@ -12,26 +12,26 @@ import CombineMoya import MapKit // MARK: - API 요청을 담당 -final class OpenWeatherService: NetworkService { +public final class OpenWeatherService: NetworkService { // MARK: - Singleton - static let shared = OpenWeatherService() + public static let shared = OpenWeatherService() private init() { bind() } // MARK: - Input & Output - enum Input { + public enum Input { case requestWeather(CLLocation) } - let input = PassthroughSubject() + public let input = PassthroughSubject() // MARK: - Output - enum Output { + public enum Output { case responseWeather(weather: (Int, Double), aqi: Int) // 날씨컨디션, 기온을 제공 } - let output = PassthroughSubject() + public let output = PassthroughSubject() // MARK: - Properties private var cancellables = Set() diff --git a/RunLog/RunLog/Sources/Presentation/Common/Coordinator/.gitkeep b/RunLog/Projects/Data/Tests/.gitkeep similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Common/Coordinator/.gitkeep rename to RunLog/Projects/Data/Tests/.gitkeep diff --git a/RunLog/Projects/DesignSystem/InfoPlists/Info.plist b/RunLog/Projects/DesignSystem/InfoPlists/Info.plist new file mode 100644 index 0000000..05b2611 --- /dev/null +++ b/RunLog/Projects/DesignSystem/InfoPlists/Info.plist @@ -0,0 +1,36 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + UIAppFonts + + NanumMyeongjo-Regular.ttf + RacingSansOne-Regular.ttf + Pretendard-Black.otf + Pretendard-Bold.otf + Pretendard-ExtraBold.otf + Pretendard-ExtraLight.otf + Pretendard-Light.otf + Pretendard-Medium.otf + Pretendard-Regular.otf + Pretendard-SemiBold.otf + Pretendard-Thin.otf + + + diff --git a/RunLog/Projects/DesignSystem/Project.swift b/RunLog/Projects/DesignSystem/Project.swift new file mode 100644 index 0000000..7282c59 --- /dev/null +++ b/RunLog/Projects/DesignSystem/Project.swift @@ -0,0 +1,15 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let project = Project.framework( + name: Module.designSystem.name, + organizationName: Module.organizationName, + infoPlist: .file(path: "InfoPlists/info.plist"), + dependencies: [ + Module.util.project, + .external(name: "SnapKit"), + .external(name: "Then"), + .external(name: "NVActivityIndicatorView"), + ], + resources: .default +) diff --git a/RunLog/RunLog/Resources/Fonts/NanumMyeongjo-Regular.ttf b/RunLog/Projects/DesignSystem/Resources/Fonts/NanumMyeongjo-Regular.ttf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/NanumMyeongjo-Regular.ttf rename to RunLog/Projects/DesignSystem/Resources/Fonts/NanumMyeongjo-Regular.ttf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-Black.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Black.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-Black.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Black.otf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-Bold.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Bold.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-Bold.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Bold.otf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-ExtraBold.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-ExtraBold.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-ExtraBold.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-ExtraBold.otf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-ExtraLight.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-ExtraLight.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-ExtraLight.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-ExtraLight.otf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-Light.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Light.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-Light.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Light.otf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-Medium.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Medium.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-Medium.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Medium.otf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-Regular.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Regular.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-Regular.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Regular.otf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-SemiBold.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-SemiBold.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-SemiBold.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-SemiBold.otf diff --git a/RunLog/RunLog/Resources/Fonts/Pretendard-Thin.otf b/RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Thin.otf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/Pretendard-Thin.otf rename to RunLog/Projects/DesignSystem/Resources/Fonts/Pretendard-Thin.otf diff --git a/RunLog/RunLog/Resources/Fonts/RacingSansOne-Regular.ttf b/RunLog/Projects/DesignSystem/Resources/Fonts/RacingSansOne-Regular.ttf similarity index 100% rename from RunLog/RunLog/Resources/Fonts/RacingSansOne-Regular.ttf rename to RunLog/Projects/DesignSystem/Resources/Fonts/RacingSansOne-Regular.ttf diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Church.imageset/Church.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Church.imageset/Church.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Church.imageset/Church.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Church.imageset/Church.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Church.imageset/Church@2x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Church.imageset/Church@2x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Church.imageset/Church@2x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Church.imageset/Church@2x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Church.imageset/Church@3x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Church.imageset/Church@3x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Church.imageset/Church@3x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Church.imageset/Church@3x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Church.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Church.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Church.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Church.imageset/Contents.json diff --git a/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Earth.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Earth.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Earth.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Earth.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Earth.imageset/Earth.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Earth.imageset/Earth.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Earth.imageset/Earth.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Earth.imageset/Earth.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Earth.imageset/Earth@2x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Earth.imageset/Earth@2x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Earth.imageset/Earth@2x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Earth.imageset/Earth@2x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Earth.imageset/Earth@3x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Earth.imageset/Earth@3x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Earth.imageset/Earth@3x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Earth.imageset/Earth@3x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Flag.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Flag.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Flag.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Flag.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Flag.imageset/Flag.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Flag.imageset/Flag.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Flag.imageset/Flag.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Flag.imageset/Flag.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Flag.imageset/Flag@2x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Flag.imageset/Flag@2x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Flag.imageset/Flag@2x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Flag.imageset/Flag@2x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Flag.imageset/Flag@3x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Flag.imageset/Flag@3x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Flag.imageset/Flag@3x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Flag.imageset/Flag@3x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Korea.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Korea.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Korea.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Korea.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Korea.imageset/Korea.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Korea.imageset/Korea.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Korea.imageset/Korea.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Korea.imageset/Korea.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Korea.imageset/Korea@2x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Korea.imageset/Korea@2x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Korea.imageset/Korea@2x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Korea.imageset/Korea@2x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Korea.imageset/Korea@3x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Korea.imageset/Korea@3x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Korea.imageset/Korea@3x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Korea.imageset/Korea@3x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Mandarin.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Mandarin.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Mandarin.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Mandarin.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Mandarin.imageset/Mandarin.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Mandarin.imageset/Mandarin.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Mandarin.imageset/Mandarin.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Mandarin.imageset/Mandarin.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Mandarin.imageset/Mandarin@2x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Mandarin.imageset/Mandarin@2x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Mandarin.imageset/Mandarin@2x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Mandarin.imageset/Mandarin@2x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Mandarin.imageset/Mandarin@3x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Mandarin.imageset/Mandarin@3x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Mandarin.imageset/Mandarin@3x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Mandarin.imageset/Mandarin@3x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Medal.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Medal.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Medal.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Medal.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Medal.imageset/Medal.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Medal.imageset/Medal.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Medal.imageset/Medal.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Medal.imageset/Medal.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Medal.imageset/Medal@2x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Medal.imageset/Medal@2x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Medal.imageset/Medal@2x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Medal.imageset/Medal@2x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Medal.imageset/Medal@3x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Medal.imageset/Medal@3x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Medal.imageset/Medal@3x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Medal.imageset/Medal@3x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Rocket.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Rocket.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Rocket.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Rocket.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Rocket.imageset/Rocket.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Rocket.imageset/Rocket.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Rocket.imageset/Rocket.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Rocket.imageset/Rocket.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Rocket.imageset/Rocket@2x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Rocket.imageset/Rocket@2x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Rocket.imageset/Rocket@2x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Rocket.imageset/Rocket@2x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/Rocket.imageset/Rocket@3x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/Rocket.imageset/Rocket@3x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/Rocket.imageset/Rocket@3x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/Rocket.imageset/Rocket@3x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/UnitExample.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/UnitExample.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/UnitExample.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/UnitExample.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/UnitExample.imageset/Frame 2087327598.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/UnitExample.imageset/Frame 2087327598.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/UnitExample.imageset/Frame 2087327598.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/UnitExample.imageset/Frame 2087327598.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/UnitExample.imageset/Frame 2087327598@2x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/UnitExample.imageset/Frame 2087327598@2x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/UnitExample.imageset/Frame 2087327598@2x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/UnitExample.imageset/Frame 2087327598@2x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/UnitExample.imageset/Frame 2087327598@3x.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/UnitExample.imageset/Frame 2087327598@3x.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/UnitExample.imageset/Frame 2087327598@3x.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/UnitExample.imageset/Frame 2087327598@3x.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/noneBeat.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/noneBeat.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/noneBeat.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/noneBeat.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/noneBeat.imageset/noneBeat.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/noneBeat.imageset/noneBeat.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/noneBeat.imageset/noneBeat.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/noneBeat.imageset/noneBeat.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/oneBeat.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/oneBeat.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/oneBeat.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/oneBeat.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/oneBeat.imageset/oneBeat.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/oneBeat.imageset/oneBeat.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/oneBeat.imageset/oneBeat.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/oneBeat.imageset/oneBeat.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/threeBeats.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/threeBeats.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/threeBeats.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/threeBeats.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/threeBeats.imageset/threeBeats.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/threeBeats.imageset/threeBeats.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/threeBeats.imageset/threeBeats.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/threeBeats.imageset/threeBeats.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/twoBeats.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/twoBeats.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/twoBeats.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/twoBeats.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/twoBeats.imageset/twoBeats.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/twoBeats.imageset/twoBeats.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/twoBeats.imageset/twoBeats.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/twoBeats.imageset/twoBeats.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/walkDog.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkDog.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/walkDog.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkDog.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/walkDog.imageset/walkDog.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkDog.imageset/walkDog.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/walkDog.imageset/walkDog.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkDog.imageset/walkDog.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/walkGirl.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkGirl.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/walkGirl.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkGirl.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/walkGirl.imageset/walkGirl.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkGirl.imageset/walkGirl.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/walkGirl.imageset/walkGirl.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkGirl.imageset/walkGirl.png diff --git a/RunLog/RunLog/Resources/Assets.xcassets/walkMan.imageset/Contents.json b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkMan.imageset/Contents.json similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/walkMan.imageset/Contents.json rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkMan.imageset/Contents.json diff --git a/RunLog/RunLog/Resources/Assets.xcassets/walkMan.imageset/walkMan.png b/RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkMan.imageset/walkMan.png similarity index 100% rename from RunLog/RunLog/Resources/Assets.xcassets/walkMan.imageset/walkMan.png rename to RunLog/Projects/DesignSystem/Resources/Images.xcassets/walkMan.imageset/walkMan.png diff --git a/RunLog/RunLog/Sources/DesignSystem/ButtonSystem.swift b/RunLog/Projects/DesignSystem/Sources/ButtonSystem.swift similarity index 99% rename from RunLog/RunLog/Sources/DesignSystem/ButtonSystem.swift rename to RunLog/Projects/DesignSystem/Sources/ButtonSystem.swift index d5b5eeb..a0ce20c 100644 --- a/RunLog/RunLog/Sources/DesignSystem/ButtonSystem.swift +++ b/RunLog/Projects/DesignSystem/Sources/ButtonSystem.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/14/25. // +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/DesignSystem/ColorSystem.swift b/RunLog/Projects/DesignSystem/Sources/ColorSystem.swift similarity index 99% rename from RunLog/RunLog/Sources/DesignSystem/ColorSystem.swift rename to RunLog/Projects/DesignSystem/Sources/ColorSystem.swift index 383d9e1..949ecaf 100644 --- a/RunLog/RunLog/Sources/DesignSystem/ColorSystem.swift +++ b/RunLog/Projects/DesignSystem/Sources/ColorSystem.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/14/25. // +import RLUtil import UIKit diff --git a/RunLog/RunLog/Sources/DesignSystem/FontSystem.swift b/RunLog/Projects/DesignSystem/Sources/FontSystem.swift similarity index 60% rename from RunLog/RunLog/Sources/DesignSystem/FontSystem.swift rename to RunLog/Projects/DesignSystem/Sources/FontSystem.swift index af67ee7..c57d043 100644 --- a/RunLog/RunLog/Sources/DesignSystem/FontSystem.swift +++ b/RunLog/Projects/DesignSystem/Sources/FontSystem.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/14/25. // +import RLUtil + import UIKit public enum RLFont { @@ -32,7 +34,7 @@ public enum RLFont { } extension RLFont { - var value: UIFont { + public var value: UIFont { switch self { case .Logo1: return .RLLogo1 @@ -70,7 +72,7 @@ extension RLFont { return .RLSegment2 } } - var lineHeightMultiple: CGFloat { + public var lineHeightMultiple: CGFloat { switch self { case .Logo1, .Logo2: return 1.10 @@ -93,16 +95,16 @@ extension RLFont { extension UIFont { // MARK: - Font Style - public enum RacingSansOne: String { + public enum RacingSansOne: String, CaseIterable { case regular = "RacingSansOne-Regular" } - public enum NanumMyeongjo: String { + public enum NanumMyeongjo: String, CaseIterable { case regular = "NanumMyeongjo-Regular" } // TODO: Pretendard로 네이밍 변경 - public enum RLFont: String { + public enum Pretendard: String, CaseIterable { case black = "Pretendard-Black" case bold = "Pretendard-Bold" case extraBold = "Pretendard-ExtraBold" @@ -145,54 +147,93 @@ extension UIFont { // MARK: - Heading public static var RLHeading1: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 22, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 22, weight: .semibold) } public static var RLHeading2: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 20, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 20, weight: .semibold) } public static var RLHeading4: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 36, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 36, weight: .semibold) } // MARK: - Headline public static var RLHeadline1: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 18, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 18, weight: .semibold) } public static var RLHeadline2: UIFont { - dynamicFont(name: RLFont.regular.rawValue, baseSize: 18, weight: .regular) + dynamicFont(name: Pretendard.regular.rawValue, baseSize: 18, weight: .regular) } public static var RLHeadline3: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 18, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 18, weight: .semibold) } // MARK: - Title public static var RLTitle: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 24, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 24, weight: .semibold) } public static var RLMainTitle: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 26, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 26, weight: .semibold) } public static var RLDetailTitle: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 32, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 32, weight: .semibold) } // MARK: - etc public static var RLBody1: UIFont { - dynamicFont(name: RLFont.regular.rawValue, baseSize: 16, weight: .regular) + dynamicFont(name: Pretendard.regular.rawValue, baseSize: 16, weight: .regular) } public static var RLLabel1: UIFont { - dynamicFont(name: RLFont.bold.rawValue, baseSize: 14, weight: .bold) + dynamicFont(name: Pretendard.bold.rawValue, baseSize: 14, weight: .bold) } public static var RLLabel2: UIFont { - dynamicFont(name: RLFont.regular.rawValue, baseSize: 14, weight: .regular) + dynamicFont(name: Pretendard.regular.rawValue, baseSize: 14, weight: .regular) } public static var RLButton: UIFont { - dynamicFont(name: RLFont.medium.rawValue, baseSize: 24, weight: .medium) + dynamicFont(name: Pretendard.medium.rawValue, baseSize: 24, weight: .medium) } public static var RLSegment1: UIFont { - dynamicFont(name: RLFont.semiBold.rawValue, baseSize: 16, weight: .semibold) + dynamicFont(name: Pretendard.semiBold.rawValue, baseSize: 16, weight: .semibold) } public static var RLSegment2: UIFont { - dynamicFont(name: RLFont.medium.rawValue, baseSize: 16, weight: .medium) + dynamicFont(name: Pretendard.medium.rawValue, baseSize: 16, weight: .medium) + } + + +} + + +extension UIFont { + public static func registerFonts() { + let fontEnums: [[any RawRepresentable]] = [ + RacingSansOne.allCases, + NanumMyeongjo.allCases, + Pretendard.allCases + ] + + let extensions = ["otf", "ttf"] + + for fontGroup in fontEnums { + for font in fontGroup { + let fontName = font.rawValue + + var found = false + for ext in extensions { + if let url = Bundle.module.url(forResource: fontName, withExtension: ext) { + var error: Unmanaged? + if CTFontManagerRegisterFontsForURL(url as CFURL, .process, &error) == false { + let description = error?.takeRetainedValue().localizedDescription ?? "Unknown error" + print("Font \(fontName).\(ext) failed to register: \(description)") + } + found = true + break + } + } + + if !found { + print("Font file \(fontName).otf or .ttf not found.") + } + } + } } } + diff --git a/RunLog/RunLog/Sources/DesignSystem/IconSystem.swift b/RunLog/Projects/DesignSystem/Sources/IconSystem.swift similarity index 91% rename from RunLog/RunLog/Sources/DesignSystem/IconSystem.swift rename to RunLog/Projects/DesignSystem/Sources/IconSystem.swift index 797b35b..0111622 100644 --- a/RunLog/RunLog/Sources/DesignSystem/IconSystem.swift +++ b/RunLog/Projects/DesignSystem/Sources/IconSystem.swift @@ -5,10 +5,11 @@ // Created by 심근웅 on 3/14/25. // +import UIKit import Foundation // MARK: - 아이콘 -enum RLIcon { +public enum RLIcon { case ellipsis case rightArrow case leftArrow @@ -47,7 +48,7 @@ enum RLIcon { } extension RLIcon { - var name: String { + public var name: String { switch self { case .fold: return "xmark" @@ -117,3 +118,9 @@ extension RLIcon { } } } + +extension UIImage { + public static func designSystem(named name: String) -> UIImage? { + UIImage(named: name, in: .module, with: nil) + } +} diff --git a/RunLog/RunLog/Sources/DesignSystem/LabelSystem.swift b/RunLog/Projects/DesignSystem/Sources/LabelSystem.swift similarity index 91% rename from RunLog/RunLog/Sources/DesignSystem/LabelSystem.swift rename to RunLog/Projects/DesignSystem/Sources/LabelSystem.swift index 61cc4c2..0a5e383 100644 --- a/RunLog/RunLog/Sources/DesignSystem/LabelSystem.swift +++ b/RunLog/Projects/DesignSystem/Sources/LabelSystem.swift @@ -4,19 +4,20 @@ // // Created by 심근웅 on 3/15/25. // +import RLUtil import UIKit import SnapKit import Then /// 아이콘을 내포하는 레이블 -final class RLLabel: UIView { +public final class RLLabel: UIView { // MARK: - 내부 Components - var icon = UIImageView() - var label = UILabel() + public var icon = UIImageView() + public var label = UILabel() /// Label의 attributedText 설정 - var attributedText: NSAttributedString? { + public var attributedText: NSAttributedString? { get { return label.attributedText } @@ -27,7 +28,7 @@ final class RLLabel: UIView { } /// text와 icon의 색상 변경 - override var tintColor: UIColor! { + public override var tintColor: UIColor! { get { return label.tintColor } @@ -71,7 +72,8 @@ final class RLLabel: UIView { // MARK: - Setup UI private func setupUI() { // subview - self.addSubviews(icon, label) + self.addSubview(icon) + self.addSubview(label) // autoLayout if icon.image == nil { diff --git a/RunLog/RunLog/Sources/DesignSystem/TextFieldSystem.swift b/RunLog/Projects/DesignSystem/Sources/TextFieldSystem.swift similarity index 99% rename from RunLog/RunLog/Sources/DesignSystem/TextFieldSystem.swift rename to RunLog/Projects/DesignSystem/Sources/TextFieldSystem.swift index ca18b94..008d1bd 100644 --- a/RunLog/RunLog/Sources/DesignSystem/TextFieldSystem.swift +++ b/RunLog/Projects/DesignSystem/Sources/TextFieldSystem.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/16/25. // +import RLUtil import UIKit import Combine diff --git a/RunLog/RunLog/Sources/DesignSystem/TextSystem.swift b/RunLog/Projects/DesignSystem/Sources/TextSystem.swift similarity index 100% rename from RunLog/RunLog/Sources/DesignSystem/TextSystem.swift rename to RunLog/Projects/DesignSystem/Sources/TextSystem.swift diff --git a/RunLog/RunLog/Sources/Presentation/Log/Coordinator/.gitkeep b/RunLog/Projects/DesignSystem/Tests/.gitkeep similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Log/Coordinator/.gitkeep rename to RunLog/Projects/DesignSystem/Tests/.gitkeep diff --git a/RunLog/Projects/Domain/Project.swift b/RunLog/Projects/Domain/Project.swift new file mode 100644 index 0000000..8a1359b --- /dev/null +++ b/RunLog/Projects/Domain/Project.swift @@ -0,0 +1,12 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let project = Project.framework( + name: Module.domain.name, + organizationName: Module.organizationName, + infoPlist: .default, + dependencies: [ + Module.util.project, + Module.designSystem.project + ] +) diff --git a/RunLog/Projects/Domain/Sources/Entity/AppConfig.swift b/RunLog/Projects/Domain/Sources/Entity/AppConfig.swift new file mode 100644 index 0000000..37958e1 --- /dev/null +++ b/RunLog/Projects/Domain/Sources/Entity/AppConfig.swift @@ -0,0 +1,30 @@ +// +// AppConfig.swift +// RunLog +// +// Created by 신승재 on 3/14/25. +// + +import Foundation + +public struct AppConfig: Equatable { + public var nickname: String + public var totalDistance: Double + public var streakDays: Int + public var totalDays: Int + public var unitDistance: Double + + public init( + nickname: String, + totalDistance: Double, + streakDays: Int, + totalDays: Int, + unitDistance: Double + ) { + self.nickname = nickname + self.totalDistance = totalDistance + self.streakDays = streakDays + self.totalDays = totalDays + self.unitDistance = unitDistance + } +} diff --git a/RunLog/Projects/Domain/Sources/Entity/DayLog.swift b/RunLog/Projects/Domain/Sources/Entity/DayLog.swift new file mode 100644 index 0000000..d3252f0 --- /dev/null +++ b/RunLog/Projects/Domain/Sources/Entity/DayLog.swift @@ -0,0 +1,57 @@ +// +// DayLog.swift +// RunLog +// +// Created by 신승재 on 3/14/25. +// + +import Foundation + +public struct DayLog: Equatable { + public let date: Date + public let locationName: String + public let weather: Int + public let temperature: Double + + public var trackImage: Data + public var title: String + public var level: Int + public var totalTime: TimeInterval + public var totalDistance: Double + public var totalSteps: Int + public var sections: [Section] + + public init( + date: Date, + locationName: String, + weather: Int, + temperature: Double, + trackImage: Data, + title: String, + level: Int, + totalTime: TimeInterval, + totalDistance: Double, + totalSteps: Int, + sections: [Section] + ) { + self.date = date + self.locationName = locationName + self.weather = weather + self.temperature = temperature + self.trackImage = trackImage + self.title = title + self.level = level + self.totalTime = totalTime + self.totalDistance = totalDistance + self.totalSteps = totalSteps + self.sections = sections + } +} + + +//extension DayLog { +// /// DayLog의 각 section을 RecordDetail 배열로 변환 +// func toRecordDetails() -> [RecordDetail] { +// return self.sections.map { RecordDetail(from: $0) } +// } +//} diff --git a/RunLog/Projects/Domain/Sources/Entity/Section.swift b/RunLog/Projects/Domain/Sources/Entity/Section.swift new file mode 100644 index 0000000..d30f5de --- /dev/null +++ b/RunLog/Projects/Domain/Sources/Entity/Section.swift @@ -0,0 +1,32 @@ +// +// Section.swift +// RunLog +// +// Created by 신승재 on 3/14/25. +// + +import Foundation + +public struct Section: Equatable { + public var distance: Double + public var steps: Int + public var route: [Point] + + public init(distance: Double, steps: Int, route: [Point]) { + self.distance = distance + self.steps = steps + self.route = route + } +} + +public struct Point: Equatable { + public var latitude: Double + public var longitude: Double + public var timestamp: Date + + public init(latitude: Double, longitude: Double, timestamp: Date) { + self.latitude = latitude + self.longitude = longitude + self.timestamp = timestamp + } +} diff --git a/RunLog/RunLog/Sources/Domain/Error/AppConfigError.swift b/RunLog/Projects/Domain/Sources/Error/AppConfigError.swift similarity index 97% rename from RunLog/RunLog/Sources/Domain/Error/AppConfigError.swift rename to RunLog/Projects/Domain/Sources/Error/AppConfigError.swift index 8e54c52..d5b5fec 100644 --- a/RunLog/RunLog/Sources/Domain/Error/AppConfigError.swift +++ b/RunLog/Projects/Domain/Sources/Error/AppConfigError.swift @@ -8,7 +8,7 @@ import Foundation /// AppConfig 저장소 동작 중 발생할 수 있는 에러를 정의한 열거형입니다. -enum AppConfigError: Error { +public enum AppConfigError: Error { /// 이미 AppConfig 객체가 존재하는 경우 case duplicatedObject diff --git a/RunLog/Projects/Domain/Sources/Error/DataError.swift b/RunLog/Projects/Domain/Sources/Error/DataError.swift new file mode 100644 index 0000000..d73a9c5 --- /dev/null +++ b/RunLog/Projects/Domain/Sources/Error/DataError.swift @@ -0,0 +1,32 @@ +// +// DataError.swift +// RLDomain +// +// Created by 신승재 on 7/20/25. +// Copyright © 2025 ESTSOFTiOSTEAM1. All rights reserved. +// + +import Foundation + +public enum DataError: LocalizedError { + case fetchError + case deleteError + case modelNotFound + case modelAlreadyExist + case conversionError + + var errorDescription: String { + switch self { + case .fetchError: + "Fetch Error" + case .deleteError: + "Delete Error" + case .modelNotFound: + "Model Not Found" + case .modelAlreadyExist: + "Model Already Exist" + case .conversionError: + "Conversion Error" + } + } +} diff --git a/RunLog/RunLog/Sources/Domain/Error/MediaUseCaseError.swift b/RunLog/Projects/Domain/Sources/Error/MediaUseCaseError.swift similarity index 100% rename from RunLog/RunLog/Sources/Domain/Error/MediaUseCaseError.swift rename to RunLog/Projects/Domain/Sources/Error/MediaUseCaseError.swift diff --git a/RunLog/RunLog/Sources/Domain/Repository/AppConfigRepository.swift b/RunLog/Projects/Domain/Sources/Repository/AppConfigRepository.swift similarity index 95% rename from RunLog/RunLog/Sources/Domain/Repository/AppConfigRepository.swift rename to RunLog/Projects/Domain/Sources/Repository/AppConfigRepository.swift index 1b2cdbd..e627fa3 100644 --- a/RunLog/RunLog/Sources/Domain/Repository/AppConfigRepository.swift +++ b/RunLog/Projects/Domain/Sources/Repository/AppConfigRepository.swift @@ -9,7 +9,7 @@ import Foundation /// 앱 설정(AppConfig)에 대한 CRUD 기능을 정의하는 저장소 프로토콜입니다. /// 영속 저장소(UserDefaults, File, Database 등)와의 인터페이스를 추상화합니다. -protocol AppConfigRepository { +public protocol AppConfigRepository { /// 앱 설정을 생성하여 저장소에 기록합니다. /// - Parameter config: 저장할 앱 설정 값 diff --git a/RunLog/RunLog/Sources/Domain/Repository/DayLogRepository.swift b/RunLog/Projects/Domain/Sources/Repository/DayLogRepository.swift similarity index 97% rename from RunLog/RunLog/Sources/Domain/Repository/DayLogRepository.swift rename to RunLog/Projects/Domain/Sources/Repository/DayLogRepository.swift index c7d9fe3..81f33eb 100644 --- a/RunLog/RunLog/Sources/Domain/Repository/DayLogRepository.swift +++ b/RunLog/Projects/Domain/Sources/Repository/DayLogRepository.swift @@ -7,7 +7,7 @@ import Foundation -protocol DayLogRepository { +public protocol DayLogRepository { /// 새로운 DayLog를 생성합니다. /// - Parameter dayLog: 저장할 DayLog 도메인 모델 /// - Throws: 저장 실패 시 `CoreDataError` 발생 diff --git a/RunLog/RunLog/Sources/Domain/UseCase/AppConfigUseCase.swift b/RunLog/Projects/Domain/Sources/UseCase/AppConfigUseCase.swift similarity index 98% rename from RunLog/RunLog/Sources/Domain/UseCase/AppConfigUseCase.swift rename to RunLog/Projects/Domain/Sources/UseCase/AppConfigUseCase.swift index 95bdec5..0f6ef0c 100644 --- a/RunLog/RunLog/Sources/Domain/UseCase/AppConfigUseCase.swift +++ b/RunLog/Projects/Domain/Sources/UseCase/AppConfigUseCase.swift @@ -7,7 +7,7 @@ import Foundation -protocol AppConfigUseCase { +public protocol AppConfigUseCase { // MARK: - Fetch Methods diff --git a/RunLog/RunLog/Sources/Domain/UseCase/DayLogUseCase.swift b/RunLog/Projects/Domain/Sources/UseCase/DayLogUseCase.swift similarity index 98% rename from RunLog/RunLog/Sources/Domain/UseCase/DayLogUseCase.swift rename to RunLog/Projects/Domain/Sources/UseCase/DayLogUseCase.swift index e20fc41..f635118 100644 --- a/RunLog/RunLog/Sources/Domain/UseCase/DayLogUseCase.swift +++ b/RunLog/Projects/Domain/Sources/UseCase/DayLogUseCase.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -protocol DayLogUseCase { +public protocol DayLogUseCase { /// 새로운 DayLog를 생성합니다. (러닝 시작 시 호출) /// - Parameters: diff --git a/RunLog/RunLog/Sources/Domain/UseCase/MediaUseCase.swift b/RunLog/Projects/Domain/Sources/UseCase/MediaUseCase.swift similarity index 97% rename from RunLog/RunLog/Sources/Domain/UseCase/MediaUseCase.swift rename to RunLog/Projects/Domain/Sources/UseCase/MediaUseCase.swift index 05124cc..c527f37 100644 --- a/RunLog/RunLog/Sources/Domain/UseCase/MediaUseCase.swift +++ b/RunLog/Projects/Domain/Sources/UseCase/MediaUseCase.swift @@ -10,7 +10,7 @@ import MapKit /// 미디어 관련 유스케이스를 정의하는 프로토콜입니다. /// 주어진 경로 데이터를 이미지로 변환하거나 저장하는 기능을 제공합니다. -protocol MediaUseCase { +public protocol MediaUseCase { /// 주어진 섹션 데이터를 CLLocationCoordinate2D 좌표 배열로 변환합니다. /// - Parameter sections: 위치 정보를 포함하는 섹션 배열 diff --git a/RunLog/RunLog/Sources/Domain/UseCaseImpl/AppConfigUseCaseImpl.swift b/RunLog/Projects/Domain/Sources/UseCaseImpl/AppConfigUseCaseImpl.swift similarity index 77% rename from RunLog/RunLog/Sources/Domain/UseCaseImpl/AppConfigUseCaseImpl.swift rename to RunLog/Projects/Domain/Sources/UseCaseImpl/AppConfigUseCaseImpl.swift index 76b9cf3..9c9740f 100644 --- a/RunLog/RunLog/Sources/Domain/UseCaseImpl/AppConfigUseCaseImpl.swift +++ b/RunLog/Projects/Domain/Sources/UseCaseImpl/AppConfigUseCaseImpl.swift @@ -4,14 +4,15 @@ // // Created by 김도연 on 3/19/25. // +import RLUtil import Foundation -final class AppConfigUseCaseImpl: AppConfigUseCase { +public final class AppConfigUseCaseImpl: AppConfigUseCase { private let appConfigRepository: AppConfigRepository - init(appConfigRepository: AppConfigRepository) { + public init(appConfigRepository: AppConfigRepository) { self.appConfigRepository = appConfigRepository Task { @@ -24,35 +25,35 @@ final class AppConfigUseCaseImpl: AppConfigUseCase { } - func getUnitDistance() async throws -> Double { + public func getUnitDistance() async throws -> Double { // print("Impl:", #function) let config = try await appConfigRepository.readAppConfig() return config.unitDistance } - func getNickname() async throws -> String { + public func getNickname() async throws -> String { // print("Impl:", #function) let config = try await appConfigRepository.readAppConfig() return config.nickname } - func getUserIndicators() async throws -> (streakDays: Int, totalDays: Int) { + public func getUserIndicators() async throws -> (streakDays: Int, totalDays: Int) { // print("Impl:", #function) let config = try await appConfigRepository.readAppConfig() return (config.streakDays, config.totalDays) } - func getTotalDistance() async throws -> Double { + public func getTotalDistance() async throws -> Double { // print("Impl:", #function) let config = try await appConfigRepository.readAppConfig() return config.totalDistance } - func getDistanceIndicators() async throws -> (roadName: String, count : Double) { + public func getDistanceIndicators() async throws -> (roadName: String, count : Double) { // print("Impl:", #function) let totalDistance = try await appConfigRepository.readAppConfig().totalDistance @@ -68,7 +69,7 @@ final class AppConfigUseCaseImpl: AppConfigUseCase { return (selectedRoad.name, totalDistance / selectedRoad.distance) } - func updateUnitDistance(_ unitDistance: Double) async throws { + public func updateUnitDistance(_ unitDistance: Double) async throws { // print("Impl:", #function) var config = try await appConfigRepository.readAppConfig() @@ -77,7 +78,7 @@ final class AppConfigUseCaseImpl: AppConfigUseCase { try await appConfigRepository.updateAppConfig(config) } - func updateNickname(_ nickname: String) async throws { + public func updateNickname(_ nickname: String) async throws { // print("Impl:", #function) var config = try await appConfigRepository.readAppConfig() diff --git a/RunLog/RunLog/Sources/Domain/UseCaseImpl/DayLogUseCaseImpl.swift b/RunLog/Projects/Domain/Sources/UseCaseImpl/DayLogUseCaseImpl.swift similarity index 86% rename from RunLog/RunLog/Sources/Domain/UseCaseImpl/DayLogUseCaseImpl.swift rename to RunLog/Projects/Domain/Sources/UseCaseImpl/DayLogUseCaseImpl.swift index 77a1475..2283391 100644 --- a/RunLog/RunLog/Sources/Domain/UseCaseImpl/DayLogUseCaseImpl.swift +++ b/RunLog/Projects/Domain/Sources/UseCaseImpl/DayLogUseCaseImpl.swift @@ -4,16 +4,17 @@ // // Created by 신승재 on 3/20/25. // +import RLUtil import Foundation import UIKit -final class DayLogUseCaseImpl: DayLogUseCase { +public final class DayLogUseCaseImpl: DayLogUseCase { private let dayLogRepository: DayLogRepository private let appConfigRepository: AppConfigRepository - init( + public init( dayLogRepository: DayLogRepository, appConfigRepository: AppConfigRepository ) { @@ -21,7 +22,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { self.appConfigRepository = appConfigRepository } - func initializeDayLog( + public func initializeDayLog( locationName: String, weather: Int, temperature: Double @@ -61,7 +62,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { try await appConfigRepository.updateAppConfig(appconfig) } - func getDayLogByDate(_ date: Date) async throws -> DayLog? { + public func getDayLogByDate(_ date: Date) async throws -> DayLog? { print("Impl:", #function) let dayLog = try await dayLogRepository.readDayLog( @@ -70,20 +71,20 @@ final class DayLogUseCaseImpl: DayLogUseCase { return dayLog } - func getAllDayLogs() async throws -> [DayLog] { + public func getAllDayLogs() async throws -> [DayLog] { print("Impl:", #function) let dayLogs = try await dayLogRepository.readAllDayLogs() return dayLogs } - func deleteDayLogByDate(_ date: Date) async throws { + public func deleteDayLogByDate(_ date: Date) async throws { print("Impl:", #function) try await dayLogRepository.deleteDayLog(date: date.toYearMonthDay) } - func addSectionByDate(_ date: Date, section: Section) async throws { + public func addSectionByDate(_ date: Date, section: Section) async throws { print("Impl:", #function) // 1. update 할 DayLog 가져오기 @@ -114,7 +115,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { try await appConfigRepository.updateAppConfig(appconfig) } - func getTitleByDate(_ date: Date) async throws -> String { + public func getTitleByDate(_ date: Date) async throws -> String { print("Impl:", #function) let dayLog = try await dayLogRepository.readDayLog( @@ -123,7 +124,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { return dayLog.title } - func updateTitleByDate(_ date: Date, title: String) async throws { + public func updateTitleByDate(_ date: Date, title: String) async throws { print("Impl:", #function) var targetDayLog = try await dayLogRepository.readDayLog( @@ -134,7 +135,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { try await dayLogRepository.updateDayLog(targetDayLog) } - func getLevelByDate(_ date: Date) async throws -> Int { + public func getLevelByDate(_ date: Date) async throws -> Int { print("Impl:", #function) let dayLog = try await dayLogRepository.readDayLog( @@ -143,7 +144,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { return dayLog.level } - func updateLevelByDate(_ date: Date, level: Int) async throws { + public func updateLevelByDate(_ date: Date, level: Int) async throws { print("Impl:", #function) var targetDayLog = try await dayLogRepository.readDayLog( @@ -154,7 +155,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { try await dayLogRepository.updateDayLog(targetDayLog) } - func updateTrackImageByDate(_ date: Date, image: UIImage) async throws { + public func updateTrackImageByDate(_ date: Date, image: UIImage) async throws { print("Impl:", #function) var targetDayLog = try await dayLogRepository.readDayLog( @@ -169,7 +170,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { try await dayLogRepository.updateDayLog(targetDayLog) } - func updateStreakIfNeeded() async throws { + public func updateStreakIfNeeded() async throws { let today = Date().toYearMonthDay // case: 오늘 운동을 했는지 안했는지 모르겟는데 마이페이지로 들어온 상황 @@ -178,7 +179,7 @@ final class DayLogUseCaseImpl: DayLogUseCase { do { // yes -> 업데이트 X try await dayLogRepository.readDayLog(date: today) - } catch CoreDataError.modelNotFound { + } catch DataError.modelNotFound { // no -> 어제 운동했니? let hasYesterdayDayLog = try await hasYesterdayDayLog() // yes -> 업데이트 X @@ -205,7 +206,7 @@ extension DayLogUseCaseImpl { do { try await dayLogRepository.readDayLog(date: yesterday) return true - } catch CoreDataError.modelNotFound { + } catch DataError.modelNotFound { return false } } diff --git a/RunLog/RunLog/Sources/Domain/UseCaseImpl/MediaUseCaseImpl.swift b/RunLog/Projects/Domain/Sources/UseCaseImpl/MediaUseCaseImpl.swift similarity index 92% rename from RunLog/RunLog/Sources/Domain/UseCaseImpl/MediaUseCaseImpl.swift rename to RunLog/Projects/Domain/Sources/UseCaseImpl/MediaUseCaseImpl.swift index d71ba91..8214884 100644 --- a/RunLog/RunLog/Sources/Domain/UseCaseImpl/MediaUseCaseImpl.swift +++ b/RunLog/Projects/Domain/Sources/UseCaseImpl/MediaUseCaseImpl.swift @@ -4,16 +4,17 @@ // // Created by 김도연 on 3/21/25. // +import RLDesignSystem import UIKit import MapKit import CoreLocation -final class MediaUseCaseImpl: MediaUseCase { +public final class MediaUseCaseImpl: MediaUseCase { - init() {} + public init() {} - func convertSectionsToCoordinates(sections: [Section]) -> [[CLLocationCoordinate2D]] { + public func convertSectionsToCoordinates(sections: [Section]) -> [[CLLocationCoordinate2D]] { var coordinates = [[CLLocationCoordinate2D]]() for section in sections { @@ -28,7 +29,7 @@ final class MediaUseCaseImpl: MediaUseCase { return coordinates } - func setRouteImage(route coordinates: [[CLLocationCoordinate2D]]) async throws -> UIImage { + public func setRouteImage(route coordinates: [[CLLocationCoordinate2D]]) async throws -> UIImage { let flatCoordinates = coordinates.flatMap { $0 } let centerCoordinate = try getRouteCenterCoordinate(flatCoordinates) let region = makeRouteSizeRegion(center: centerCoordinate, coordinates: flatCoordinates) @@ -76,7 +77,7 @@ final class MediaUseCaseImpl: MediaUseCase { return overlayImage } - func saveImageToDocuments(image: UIImage, imageName: String) throws { + public func saveImageToDocuments(image: UIImage, imageName: String) throws { guard let imageData = image.pngData() else { throw NSError(domain: "com.estsoft.runlog", code: -1, userInfo: [NSLocalizedDescriptionKey: "이미지 변환 실패"]) } diff --git a/RunLog/RunLog/Sources/Presentation/Run/ViewModel/Coordinator/.gitkeep b/RunLog/Projects/Domain/Tests/.gitkeep similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Run/ViewModel/Coordinator/.gitkeep rename to RunLog/Projects/Domain/Tests/.gitkeep diff --git a/RunLog/Projects/Inject/Project.swift b/RunLog/Projects/Inject/Project.swift new file mode 100644 index 0000000..5dd5663 --- /dev/null +++ b/RunLog/Projects/Inject/Project.swift @@ -0,0 +1,9 @@ +import ProjectDescription + +import ProjectDescriptionHelpers + +let project = Project.framework( + name: Module.inject.name, + organizationName: Module.organizationName, + infoPlist: .default +) diff --git a/RunLog/RunLog/Sources/App/DIContainer.swift b/RunLog/Projects/Inject/Sources/DIContainer.swift similarity index 70% rename from RunLog/RunLog/Sources/App/DIContainer.swift rename to RunLog/Projects/Inject/Sources/DIContainer.swift index 7ff2d52..da3ce67 100644 --- a/RunLog/RunLog/Sources/App/DIContainer.swift +++ b/RunLog/Projects/Inject/Sources/DIContainer.swift @@ -7,20 +7,20 @@ import Foundation -class DIContainer { +public final class DIContainer { - static let shared = DIContainer() + public static let shared = DIContainer() private var dependencies = [String: Any]() private init() {} - func register(_ dependency: T, for type: T.Type) { + public func register(_ dependency: T, for type: T.Type) { let key = String(describing: type) dependencies[key] = dependency } - func resolve(_ type: T.Type) -> T { + public func resolve(_ type: T.Type) -> T { let key = String(describing: type) guard let dependency = dependencies[key] else { preconditionFailure("\(key)는 register되지 않았어요. resolve 부르기 전에 register 해주세요") @@ -31,10 +31,10 @@ class DIContainer { @propertyWrapper -class Dependency { - let wrappedValue: T +public class Dependency { + public let wrappedValue: T - init() { + public init() { self.wrappedValue = DIContainer.shared.resolve(T.self) } } diff --git a/RunLog/RunLog/Sources/Presentation/Setting/Coordinator/.gitkeep b/RunLog/Projects/Inject/Tests/.gitkeep similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Setting/Coordinator/.gitkeep rename to RunLog/Projects/Inject/Tests/.gitkeep diff --git a/RunLog/Projects/Presentation/Project.swift b/RunLog/Projects/Presentation/Project.swift new file mode 100644 index 0000000..864406e --- /dev/null +++ b/RunLog/Projects/Presentation/Project.swift @@ -0,0 +1,19 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let project = Project.framework( + name: Module.presentation.name, + organizationName: Module.organizationName, + infoPlist: .default, + dependencies: [ + Module.inject.project, + Module.domain.project, + Module.data.project, // 수정해야함 + Module.util.project, + Module.designSystem.project, + .external(name: "SnapKit"), + .external(name: "Then"), + .external(name: "NVActivityIndicatorView"), + .external(name: "NVActivityIndicatorViewExtended"), + ] +) diff --git a/RunLog/RunLog/Sources/Presentation/Common/View/MainTabBarController.swift b/RunLog/Projects/Presentation/Sources/Common/View/MainTabBarController.swift similarity index 91% rename from RunLog/RunLog/Sources/Presentation/Common/View/MainTabBarController.swift rename to RunLog/Projects/Presentation/Sources/Common/View/MainTabBarController.swift index c4ade7a..09d4008 100644 --- a/RunLog/RunLog/Sources/Presentation/Common/View/MainTabBarController.swift +++ b/RunLog/Projects/Presentation/Sources/Common/View/MainTabBarController.swift @@ -4,6 +4,7 @@ // // Created by 심근웅 on 3/14/25. // +import RLDesignSystem import UIKit @@ -50,11 +51,11 @@ enum MainTab: CaseIterable { } } -class MainTabBarController: UITabBarController { +public final class MainTabBarController: UITabBarController { // MARK: - Init - init() { + public init() { super.init(nibName: nil, bundle: nil) } @@ -62,7 +63,7 @@ class MainTabBarController: UITabBarController { fatalError("init(coder:) has not been implemented") } - override func viewDidLoad() { + public override func viewDidLoad() { super.viewDidLoad() viewControllers = MainTab.allCases.map { $0.navigationController() } } diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/Model/DisplayDayLog.swift b/RunLog/Projects/Presentation/Sources/DetailLog/Model/DisplayDayLog.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/DetailLog/Model/DisplayDayLog.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/Model/DisplayDayLog.swift index a5fa9ea..b334ee1 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/Model/DisplayDayLog.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/Model/DisplayDayLog.swift @@ -4,6 +4,8 @@ // // Created by 도민준 on 3/21/25. // +import RLDomain +import RLUtil import Foundation diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/Model/RecordDetail.swift b/RunLog/Projects/Presentation/Sources/DetailLog/Model/RecordDetail.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/DetailLog/Model/RecordDetail.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/Model/RecordDetail.swift index bea973b..808f851 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/Model/RecordDetail.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/Model/RecordDetail.swift @@ -4,6 +4,7 @@ // // Created by 도민준 on 3/21/25. // +import RLDomain import Foundation diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/View/DetailLogView.swift b/RunLog/Projects/Presentation/Sources/DetailLog/View/DetailLogView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/DetailLog/View/DetailLogView.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/View/DetailLogView.swift index e94c5d5..33d2973 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/View/DetailLogView.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/View/DetailLogView.swift @@ -4,6 +4,8 @@ // // Created by 도민준 on 3/17/25. // +import RLDesignSystem +import RLUtil import UIKit import MapKit @@ -11,7 +13,7 @@ import SnapKit import Then -final class DetailLogView: UIView { + final class DetailLogView: UIView { // MARK: - UI Components 선언 diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/View/DetailLogViewController.swift b/RunLog/Projects/Presentation/Sources/DetailLog/View/DetailLogViewController.swift similarity index 94% rename from RunLog/RunLog/Sources/Presentation/DetailLog/View/DetailLogViewController.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/View/DetailLogViewController.swift index 4249966..cbe648d 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/View/DetailLogViewController.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/View/DetailLogViewController.swift @@ -4,6 +4,9 @@ // // Created by 도민준 on 3/17/25. // +import RLDomain +import RLDesignSystem +import RLUtil import UIKit import SnapKit @@ -76,19 +79,36 @@ final class DetailLogViewController: UIViewController { // MARK: - Setup Navigation Bar private func setupNavigationBar() { - // 네비게이션바 디테일 설정 - navigationController?.setupAppearance() // 스타일 설정 + + navigationController?.setupAppearance( + backgroundColor: .Gray900, + foregroundColor: .Gray000, + font: .RLHeadline1, + tintColor: .LightGreen + ) + navigationController?.navigationItem.backButtonTitle = "chevron.left" - navigationController? - .addRightMenuButton(menuItems: [ - ("수정하기", .init()), - ("공유하기", .init()), - ("삭제하기", .destructive) - ]) - .sink { [weak self] selectedTitle in - self?.viewModel.input.send(.menuSelected(selectedTitle)) - } - .store(in: &cancellables) + + let menuButton = UIButton() + menuButton.setImage(UIImage(systemName: RLIcon.ellipsis.name), for: .normal) + + let menuItems: [UIMenuElement] = [ + UIAction(title: "수정하기", handler: { [weak self] _ in + self?.viewModel.input.send(.menuSelected("수정하기")) + }), + UIAction(title: "공유하기", handler: { [weak self] _ in + self?.viewModel.input.send(.menuSelected("공유하기")) + }), + UIAction(title: "삭제하기", attributes: .destructive, handler: { [weak self] _ in + self?.viewModel.input.send(.menuSelected("삭제하기")) + }) + ] + + let menu = UIMenu(title: "", children: menuItems) + menuButton.showsMenuAsPrimaryAction = true + menuButton.menu = menu + + navigationController?.setupRightButton(menuButton) } // MARK: - Setup Gesture diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/View/MovingTrackSheetView.swift b/RunLog/Projects/Presentation/Sources/DetailLog/View/MovingTrackSheetView.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/DetailLog/View/MovingTrackSheetView.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/View/MovingTrackSheetView.swift index ff1ec2c..116b225 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/View/MovingTrackSheetView.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/View/MovingTrackSheetView.swift @@ -4,6 +4,8 @@ // // Created by 도민준 on 3/17/25. // +import RLDesignSystem +import RLUtil import UIKit import MapKit diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/View/MovingTrackSheetViewController.swift b/RunLog/Projects/Presentation/Sources/DetailLog/View/MovingTrackSheetViewController.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/DetailLog/View/MovingTrackSheetViewController.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/View/MovingTrackSheetViewController.swift index f3483ec..a4651ac 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/View/MovingTrackSheetViewController.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/View/MovingTrackSheetViewController.swift @@ -4,6 +4,7 @@ // // Created by 도민준 on 3/17/25. // +import RLDomain import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/View/RecordDetailView.swift b/RunLog/Projects/Presentation/Sources/DetailLog/View/RecordDetailView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/DetailLog/View/RecordDetailView.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/View/RecordDetailView.swift index 9cd6e1e..5e93340 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/View/RecordDetailView.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/View/RecordDetailView.swift @@ -4,6 +4,7 @@ // // Created by 도민준 on 3/17/25. // +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/View/RecordDetailViewCell.swift b/RunLog/Projects/Presentation/Sources/DetailLog/View/RecordDetailViewCell.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/DetailLog/View/RecordDetailViewCell.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/View/RecordDetailViewCell.swift index faf7dda..1290cda 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/View/RecordDetailViewCell.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/View/RecordDetailViewCell.swift @@ -4,6 +4,7 @@ // // Created by 도민준 on 3/17/25. // +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/DetailLog/ViewModel/DetailLogViewModel.swift b/RunLog/Projects/Presentation/Sources/DetailLog/ViewModel/DetailLogViewModel.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/DetailLog/ViewModel/DetailLogViewModel.swift rename to RunLog/Projects/Presentation/Sources/DetailLog/ViewModel/DetailLogViewModel.swift index cf368fa..0f0269c 100644 --- a/RunLog/RunLog/Sources/Presentation/DetailLog/ViewModel/DetailLogViewModel.swift +++ b/RunLog/Projects/Presentation/Sources/DetailLog/ViewModel/DetailLogViewModel.swift @@ -4,6 +4,8 @@ // // Created by 도민준 on 3/17/25. // +import RLDomain +import RLInject import UIKit import MapKit diff --git a/RunLog/RunLog/Sources/Presentation/Log/Component/RadioButtonCell.swift b/RunLog/Projects/Presentation/Sources/Log/Component/RadioButtonCell.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Log/Component/RadioButtonCell.swift rename to RunLog/Projects/Presentation/Sources/Log/Component/RadioButtonCell.swift index 2a88975..3f538f0 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/Component/RadioButtonCell.swift +++ b/RunLog/Projects/Presentation/Sources/Log/Component/RadioButtonCell.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/18/25. // +import RLDesignSystem import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Log/Component/UnderlineSegmentedControl.swift b/RunLog/Projects/Presentation/Sources/Log/Component/UnderlineSegmentedControl.swift similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Log/Component/UnderlineSegmentedControl.swift rename to RunLog/Projects/Presentation/Sources/Log/Component/UnderlineSegmentedControl.swift diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarView.swift b/RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarView.swift rename to RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarView.swift index d3e1e1e..b170b3e 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarView.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarView.swift @@ -4,6 +4,8 @@ // // Created by 신승재 on 3/15/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarViewCell.swift b/RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarViewCell.swift similarity index 95% rename from RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarViewCell.swift rename to RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarViewCell.swift index 1ba93d3..71e3713 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarViewCell.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarViewCell.swift @@ -4,6 +4,8 @@ // // Created by 신승재 on 3/16/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit @@ -75,7 +77,7 @@ class CalendarViewCell: UICollectionViewCell { default: imageName = RLIcon.noneBeat.name } - heartBeatImageView.image = UIImage(named: imageName) + heartBeatImageView.image = .designSystem(named: imageName) } else { self.dayLabel.text = "" heartBeatImageView.image = nil diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarViewController.swift b/RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarViewController.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarViewController.swift rename to RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarViewController.swift index c123ef6..1f0249f 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/Calendar/CalendarViewController.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/Calendar/CalendarViewController.swift @@ -4,6 +4,8 @@ // // Created by 신승재 on 3/16/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit @@ -56,9 +58,7 @@ final class CalendarViewController: UIViewController { // 랜덤 멘트 설정 let randomMotivation = Constants.MotivationMessage.random - calendarView.walkImage.image = UIImage( - named: randomMotivation.icon.name - ) + calendarView.walkImage.image = .designSystem(named: randomMotivation.iconName) calendarView.bottomLabel.text = randomMotivation.message } diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/Calendar/Model/CalendarDay.swift b/RunLog/Projects/Presentation/Sources/Log/View/Calendar/Model/CalendarDay.swift similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Log/View/Calendar/Model/CalendarDay.swift rename to RunLog/Projects/Presentation/Sources/Log/View/Calendar/Model/CalendarDay.swift diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/EditLog/EditLogInfoView.swift b/RunLog/Projects/Presentation/Sources/Log/View/EditLog/EditLogInfoView.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Log/View/EditLog/EditLogInfoView.swift rename to RunLog/Projects/Presentation/Sources/Log/View/EditLog/EditLogInfoView.swift index c9d95e6..f525374 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/EditLog/EditLogInfoView.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/EditLog/EditLogInfoView.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/18/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/EditLog/EditLogInfoViewController.swift b/RunLog/Projects/Presentation/Sources/Log/View/EditLog/EditLogInfoViewController.swift similarity index 88% rename from RunLog/RunLog/Sources/Presentation/Log/View/EditLog/EditLogInfoViewController.swift rename to RunLog/Projects/Presentation/Sources/Log/View/EditLog/EditLogInfoViewController.swift index 8ea9890..b11ecb1 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/EditLog/EditLogInfoViewController.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/EditLog/EditLogInfoViewController.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/18/25. // +import RLUtil import UIKit import SnapKit @@ -69,13 +70,30 @@ final class EditLogInfoViewController: UIViewController { // MARK: - Setup Navigation Bar private func setupNavigationBar() { navigationItem.title = "기록 관리하기" - self.navigationController?.setupAppearance() - navigationController? - .addRightButton(title: "완료") + self.navigationController?.setupAppearance( + backgroundColor: .Gray900, + foregroundColor: .Gray000, + font: .RLHeadline1, + tintColor: .LightGreen + ) + + let navigationButton = UIButton(type: .system) + let buttonTitle = "완료" + navigationButton.setTitle(buttonTitle, for: .normal) + navigationButton.titleLabel?.attributedText = .RLAttributedString( + text: buttonTitle, + font: .Label1, + color: .LightGreen, + align: .center + ) + + navigationButton.publisher .sink { [weak self] in self?.validateAndSaveInfo() } .store(in: &cancellables) + + self.navigationController?.setupRightButton(navigationButton) } private func setupTableView() { diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/LogView.swift b/RunLog/Projects/Presentation/Sources/Log/View/LogView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Log/View/LogView.swift rename to RunLog/Projects/Presentation/Sources/Log/View/LogView.swift index 65d39f2..4028f7b 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/LogView.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/LogView.swift @@ -4,6 +4,7 @@ // // Created by 신승재 on 3/14/25. // +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/LogViewController.swift b/RunLog/Projects/Presentation/Sources/Log/View/LogViewController.swift similarity index 89% rename from RunLog/RunLog/Sources/Presentation/Log/View/LogViewController.swift rename to RunLog/Projects/Presentation/Sources/Log/View/LogViewController.swift index 66c1aad..f1ea9fc 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/LogViewController.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/LogViewController.swift @@ -73,8 +73,22 @@ final class LogViewController: UIViewController { // MARK: - Setup Navigation Bar private func setupNavigationBar() { - self.navigationController?.setupAppearance() - self.navigationController?.setupLogoTitle() + self.navigationController?.setupAppearance( + backgroundColor: .Gray900, + foregroundColor: .Gray000, + font: .RLHeadline1, + tintColor: .LightGreen + ) + + let titleLabel = UILabel().then { + $0.attributedText = .RLAttributedString( + text: "Runlog", + font: .Logo2, + color: .LightGreen + ) + $0.textAlignment = .center + } + self.navigationController?.setupTitle(label: titleLabel) } // MARK: - Bind ViewModel diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/Timeline/TimelineView.swift b/RunLog/Projects/Presentation/Sources/Log/View/Timeline/TimelineView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Log/View/Timeline/TimelineView.swift rename to RunLog/Projects/Presentation/Sources/Log/View/Timeline/TimelineView.swift index ad1be5e..bed2572 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/Timeline/TimelineView.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/Timeline/TimelineView.swift @@ -4,6 +4,7 @@ // // Created by 신승재 on 3/15/25. // +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/Timeline/TimelineViewCell.swift b/RunLog/Projects/Presentation/Sources/Log/View/Timeline/TimelineViewCell.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Log/View/Timeline/TimelineViewCell.swift rename to RunLog/Projects/Presentation/Sources/Log/View/Timeline/TimelineViewCell.swift index 1e48d06..fd4ca34 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/View/Timeline/TimelineViewCell.swift +++ b/RunLog/Projects/Presentation/Sources/Log/View/Timeline/TimelineViewCell.swift @@ -4,6 +4,7 @@ // // Created by 신승재 on 3/16/25. // +import RLUtil import UIKit diff --git a/RunLog/RunLog/Sources/Presentation/Log/View/Timeline/TimelineViewController.swift b/RunLog/Projects/Presentation/Sources/Log/View/Timeline/TimelineViewController.swift similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Log/View/Timeline/TimelineViewController.swift rename to RunLog/Projects/Presentation/Sources/Log/View/Timeline/TimelineViewController.swift diff --git a/RunLog/RunLog/Sources/Presentation/Log/ViewModel/EditLogInfoViewModel.swift b/RunLog/Projects/Presentation/Sources/Log/ViewModel/EditLogInfoViewModel.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Log/ViewModel/EditLogInfoViewModel.swift rename to RunLog/Projects/Presentation/Sources/Log/ViewModel/EditLogInfoViewModel.swift index 67dda8c..3aa11e5 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/ViewModel/EditLogInfoViewModel.swift +++ b/RunLog/Projects/Presentation/Sources/Log/ViewModel/EditLogInfoViewModel.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/18/25. // +import RLDomain +import RLInject import UIKit import Combine diff --git a/RunLog/RunLog/Sources/Presentation/Log/ViewModel/LogViewModel.swift b/RunLog/Projects/Presentation/Sources/Log/ViewModel/LogViewModel.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Log/ViewModel/LogViewModel.swift rename to RunLog/Projects/Presentation/Sources/Log/ViewModel/LogViewModel.swift index f957e83..799396b 100644 --- a/RunLog/RunLog/Sources/Presentation/Log/ViewModel/LogViewModel.swift +++ b/RunLog/Projects/Presentation/Sources/Log/ViewModel/LogViewModel.swift @@ -4,6 +4,8 @@ // // Created by 신승재 on 3/14/25. // +import RLDomain +import RLInject import UIKit import Combine diff --git a/RunLog/RunLog/Sources/Presentation/Run/RunningDataProvider.swift b/RunLog/Projects/Presentation/Sources/Run/RunningDataProvider.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Run/RunningDataProvider.swift rename to RunLog/Projects/Presentation/Sources/Run/RunningDataProvider.swift index db67c43..a766077 100644 --- a/RunLog/RunLog/Sources/Presentation/Run/RunningDataProvider.swift +++ b/RunLog/Projects/Presentation/Sources/Run/RunningDataProvider.swift @@ -4,6 +4,9 @@ // // Created by 심근웅 on 3/21/25. // +import RLDomain +import RLData +import RLInject import Foundation import MapKit diff --git a/RunLog/RunLog/Sources/Presentation/Run/View/CardElementView.swift b/RunLog/Projects/Presentation/Sources/Run/View/CardElementView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Run/View/CardElementView.swift rename to RunLog/Projects/Presentation/Sources/Run/View/CardElementView.swift index 51fafdd..8bbabb3 100644 --- a/RunLog/RunLog/Sources/Presentation/Run/View/CardElementView.swift +++ b/RunLog/Projects/Presentation/Sources/Run/View/CardElementView.swift @@ -4,6 +4,7 @@ // // Created by 심근웅 on 3/15/25. // +import RLDesignSystem import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Run/View/CardView.swift b/RunLog/Projects/Presentation/Sources/Run/View/CardView.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Run/View/CardView.swift rename to RunLog/Projects/Presentation/Sources/Run/View/CardView.swift index 267c2e2..17ad8e0 100644 --- a/RunLog/RunLog/Sources/Presentation/Run/View/CardView.swift +++ b/RunLog/Projects/Presentation/Sources/Run/View/CardView.swift @@ -4,6 +4,8 @@ // // Created by 심근웅 on 3/15/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Run/View/MapBlurView.swift b/RunLog/Projects/Presentation/Sources/Run/View/MapBlurView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Run/View/MapBlurView.swift rename to RunLog/Projects/Presentation/Sources/Run/View/MapBlurView.swift index 4f4cefc..421a040 100644 --- a/RunLog/RunLog/Sources/Presentation/Run/View/MapBlurView.swift +++ b/RunLog/Projects/Presentation/Sources/Run/View/MapBlurView.swift @@ -4,6 +4,7 @@ // // Created by 심근웅 on 3/15/25. // +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Run/View/RunHomeViewController.swift b/RunLog/Projects/Presentation/Sources/Run/View/RunHomeViewController.swift similarity index 87% rename from RunLog/RunLog/Sources/Presentation/Run/View/RunHomeViewController.swift rename to RunLog/Projects/Presentation/Sources/Run/View/RunHomeViewController.swift index 3a7db4e..e89a098 100644 --- a/RunLog/RunLog/Sources/Presentation/Run/View/RunHomeViewController.swift +++ b/RunLog/Projects/Presentation/Sources/Run/View/RunHomeViewController.swift @@ -4,6 +4,8 @@ // // Created by 심근웅 on 3/14/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit @@ -134,14 +136,21 @@ final class RunHomeViewController: UIViewController { // MARK: - Setup Navigation Bar private func setupNavigationBar() { // 네비게이션바 디테일 설정 - self.setupNavigationBarAppearance() + self.setupNavigationBarAppearance(titleFont: .RLHeadline1, titleColor: .Gray000) } // MARK: - Setup Tab Bar private func setupTabBar() { - // 탭바 디테일 설정 - self.setupTabBarAppearance() - self.navigationController?.setupLogoTitle() + self.setupTabBarAppearance(tintColor: .LightGreen) + let titleLabel = UILabel().then { + $0.attributedText = .RLAttributedString( + text: "Runlog", + font: .Logo2, + color: .LightGreen + ) + $0.textAlignment = .center + } + self.navigationController?.setupTitle(label: titleLabel) } // MARK: - Setup Data @@ -160,17 +169,17 @@ final class RunHomeViewController: UIViewController { guard let self = self else { return } switch output { - // 운동시작하면 운동화면으로 넘어감 + // 운동시작하면 운동화면으로 넘어감 case .responseRunningStart: let vc = RunningViewController() vc.modalPresentationStyle = .fullScreen self.present(vc, animated: false) - // 사용자의 변경된 위치 반영 + // 사용자의 변경된 위치 반영 case .locationUpdate(let location): self.mapView.centerToLocation(location, region: self.mapView.region) - // 사용자의 변경된 위치명 반영 + // 사용자의 변경된 위치명 반영 case .locationNameUpdate(let text): self.locationLabel.attributedText = .RLAttributedString( @@ -179,15 +188,15 @@ final class RunHomeViewController: UIViewController { align: .center ) - // 변경된 날씨 정보 반영 + // 변경된 날씨 정보 반영 case .weatherUpdate(let text): self.weatherLabel.attributedText = .RLAttributedString( text: text, font: .Label2 ) - - // RoadRecord 정보 표시 + + // RoadRecord 정보 표시 case .responseRoadRecord(let text): self.RoadRecordLabel.attributedText = text } diff --git a/RunLog/RunLog/Sources/Presentation/Run/View/RunningViewController.swift b/RunLog/Projects/Presentation/Sources/Run/View/RunningViewController.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Run/View/RunningViewController.swift rename to RunLog/Projects/Presentation/Sources/Run/View/RunningViewController.swift index eec0e07..e57c808 100644 --- a/RunLog/RunLog/Sources/Presentation/Run/View/RunningViewController.swift +++ b/RunLog/Projects/Presentation/Sources/Run/View/RunningViewController.swift @@ -4,6 +4,8 @@ // // Created by 심근웅 on 3/15/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit diff --git a/RunLog/Projects/Presentation/Sources/Run/ViewModel/Coordinator/.gitkeep b/RunLog/Projects/Presentation/Sources/Run/ViewModel/Coordinator/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/RunLog/RunLog/Sources/Presentation/Run/ViewModel/RunHomeViewModel.swift b/RunLog/Projects/Presentation/Sources/Run/ViewModel/RunHomeViewModel.swift similarity index 96% rename from RunLog/RunLog/Sources/Presentation/Run/ViewModel/RunHomeViewModel.swift rename to RunLog/Projects/Presentation/Sources/Run/ViewModel/RunHomeViewModel.swift index c38f6cd..cc96d15 100644 --- a/RunLog/RunLog/Sources/Presentation/Run/ViewModel/RunHomeViewModel.swift +++ b/RunLog/Projects/Presentation/Sources/Run/ViewModel/RunHomeViewModel.swift @@ -4,6 +4,9 @@ // // Created by 심근웅 on 3/17/25. // +import RLDomain +import RLUtil +import RLInject import UIKit import Combine @@ -129,7 +132,9 @@ extension RunHomeViewModel { let attributedString = string.styledText( highlightText: "\(roadName) \(count)회", baseFont: .RLMainTitle, - highlightFont: .RLMainTitle + baseColor: .Gray000, + highlightFont: .RLMainTitle, + highlightColor: .LightGreen ) self.output.send(.responseRoadRecord(attributedString)) diff --git a/RunLog/RunLog/Sources/Presentation/Run/ViewModel/RunningViewModel.swift b/RunLog/Projects/Presentation/Sources/Run/ViewModel/RunningViewModel.swift similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Run/ViewModel/RunningViewModel.swift rename to RunLog/Projects/Presentation/Sources/Run/ViewModel/RunningViewModel.swift diff --git a/RunLog/RunLog/Sources/Presentation/Setting/Model/ProfileCardType.swift b/RunLog/Projects/Presentation/Sources/Setting/Model/ProfileCardType.swift similarity index 97% rename from RunLog/RunLog/Sources/Presentation/Setting/Model/ProfileCardType.swift rename to RunLog/Projects/Presentation/Sources/Setting/Model/ProfileCardType.swift index 264a149..a83283a 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/Model/ProfileCardType.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/Model/ProfileCardType.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 4/2/25. // +import RLDesignSystem import UIKit diff --git a/RunLog/RunLog/Sources/Presentation/Setting/Model/SettingMenuType.swift b/RunLog/Projects/Presentation/Sources/Setting/Model/SettingMenuType.swift similarity index 100% rename from RunLog/RunLog/Sources/Presentation/Setting/Model/SettingMenuType.swift rename to RunLog/Projects/Presentation/Sources/Setting/Model/SettingMenuType.swift diff --git a/RunLog/RunLog/Sources/Presentation/Setting/Model/UserInfoVO.swift b/RunLog/Projects/Presentation/Sources/Setting/Model/UserInfoVO.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Setting/Model/UserInfoVO.swift rename to RunLog/Projects/Presentation/Sources/Setting/Model/UserInfoVO.swift index 77b4d02..46f53ba 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/Model/UserInfoVO.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/Model/UserInfoVO.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 4/2/25. // +import RLUtil import Foundation diff --git a/RunLog/RunLog/Sources/Presentation/Setting/View/CalUnitView.swift b/RunLog/Projects/Presentation/Sources/Setting/View/CalUnitView.swift similarity index 97% rename from RunLog/RunLog/Sources/Presentation/Setting/View/CalUnitView.swift rename to RunLog/Projects/Presentation/Sources/Setting/View/CalUnitView.swift index ef7ae7e..6b11823 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/View/CalUnitView.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/View/CalUnitView.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/17/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit @@ -19,7 +21,7 @@ final class CalUnitView: UIView { // MARK: - UI Components 선언 /// 예시 이미지 private let exampleImageView = UIImageView().then { - $0.image = UIImage(named: "UnitExample") + $0.image = .designSystem(named: "UnitExample") $0.backgroundColor = .clear $0.contentMode = .scaleAspectFit } diff --git a/RunLog/RunLog/Sources/Presentation/Setting/View/ChangeNicknameView.swift b/RunLog/Projects/Presentation/Sources/Setting/View/ChangeNicknameView.swift similarity index 96% rename from RunLog/RunLog/Sources/Presentation/Setting/View/ChangeNicknameView.swift rename to RunLog/Projects/Presentation/Sources/Setting/View/ChangeNicknameView.swift index 07fe596..35de3c0 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/View/ChangeNicknameView.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/View/ChangeNicknameView.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/17/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Setting/View/MypageProfileView.swift b/RunLog/Projects/Presentation/Sources/Setting/View/MypageProfileView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Setting/View/MypageProfileView.swift rename to RunLog/Projects/Presentation/Sources/Setting/View/MypageProfileView.swift index e3b9f34..4061cd3 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/View/MypageProfileView.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/View/MypageProfileView.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/14/25. // +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Setting/View/ProfileCardView.swift b/RunLog/Projects/Presentation/Sources/Setting/View/ProfileCardView.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Setting/View/ProfileCardView.swift rename to RunLog/Projects/Presentation/Sources/Setting/View/ProfileCardView.swift index 5d78995..c498cee 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/View/ProfileCardView.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/View/ProfileCardView.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/14/25. // +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Setting/View/SettingMenuCell.swift b/RunLog/Projects/Presentation/Sources/Setting/View/SettingMenuCell.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Setting/View/SettingMenuCell.swift rename to RunLog/Projects/Presentation/Sources/Setting/View/SettingMenuCell.swift index 90f09ff..08630a7 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/View/SettingMenuCell.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/View/SettingMenuCell.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/15/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit diff --git a/RunLog/RunLog/Sources/Presentation/Setting/ViewController/ChangeCalUnitViewController.swift b/RunLog/Projects/Presentation/Sources/Setting/ViewController/ChangeCalUnitViewController.swift similarity index 88% rename from RunLog/RunLog/Sources/Presentation/Setting/ViewController/ChangeCalUnitViewController.swift rename to RunLog/Projects/Presentation/Sources/Setting/ViewController/ChangeCalUnitViewController.swift index 55160d9..86f565f 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/ViewController/ChangeCalUnitViewController.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/ViewController/ChangeCalUnitViewController.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/15/25. // +import RLDesignSystem +import RLUtil import UIKit import SnapKit @@ -68,15 +70,30 @@ final class ChangeCalUnitViewController: UIViewController { // MARK: - Setup Navigation Bar private func setupNavigationBar() { navigationItem.title = "기록 시각화 단위 설정" - self.navigationController?.setupAppearance() + self.navigationController?.setupAppearance( + backgroundColor: .Gray900, + foregroundColor: .Gray000, + font: .RLHeadline1, + tintColor: .LightGreen + ) - // 우측 '완료' 버튼 설정 및 동작 바인딩 - navigationController? - .addRightButton(title: "완료") + let navigationButton = UIButton(type: .system) + let buttonTitle = "완료" + navigationButton.setTitle(buttonTitle, for: .normal) + navigationButton.titleLabel?.attributedText = .RLAttributedString( + text: "완료", + font: .Label1, + color: .LightGreen, + align: .center + ) + + navigationButton.publisher .sink { [weak self] in self?.validateAndSaveUnit() } .store(in: &cancellables) + + navigationController?.setupRightButton(navigationButton) } // MARK: - Setup Gesture diff --git a/RunLog/RunLog/Sources/Presentation/Setting/ViewController/ChangeNicknameViewController.swift b/RunLog/Projects/Presentation/Sources/Setting/ViewController/ChangeNicknameViewController.swift similarity index 86% rename from RunLog/RunLog/Sources/Presentation/Setting/ViewController/ChangeNicknameViewController.swift rename to RunLog/Projects/Presentation/Sources/Setting/ViewController/ChangeNicknameViewController.swift index 6f7816f..3231102 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/ViewController/ChangeNicknameViewController.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/ViewController/ChangeNicknameViewController.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/15/25. // +import RLUtil import UIKit import SnapKit @@ -68,15 +69,33 @@ final class ChangeNicknameViewController: UIViewController { // MARK: - Setup Navigation Bar private func setupNavigationBar() { navigationItem.title = "닉네임 수정" - self.navigationController?.setupAppearance() + self.navigationController?.setupAppearance( + backgroundColor: .Gray900, + foregroundColor: .Gray000, + font: .RLHeadline1, + tintColor: .LightGreen + ) + + // 네비게이션바 우측 완료 버튼 바인딩 - navigationController? - .addRightButton(title: "완료") + let navigationButton = UIButton(type: .system) + let buttonTitle = "완료" + navigationButton.setTitle(buttonTitle, for: .normal) + navigationButton.titleLabel?.attributedText = .RLAttributedString( + text: buttonTitle, + font: .Label1, + color: .LightGreen, + align: .center + ) + + navigationButton.publisher .sink { [weak self] in self?.validateAndSaveNickname() } .store(in: &cancellables) + + navigationController?.setupRightButton(navigationButton) } private func setupTextField() { diff --git a/RunLog/RunLog/Sources/Presentation/Setting/ViewController/MyPageViewController.swift b/RunLog/Projects/Presentation/Sources/Setting/ViewController/MyPageViewController.swift similarity index 89% rename from RunLog/RunLog/Sources/Presentation/Setting/ViewController/MyPageViewController.swift rename to RunLog/Projects/Presentation/Sources/Setting/ViewController/MyPageViewController.swift index 2b59fd5..f8a9761 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/ViewController/MyPageViewController.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/ViewController/MyPageViewController.swift @@ -4,6 +4,7 @@ // // Created by 김도연 on 3/14/25. // +import RLUtil import UIKit import SnapKit @@ -64,8 +65,23 @@ final class MyPageViewController: UIViewController { // MARK: - Setup Navigation Bar private func setupNavigationBar() { - self.navigationController?.setupAppearance() - self.navigationController?.setupLogoTitle() + self.navigationController?.setupAppearance( + backgroundColor: .Gray900, + foregroundColor: .Gray000, + font: .RLHeadline1, + tintColor: .LightGreen + ) + + let titleLabel = UILabel().then { + $0.attributedText = .RLAttributedString( + text: "Runlog", + font: .Logo2, + color: .LightGreen + ) + $0.textAlignment = .center + } + + self.navigationController?.setupTitle(label: titleLabel) } private func setupTableView() { diff --git a/RunLog/RunLog/Sources/Presentation/Setting/ViewModel/CalUnitViewModel.swift b/RunLog/Projects/Presentation/Sources/Setting/ViewModel/CalUnitViewModel.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Setting/ViewModel/CalUnitViewModel.swift rename to RunLog/Projects/Presentation/Sources/Setting/ViewModel/CalUnitViewModel.swift index 39e84c9..84ad8f7 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/ViewModel/CalUnitViewModel.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/ViewModel/CalUnitViewModel.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/17/25. // +import RLDomain +import RLInject import UIKit import Combine diff --git a/RunLog/RunLog/Sources/Presentation/Setting/ViewModel/ChangeNicknameViewModel.swift b/RunLog/Projects/Presentation/Sources/Setting/ViewModel/ChangeNicknameViewModel.swift similarity index 98% rename from RunLog/RunLog/Sources/Presentation/Setting/ViewModel/ChangeNicknameViewModel.swift rename to RunLog/Projects/Presentation/Sources/Setting/ViewModel/ChangeNicknameViewModel.swift index 2b1f600..5e4f7ca 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/ViewModel/ChangeNicknameViewModel.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/ViewModel/ChangeNicknameViewModel.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/17/25. // +import RLDomain +import RLInject import UIKit import Combine diff --git a/RunLog/RunLog/Sources/Presentation/Setting/ViewModel/MyPageViewModel.swift b/RunLog/Projects/Presentation/Sources/Setting/ViewModel/MyPageViewModel.swift similarity index 99% rename from RunLog/RunLog/Sources/Presentation/Setting/ViewModel/MyPageViewModel.swift rename to RunLog/Projects/Presentation/Sources/Setting/ViewModel/MyPageViewModel.swift index 18a917b..c7e7426 100644 --- a/RunLog/RunLog/Sources/Presentation/Setting/ViewModel/MyPageViewModel.swift +++ b/RunLog/Projects/Presentation/Sources/Setting/ViewModel/MyPageViewModel.swift @@ -4,6 +4,8 @@ // // Created by 김도연 on 3/15/25. // +import RLDomain +import RLInject import UIKit import Combine diff --git a/RunLog/Projects/Presentation/Tests/.gitkeep b/RunLog/Projects/Presentation/Tests/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/RunLog/Projects/Util/Project.swift b/RunLog/Projects/Util/Project.swift new file mode 100644 index 0000000..9c61f23 --- /dev/null +++ b/RunLog/Projects/Util/Project.swift @@ -0,0 +1,11 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let project = Project.framework( + name: Module.util.name, + organizationName: Module.organizationName, + infoPlist: .default, + dependencies: [ + .external(name: "SnapKit"), + ] +) diff --git a/RunLog/RunLog/Sources/Util/Constant/Constants.swift b/RunLog/Projects/Util/Sources/Constant/Constants.swift similarity index 71% rename from RunLog/RunLog/Sources/Util/Constant/Constants.swift rename to RunLog/Projects/Util/Sources/Constant/Constants.swift index 5b7982b..49a527d 100644 --- a/RunLog/RunLog/Sources/Util/Constant/Constants.swift +++ b/RunLog/Projects/Util/Sources/Constant/Constants.swift @@ -7,36 +7,42 @@ import Foundation -struct Constants { - static let levels = ["매우 쉬움", "쉬움", "보통", "어려움", "매우 어려움"] +public struct Road { + public let name: String + public let distance: Double + public let iconName: String +} + +public struct Constants { + public static let levels = ["매우 쉬움", "쉬움", "보통", "어려움", "매우 어려움"] - static let allRoads: [Road] = [ - Road(name: "마라톤", distance: 42.195, icon: RLIcon.medal.name), - Road(name: "서울둘레길", distance: 156.5, icon: RLIcon.flag.name), - Road(name: "제주올레길", distance: 437.0, icon: RLIcon.mandarin.name), - Road(name: "국토대장정", distance: 580.0, icon: RLIcon.korea.name), - Road(name: "산티아고 순례길", distance: 800.0, icon: RLIcon.church.name), - Road(name: "지구 둘레길", distance: 40075, icon: RLIcon.earth.name), - Road(name: "지구에서 달까지", distance: 385000, icon: RLIcon.rocket.name) + public static let allRoads: [Road] = [ + Road(name: "마라톤", distance: 42.195, iconName: "Medal"), + Road(name: "서울둘레길", distance: 156.5, iconName: "Flag"), + Road(name: "제주올레길", distance: 437.0, iconName: "Mandarin"), + Road(name: "국토대장정", distance: 580.0, iconName: "Korea"), + Road(name: "산티아고 순례길", distance: 800.0, iconName: "Church"), + Road(name: "지구 둘레길", distance: 40075, iconName: "Earth"), + Road(name: "지구에서 달까지", distance: 385000, iconName: "Rocket") ] - enum MotivationMessage { + public enum MotivationMessage { case goodWeather case keepGoing case dogWalk - var icon: RLIcon { + public var iconName: String { switch self { case .goodWeather: - return .walkMan + return "walkMan" case .keepGoing: - return .walkGirl + return "walkGirl" case .dogWalk: - return .walkDog + return "walkDog" } } - var message: String { + public var message: String { switch self { case .goodWeather: return "날씨 좋은 날에 산뜻한 러닝 어때요?" @@ -47,18 +53,18 @@ struct Constants { } } - static var random: MotivationMessage { + public static var random: MotivationMessage { [goodWeather, keepGoing, dogWalk].randomElement()! } } - enum LocationMessage { + public enum LocationMessage { case unknown case consultingWithMap case detectingFootsteps case connectingGPS - var message: String { + public var message: String { switch self { case .unknown: return "지구 어딘가에서..." @@ -72,13 +78,13 @@ struct Constants { } /// 위치를 받아오는 과정에서 랜덤한 메시지를 띄웁니다. - static var random: LocationMessage { + public static var random: LocationMessage { [unknown, consultingWithMap, detectingFootsteps, connectingGPS].randomElement()! } } // MARK: - 날씨 정보 - enum WeatherCondition { + public enum WeatherCondition { case thunderstorm // 뇌우 case drizzle // 이슬비 case rain // 비 @@ -88,7 +94,7 @@ struct Constants { case clouds // 흐림 / 구름 많음 case unknown // 알 수 없음 - static func from(_ id: Int) -> WeatherCondition { + public static func from(_ id: Int) -> WeatherCondition { switch id { case 200...232: return .thunderstorm case 300...321: return .drizzle @@ -101,7 +107,7 @@ struct Constants { } } - var description: String { + public var description: String { switch self { case .thunderstorm: return "뇌우" case .drizzle: return "이슬비" @@ -116,7 +122,7 @@ struct Constants { } // MARK: - 대기질 정보 - enum AqiLevel: Int, CaseIterable { + public enum AqiLevel: Int, CaseIterable { case good = 1 // 좋음 case fair = 2 // 보통 case moderate = 3 // 나쁨 @@ -124,11 +130,11 @@ struct Constants { case veryPoor = 5 // 위험 case unknown = -1 // 알 수 없음 - static func from(_ value: Int) -> AqiLevel { + public static func from(_ value: Int) -> AqiLevel { return AqiLevel(rawValue: value) ?? .unknown } - var description: String { + public var description: String { switch self { case .good: return "좋음" case .fair: return "보통" diff --git a/RunLog/RunLog/Sources/Util/Extension/Bundle+.swift b/RunLog/Projects/Util/Sources/Extension/Bundle+.swift similarity index 89% rename from RunLog/RunLog/Sources/Util/Extension/Bundle+.swift rename to RunLog/Projects/Util/Sources/Extension/Bundle+.swift index b0d12c3..bfe6530 100644 --- a/RunLog/RunLog/Sources/Util/Extension/Bundle+.swift +++ b/RunLog/Projects/Util/Sources/Extension/Bundle+.swift @@ -6,8 +6,9 @@ // import Foundation + extension Bundle { - var weatherKey: String { + public var weatherKey: String { guard let key = object(forInfoDictionaryKey: "API_KEY") as? String else { fatalError("❌ API_KEY가 Info.plist에서 설정되지 않았습니다.") } diff --git a/RunLog/RunLog/Sources/Util/Extension/CLPlacemark+.swift b/RunLog/Projects/Util/Sources/Extension/CLPlacemark+.swift similarity index 97% rename from RunLog/RunLog/Sources/Util/Extension/CLPlacemark+.swift rename to RunLog/Projects/Util/Sources/Extension/CLPlacemark+.swift index 727e702..44d1fe8 100644 --- a/RunLog/RunLog/Sources/Util/Extension/CLPlacemark+.swift +++ b/RunLog/Projects/Util/Sources/Extension/CLPlacemark+.swift @@ -4,7 +4,6 @@ // // Created by 심근웅 on 3/21/25. // - import Foundation import MapKit @@ -12,7 +11,7 @@ import MapKit extension CLPlacemark { /// CLPlacemark 정보를 "도(광역시) 시(군,구) 동(읍,면)"의 형태로 변경하여 반환합니다. - func placemarksToString() -> String { + public func placemarksToString() -> String { var state: String = "" // 도, 광역시 var city: String = "" // 시, 군, 구 diff --git a/RunLog/RunLog/Sources/Util/Extension/Date+.swift b/RunLog/Projects/Util/Sources/Extension/Date+.swift similarity index 91% rename from RunLog/RunLog/Sources/Util/Extension/Date+.swift rename to RunLog/Projects/Util/Sources/Extension/Date+.swift index 3fc975d..da2355d 100644 --- a/RunLog/RunLog/Sources/Util/Extension/Date+.swift +++ b/RunLog/Projects/Util/Sources/Extension/Date+.swift @@ -7,7 +7,7 @@ import Foundation extension Date { // 저장하기 위해 연 월만 남기기 - var toYearMonthDay: Date { + public var toYearMonthDay: Date { var calendar = Calendar.current calendar.timeZone = TimeZone(identifier: "Asia/Seoul")! let components = calendar.dateComponents( @@ -17,7 +17,7 @@ extension Date { return calendar.date(from: components)! } - func formattedString(_ style: DateFormatStyle) -> String { + public func formattedString(_ style: DateFormatStyle) -> String { let formatter = DateFormatter() formatter.locale = Locale(identifier: "ko_KR") formatter.timeZone = TimeZone(identifier: "Asia/Seoul")! @@ -26,7 +26,7 @@ extension Date { } } -enum DateFormatStyle { +public enum DateFormatStyle { case fullDate // "2025. 02. 13." case monthDay // "0월 0일 (수)" case yearMonth // "2025년 3월" diff --git a/RunLog/RunLog/Sources/Util/Extension/Double+.swift b/RunLog/Projects/Util/Sources/Extension/Double+.swift similarity index 81% rename from RunLog/RunLog/Sources/Util/Extension/Double+.swift rename to RunLog/Projects/Util/Sources/Extension/Double+.swift index 91bd94e..81999e5 100644 --- a/RunLog/RunLog/Sources/Util/Extension/Double+.swift +++ b/RunLog/Projects/Util/Sources/Extension/Double+.swift @@ -9,19 +9,19 @@ import Foundation extension Double { /// 소수점 자리수를 지정하여 문자열로 변환 - func toString(withDecimal decimal: Int = 2) -> String { + public func toString(withDecimal decimal: Int = 2) -> String { return String(format: "%.\(decimal)f", self) } /// mm : ss 의 형태로 반환 - var asTimeString: String { + public var asTimeString: String { let minutes = Int(self) / 60 let seconds = Int(self) % 60 return String(format: "%02d : %02d", minutes, seconds) } // 소숫점 뒤에 0을 없애주는 애들 - var formattedString: String { + public var formattedString: String { let formattedString = String(self) if let dotIndex = formattedString.firstIndex(of: ".") { let afterDot = formattedString[dotIndex...] @@ -34,8 +34,8 @@ extension Double { } /// 각도를 라디안으로 변환 - var deg2rad: Double { self * .pi / 180 } + public var deg2rad: Double { self * .pi / 180 } /// 라디안을 각도로 변환 - var rad2deg: Double { self * 180 / .pi } + public var rad2deg: Double { self * 180 / .pi } } diff --git a/RunLog/RunLog/Sources/Util/Extension/Int+.swift b/RunLog/Projects/Util/Sources/Extension/Int+.swift similarity index 86% rename from RunLog/RunLog/Sources/Util/Extension/Int+.swift rename to RunLog/Projects/Util/Sources/Extension/Int+.swift index 163b41d..f2e659f 100644 --- a/RunLog/RunLog/Sources/Util/Extension/Int+.swift +++ b/RunLog/Projects/Util/Sources/Extension/Int+.swift @@ -9,14 +9,14 @@ import Foundation extension Int { /// 3자리마다 콤마(,)를 추가하여 문자열로 변환 - var formattedString: String { + public var formattedString: String { let numberFormatter = NumberFormatter() numberFormatter.numberStyle = .decimal return numberFormatter.string(from: NSNumber(value: self)) ?? "\(self)" } /// 오픈웨더에서 제공받은 날씨 정보를 한글화하여 반환 - func toWeatherDescription() -> String { + public func toWeatherDescription() -> String { switch self { case 1: return "맑음" case 2: return "흐림" @@ -26,7 +26,7 @@ extension Int { } } - func toLevelDescription() -> String { + public func toLevelDescription() -> String { switch self { case 0: return "매우 쉬움" case 1: return "쉬움" diff --git a/RunLog/RunLog/Sources/Util/Extension/MKMapView+.swift b/RunLog/Projects/Util/Sources/Extension/MKMapView+.swift similarity index 95% rename from RunLog/RunLog/Sources/Util/Extension/MKMapView+.swift rename to RunLog/Projects/Util/Sources/Extension/MKMapView+.swift index b5cbd4e..e9e2a87 100644 --- a/RunLog/RunLog/Sources/Util/Extension/MKMapView+.swift +++ b/RunLog/Projects/Util/Sources/Extension/MKMapView+.swift @@ -15,7 +15,7 @@ extension MKMapView { /// - location: 표현하고자하는 위치 /// - regionRadius: 최대로 보여질 지도 거리 /// - region: 기존 카메라 상태 - func centerToLocation( + public func centerToLocation( _ location: CLLocation, regionRadius: CLLocationDistance = 150, // 주변 거리(미터) region: MKCoordinateRegion? = nil @@ -51,7 +51,7 @@ extension MKMapView { } // MARK: - 초기 카메라 위치 세팅 - 좌표: 서울 - func initZoomLevel(_ meters: CLLocationDistance = 150) { + public func initZoomLevel(_ meters: CLLocationDistance = 150) { let newRegion = MKCoordinateRegion( center: CLLocationCoordinate2D( latitude: 37.5665, diff --git a/RunLog/RunLog/Sources/Util/Extension/String+.swift b/RunLog/Projects/Util/Sources/Extension/String+.swift similarity index 65% rename from RunLog/RunLog/Sources/Util/Extension/String+.swift rename to RunLog/Projects/Util/Sources/Extension/String+.swift index 1d6168b..da11e7b 100644 --- a/RunLog/RunLog/Sources/Util/Extension/String+.swift +++ b/RunLog/Projects/Util/Sources/Extension/String+.swift @@ -9,11 +9,13 @@ import UIKit extension String { /// 특정 부분의 텍스트 스타일을 변경하는 AttributedString 반환 - func styledText(highlightText: String, - baseFont: UIFont = .RLHeadline2, - baseColor: UIColor = .Gray000, - highlightFont: UIFont = .RLHeadline2, - highlightColor: UIColor = .LightGreen) -> NSMutableAttributedString { + public func styledText( + highlightText: String, + baseFont: UIFont, + baseColor: UIColor, + highlightFont: UIFont, + highlightColor: UIColor + ) -> NSMutableAttributedString { let attributedString = NSMutableAttributedString(string: self, attributes: [ .font: baseFont, @@ -29,3 +31,10 @@ extension String { return attributedString } } + + +//highlightText: String, +//baseFont: UIFont = .RLHeadline2, +//baseColor: UIColor = .Gray000, +//highlightFont: UIFont = .RLHeadline2, +//highlightColor: UIColor = .LightGreen diff --git a/RunLog/RunLog/Sources/Util/Extension/TimeInterval+.swift b/RunLog/Projects/Util/Sources/Extension/TimeInterval+.swift similarity index 88% rename from RunLog/RunLog/Sources/Util/Extension/TimeInterval+.swift rename to RunLog/Projects/Util/Sources/Extension/TimeInterval+.swift index b93df17..4bb38fe 100644 --- a/RunLog/RunLog/Sources/Util/Extension/TimeInterval+.swift +++ b/RunLog/Projects/Util/Sources/Extension/TimeInterval+.swift @@ -9,7 +9,7 @@ import Foundation extension TimeInterval { /// TimeInterval (초)를 "X시간 Y분" 형식의 문자열로 변환 - var hourMinuteString: String { + public var hourMinuteString: String { let hours = Int(self) / 3600 let minutes = (Int(self) % 3600) / 60 return "\(hours)시간 \(minutes)분" diff --git a/RunLog/RunLog/Sources/Util/Extension/UIButton+.swift b/RunLog/Projects/Util/Sources/Extension/UIButton+.swift similarity index 81% rename from RunLog/RunLog/Sources/Util/Extension/UIButton+.swift rename to RunLog/Projects/Util/Sources/Extension/UIButton+.swift index 446400d..3bd9ffa 100644 --- a/RunLog/RunLog/Sources/Util/Extension/UIButton+.swift +++ b/RunLog/Projects/Util/Sources/Extension/UIButton+.swift @@ -9,7 +9,7 @@ import UIKit import Combine extension UIButton { - var publisher: AnyPublisher { + public var publisher: AnyPublisher { controlPublisher(for: .touchUpInside) .map { _ in } .eraseToAnyPublisher() diff --git a/RunLog/RunLog/Sources/Util/Extension/UIColor+.swift b/RunLog/Projects/Util/Sources/Extension/UIColor+.swift similarity index 92% rename from RunLog/RunLog/Sources/Util/Extension/UIColor+.swift rename to RunLog/Projects/Util/Sources/Extension/UIColor+.swift index 5695672..96a5e6e 100644 --- a/RunLog/RunLog/Sources/Util/Extension/UIColor+.swift +++ b/RunLog/Projects/Util/Sources/Extension/UIColor+.swift @@ -11,7 +11,7 @@ import UIKit // MARK: - Hex -> UIColor extension UIColor { /// hex값과 alpha값을 전달 받아 hex값에 맞는 색상으로 초기화합니다. - convenience init(hex: String, alpha: CGFloat = 1.0) { + public convenience init(hex: String, alpha: CGFloat = 1.0) { var hexFormatted: String = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased() if hexFormatted.hasPrefix("#") { hexFormatted = String(hexFormatted.dropFirst()) diff --git a/RunLog/RunLog/Sources/Util/Extension/UIControl+.swift b/RunLog/Projects/Util/Sources/Extension/UIControl+.swift similarity index 75% rename from RunLog/RunLog/Sources/Util/Extension/UIControl+.swift rename to RunLog/Projects/Util/Sources/Extension/UIControl+.swift index b10791f..77c4405 100644 --- a/RunLog/RunLog/Sources/Util/Extension/UIControl+.swift +++ b/RunLog/Projects/Util/Sources/Extension/UIControl+.swift @@ -10,18 +10,18 @@ import Combine extension UIControl { - func controlPublisher(for event: UIControl.Event) -> UIControl.EventPublisher { + public func controlPublisher(for event: UIControl.Event) -> UIControl.EventPublisher { .init(control: self, event: event) } - struct EventPublisher: Publisher { - typealias Output = UIControl - typealias Failure = Never + public struct EventPublisher: Publisher { + public typealias Output = UIControl + public typealias Failure = Never - let control: UIControl - let event: UIControl.Event + public let control: UIControl + public let event: UIControl.Event - func receive(subscriber: S) where S : Subscriber, Never == S.Failure, UIControl == S.Input { + public func receive(subscriber: S) where S : Subscriber, Never == S.Failure, UIControl == S.Input { let subscription = EventSubscription(control: control, subscrier: subscriber, event: event) subscriber.receive(subscription: subscription) } diff --git a/RunLog/Projects/Util/Sources/Extension/UINavigationController+.swift b/RunLog/Projects/Util/Sources/Extension/UINavigationController+.swift new file mode 100644 index 0000000..aa8bf7a --- /dev/null +++ b/RunLog/Projects/Util/Sources/Extension/UINavigationController+.swift @@ -0,0 +1,47 @@ +// +// UINavigationController+.swift +// RunLog +// +// Created by 신승재 on 3/14/25. +// + +import UIKit +import Combine + +extension UINavigationController { + + /// 네비게이션 바의 스타일 설정 + public func setupAppearance( + backgroundColor: UIColor, + foregroundColor: UIColor, + font: UIFont, + tintColor: UIColor + ) { + + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.backgroundColor = backgroundColor + appearance.shadowColor = .clear + appearance.titleTextAttributes = [ + .foregroundColor: foregroundColor, + .font: font + ] + + navigationBar.standardAppearance = appearance + navigationBar.scrollEdgeAppearance = appearance + navigationBar.compactAppearance = appearance + navigationBar.tintColor = tintColor + + let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) + navigationBar.topItem?.backBarButtonItem = backButton + } + + public func setupTitle(label: UILabel) { + topViewController?.navigationItem.titleView = label + } + + + public func setupRightButton(_ button: UIButton) { + topViewController?.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button) + } +} diff --git a/RunLog/RunLog/Sources/Util/Extension/UITapGestureRecognizer+.swift b/RunLog/Projects/Util/Sources/Extension/UITapGestureRecognizer+.swift similarity index 87% rename from RunLog/RunLog/Sources/Util/Extension/UITapGestureRecognizer+.swift rename to RunLog/Projects/Util/Sources/Extension/UITapGestureRecognizer+.swift index f32a9bf..71fda0d 100644 --- a/RunLog/RunLog/Sources/Util/Extension/UITapGestureRecognizer+.swift +++ b/RunLog/Projects/Util/Sources/Extension/UITapGestureRecognizer+.swift @@ -10,9 +10,9 @@ import Combine extension UITapGestureRecognizer { /// UITapGestureRecognizer를 Combine에서 Publisher로 사용하기 위한 커스텀 구현 - struct TapPublisher: Publisher { - typealias Output = UITapGestureRecognizer - typealias Failure = Never + public struct TapPublisher: Publisher { + public typealias Output = UITapGestureRecognizer + public typealias Failure = Never private let gesture: UITapGestureRecognizer @@ -20,7 +20,7 @@ extension UITapGestureRecognizer { self.gesture = gesture } - func receive(subscriber: S) where S: Subscriber, S.Failure == Failure, S.Input == Output { + public func receive(subscriber: S) where S: Subscriber, S.Failure == Failure, S.Input == Output { // Subscription 생성 후 Subscriber에 전달 let subscription = TapGestureSubscription(gesture: gesture, subscriber: subscriber) subscriber.receive(subscription: subscription) @@ -60,7 +60,7 @@ extension UITapGestureRecognizer { } /// UITapGestureRecognizer에서 TapPublisher를 만들 수 있도록 하는 프로퍼티 - var tapPublisher: TapPublisher { + public var tapPublisher: TapPublisher { TapPublisher(gesture: self) } } diff --git a/RunLog/RunLog/Sources/Util/Extension/UITextField+.swift b/RunLog/Projects/Util/Sources/Extension/UITextField+.swift similarity index 84% rename from RunLog/RunLog/Sources/Util/Extension/UITextField+.swift rename to RunLog/Projects/Util/Sources/Extension/UITextField+.swift index 56c0c27..3b5bbeb 100644 --- a/RunLog/RunLog/Sources/Util/Extension/UITextField+.swift +++ b/RunLog/Projects/Util/Sources/Extension/UITextField+.swift @@ -9,7 +9,7 @@ import UIKit import Combine extension UITextField { - var publisher: AnyPublisher { + public var publisher: AnyPublisher { controlPublisher(for: .editingChanged) .compactMap { $0 as? UITextField } .map { $0.text ?? "" } diff --git a/RunLog/RunLog/Sources/Util/Extension/UIView+.swift b/RunLog/Projects/Util/Sources/Extension/UIView+.swift similarity index 81% rename from RunLog/RunLog/Sources/Util/Extension/UIView+.swift rename to RunLog/Projects/Util/Sources/Extension/UIView+.swift index 19000c1..e416a89 100644 --- a/RunLog/RunLog/Sources/Util/Extension/UIView+.swift +++ b/RunLog/Projects/Util/Sources/Extension/UIView+.swift @@ -9,7 +9,7 @@ import UIKit extension UIView { /// 여러 개의 서브뷰를 한 번에 추가하는 함수 - func addSubviews(_ views: UIView...) { + public func addSubviews(_ views: UIView...) { views.forEach { addSubview($0) } } } diff --git a/RunLog/RunLog/Sources/Util/Extension/UIViewController+.swift b/RunLog/Projects/Util/Sources/Extension/UIViewController+.swift similarity index 84% rename from RunLog/RunLog/Sources/Util/Extension/UIViewController+.swift rename to RunLog/Projects/Util/Sources/Extension/UIViewController+.swift index cd257f6..d6d42d4 100644 --- a/RunLog/RunLog/Sources/Util/Extension/UIViewController+.swift +++ b/RunLog/Projects/Util/Sources/Extension/UIViewController+.swift @@ -15,14 +15,14 @@ extension UIViewController { } /// 로딩 인디케이터 시작 - func startLoading() { + public func startLoading() { print(#function) guard LoadingIndicator.activityIndicator == nil else { return } // 이미 있으면 중복 생성 방지 let indicator = NVActivityIndicatorView( frame: .zero, type: .pacman, - color: .LightGreen, + color: .green, //.LightGreen padding: 44 ) @@ -37,7 +37,7 @@ extension UIViewController { } /// 로딩 인디케이터 종료 - func stopLoading() { + public func stopLoading() { print(#function) LoadingIndicator.activityIndicator?.stopAnimating() LoadingIndicator.activityIndicator?.removeFromSuperview() @@ -45,15 +45,15 @@ extension UIViewController { } /// 네비게이션 바의 스타일 설정 - func setupNavigationBarAppearance() { + public func setupNavigationBarAppearance(titleFont: UIFont, titleColor: UIColor) { let appearance = UINavigationBarAppearance() appearance.configureWithOpaqueBackground() appearance.backgroundColor = .black appearance.shadowColor = .clear appearance.titleTextAttributes = [ - .foregroundColor: UIColor.Gray000, - .font: UIFont.RLHeadline1 + .foregroundColor: titleColor, + .font: titleFont ] self.navigationController?.navigationBar.standardAppearance = appearance self.navigationController?.navigationBar.scrollEdgeAppearance = appearance @@ -61,7 +61,7 @@ extension UIViewController { } /// 탭 바의 스타일 설정 - func setupTabBarAppearance() { + public func setupTabBarAppearance(tintColor: UIColor) { let appearance = UITabBarAppearance() appearance.configureWithOpaqueBackground() appearance.backgroundColor = UIColor(hex: "#1C1C1C") @@ -69,11 +69,11 @@ extension UIViewController { self.tabBarController?.tabBar.standardAppearance = appearance self.tabBarController?.tabBar.scrollEdgeAppearance = appearance - self.tabBarController?.tabBar.tintColor = .LightGreen + self.tabBarController?.tabBar.tintColor = tintColor // .LightGreen } /// 터치하면 키보드가 내려가는 기능 추가 - func setupTapGestureToDismissKeyboard() { + public func setupTapGestureToDismissKeyboard() { let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) tapGesture.cancelsTouchesInView = false view.addGestureRecognizer(tapGesture) @@ -83,7 +83,7 @@ extension UIViewController { view.endEditing(true) } - func showAlert(message: String) { + public func showAlert(message: String) { let alert = UIAlertController(title: "알림", message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "확인", style: .default)) present(alert, animated: true) diff --git a/RunLog/RunLog/Sources/Util/Constant/DynamicSize.swift b/RunLog/Projects/Util/Sources/Helpers/DynamicSize.swift similarity index 90% rename from RunLog/RunLog/Sources/Util/Constant/DynamicSize.swift rename to RunLog/Projects/Util/Sources/Helpers/DynamicSize.swift index 63d3767..567916a 100644 --- a/RunLog/RunLog/Sources/Util/Constant/DynamicSize.swift +++ b/RunLog/Projects/Util/Sources/Helpers/DynamicSize.swift @@ -1,10 +1,11 @@ // -// ScreenSizeManager.swift +// DynamicSize.swift // RunLog // // Created by 심근웅 on 3/23/25. // +import UIKit import Foundation /// 화면 크기에 맞춰 동적으로 사이즈를 조정하는 구조체 @@ -12,7 +13,7 @@ import Foundation /// - Note: /// - 기준 사이즈는 **iPone 16 Pro Max** (440 x 956) ///- `SceneDelegate`에서 `setScreenSize(_:)`를 호출하여 초기 화면 크기를 설정해야 함 -struct DynamicSize { +public struct DynamicSize { /// 기준 너비 (16 Pro Max) private static let baseWidth: CGFloat = 440 @@ -29,7 +30,7 @@ struct DynamicSize { /// 현재 화면 크기 설정 /// /// - Parameter newBounds: 새롭게 설정할 화면의 `CGRect` 크기 - static func setScreenSize(_ newBounds: CGRect) { + public static func setScreenSize(_ newBounds: CGRect) { self.bounds = newBounds } @@ -59,7 +60,7 @@ extension DynamicSize { } /// 주어진 값에 스케일 비율을 적용 - static func scaledSize(_ size: CGFloat) -> CGFloat { + public static func scaledSize(_ size: CGFloat) -> CGFloat { return size * scaleFactor } } diff --git a/RunLog/Projects/Util/Tests/.gitkeep b/RunLog/Projects/Util/Tests/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/RunLog/RunLog/Info.plist b/RunLog/RunLog/Info.plist deleted file mode 100644 index 29fee54..0000000 --- a/RunLog/RunLog/Info.plist +++ /dev/null @@ -1,50 +0,0 @@ - - - - - API_KEY - $(API_KEY) - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - NSRemoteNotificationUsageDescription - 푸시 알림을 통해 개인화된 최신 소식을 받아보세요. - UIAppFonts - - NanumMyeongjo-Regular.ttf - RacingSansOne-Regular.ttf - Pretendard-Black.otf - Pretendard-Bold.otf - Pretendard-ExtraBold.otf - Pretendard-ExtraLight.otf - Pretendard-Light.otf - Pretendard-Medium.otf - Pretendard-Regular.otf - Pretendard-SemiBold.otf - Pretendard-Thin.otf - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - UISceneConfigurations - - UIWindowSceneSessionRoleApplication - - - UISceneConfigurationName - Default Configuration - UISceneDelegateClassName - $(PRODUCT_MODULE_NAME).SceneDelegate - - - - - UIBackgroundModes - - location - - - diff --git a/RunLog/RunLog/Sources/Data/CoreDataContainer.swift b/RunLog/RunLog/Sources/Data/CoreDataContainer.swift deleted file mode 100644 index a52cda0..0000000 --- a/RunLog/RunLog/Sources/Data/CoreDataContainer.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// CoreDataContainer.swift -// RunLog -// -// Created by 신승재 on 3/20/25. -// - -import CoreData - -final class CoreDataContainer { - - lazy var persistentContainer: NSPersistentContainer = { - let container = NSPersistentContainer(name: "DTOs") - container.loadPersistentStores { storeDescription, error in - if let error = error as NSError? { - fatalError("Unresolved error \(error)") - } - } - return container - }() - - var context: NSManagedObjectContext { - return persistentContainer.viewContext - } - -} - -enum CoreDataError: LocalizedError { - case fetchError - case deleteError - case modelNotFound - case modelAlreadyExist - case conversionError - - var errorDescription: String { - switch self { - case .fetchError: - "Fetch Error" - case .deleteError: - "Delete Error" - case .modelNotFound: - "Model Not Found" - case .modelAlreadyExist: - "Model Already Exist" - case .conversionError: - "Conversion Error" - } - } -} diff --git a/RunLog/RunLog/Sources/Domain/Entity/AppConfig.swift b/RunLog/RunLog/Sources/Domain/Entity/AppConfig.swift deleted file mode 100644 index ca1bd78..0000000 --- a/RunLog/RunLog/Sources/Domain/Entity/AppConfig.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// AppConfig.swift -// RunLog -// -// Created by 신승재 on 3/14/25. -// - -import Foundation - -struct AppConfig: Equatable { - var nickname: String - var totalDistance: Double - var streakDays: Int - var totalDays: Int - - var unitDistance: Double -} diff --git a/RunLog/RunLog/Sources/Domain/Entity/DayLog.swift b/RunLog/RunLog/Sources/Domain/Entity/DayLog.swift deleted file mode 100644 index 5033add..0000000 --- a/RunLog/RunLog/Sources/Domain/Entity/DayLog.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// DayLog.swift -// RunLog -// -// Created by 신승재 on 3/14/25. -// - -import Foundation - -struct DayLog: Equatable { - let date: Date - let locationName: String - let weather: Int - let temperature: Double - - var trackImage: Data - var title: String - var level: Int - var totalTime: TimeInterval - var totalDistance: Double - var totalSteps: Int - var sections: [Section] -} diff --git a/RunLog/RunLog/Sources/Domain/Entity/Road.swift b/RunLog/RunLog/Sources/Domain/Entity/Road.swift deleted file mode 100644 index 6928fe2..0000000 --- a/RunLog/RunLog/Sources/Domain/Entity/Road.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// Road.swift -// RunLog -// -// Created by 김도연 on 3/20/25. -// - -import Foundation - -struct Road { - let name: String - let distance: Double - let icon: String -} diff --git a/RunLog/RunLog/Sources/Domain/Entity/Section.swift b/RunLog/RunLog/Sources/Domain/Entity/Section.swift deleted file mode 100644 index c950354..0000000 --- a/RunLog/RunLog/Sources/Domain/Entity/Section.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// Section.swift -// RunLog -// -// Created by 신승재 on 3/14/25. -// - -import Foundation - -struct Section: Equatable { - var distance: Double - var steps: Int - var route: [Point] -} - -struct Point: Equatable { - var latitude: Double - var longitude: Double - var timestamp: Date -} diff --git a/RunLog/RunLog/Sources/Util/Extension/DayLog+.swift b/RunLog/RunLog/Sources/Util/Extension/DayLog+.swift deleted file mode 100644 index 637e9d3..0000000 --- a/RunLog/RunLog/Sources/Util/Extension/DayLog+.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// DayLog+.swift -// RunLog -// -// Created by 도민준 on 3/21/25. -// - -import Foundation - -extension DayLog { - /// DayLog의 각 section을 RecordDetail 배열로 변환 - func toRecordDetails() -> [RecordDetail] { - return self.sections.map { RecordDetail(from: $0) } - } -} diff --git a/RunLog/RunLog/Sources/Util/Extension/UINavigationController+.swift b/RunLog/RunLog/Sources/Util/Extension/UINavigationController+.swift deleted file mode 100644 index b3bf192..0000000 --- a/RunLog/RunLog/Sources/Util/Extension/UINavigationController+.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// UINavigationController+.swift -// RunLog -// -// Created by 신승재 on 3/14/25. -// - -import UIKit -import Combine - -extension UINavigationController { - - /// 네비게이션 바의 스타일 설정 - func setupAppearance() { - - let appearance = UINavigationBarAppearance() - appearance.configureWithOpaqueBackground() - appearance.backgroundColor = .Gray900 - appearance.shadowColor = .clear - appearance.titleTextAttributes = [ - .foregroundColor: UIColor.Gray000, - .font: UIFont.RLHeadline1 - ] - - navigationBar.standardAppearance = appearance - navigationBar.scrollEdgeAppearance = appearance - navigationBar.compactAppearance = appearance - navigationBar.tintColor = .LightGreen - - let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) - navigationBar.topItem?.backBarButtonItem = backButton - } - - func setupLogoTitle() { - let titleLabel = UILabel().then { - $0.attributedText = - .RLAttributedString( - text: "Runlog", - font: .Logo2, - color: .LightGreen - ) - $0.textAlignment = .center - } - topViewController?.navigationItem.titleView = titleLabel - } - - - /// 오른쪽 버튼 추가 - func addRightButton( - title: String? = nil, - icon: String? = nil, - target: Any?, - action: Selector - ) { - let rightButton = UIButton(type: .system) - - if let title = title { - rightButton.setTitle(title, for: .normal) - rightButton.setTitleColor(.label, for: .normal) - - rightButton.titleLabel?.attributedText = .RLAttributedString(text: title, font: .Label1, color: .LightGreen, align: .center) - } else if let icon = icon { - rightButton.setImage(UIImage(systemName: icon), for: .normal) - rightButton.tintColor = .LightGreen - } - - rightButton.addTarget(target, action: action, for: .touchUpInside) - topViewController?.navigationItem.rightBarButtonItem = UIBarButtonItem( - customView: rightButton - ) - } - - func addRightButton( - title: String? = nil, - icon: String? = nil - ) -> AnyPublisher { - let rightButton = UIButton(type: .system) - - if let title = title { - let attributedTitle = NSAttributedString.RLAttributedString( - text: title, - font: .Label1, - color: .LightGreen, - align: .center - ) - - rightButton.setAttributedTitle(attributedTitle, for: .normal) - } else if let icon = icon { - rightButton.setImage(UIImage(systemName: icon), for: .normal) - rightButton.tintColor = .LightGreen - } - - let publisher = rightButton.publisher - topViewController?.navigationItem.rightBarButtonItem = UIBarButtonItem( - customView: rightButton - ) - - return publisher - } - - func addRightMenuButton(menuItems: [(title: String, attributes: UIMenuElement.Attributes)]) -> AnyPublisher { - let rightButton = UIButton(type: .system) - - // RLIcon 시스템에 등록된 ellipsis 아이콘 사용 (예: RLIcon.ellipsis) - rightButton.setImage(UIImage(systemName: RLIcon.ellipsis.name), for: .normal) - rightButton.tintColor = .LightGreen - - let subject = PassthroughSubject() - - // UIAction 배열 생성 (아이콘 없이 제목과 속성만 사용) - let actions = menuItems.map { item in - UIAction(title: item.title, - image: nil, - attributes: item.attributes) { _ in - subject.send(item.title) - } - } - - let menu = UIMenu(title: "", children: actions) - - if #available(iOS 14.0, *) { - rightButton.showsMenuAsPrimaryAction = true - rightButton.menu = menu - } - - let barButtonItem = UIBarButtonItem(customView: rightButton) - topViewController?.navigationItem.rightBarButtonItem = barButtonItem - - return subject.eraseToAnyPublisher() - } -} diff --git a/RunLog/Tuist/ProjectDescriptionHelpers/Project+Templete.swift b/RunLog/Tuist/ProjectDescriptionHelpers/Project+Templete.swift new file mode 100644 index 0000000..635a1c0 --- /dev/null +++ b/RunLog/Tuist/ProjectDescriptionHelpers/Project+Templete.swift @@ -0,0 +1,91 @@ +import ProjectDescription + +extension Project { + public static func project( + name: String, + organizationName: String, + product: Product, + bundleID: String, + infoPlist: InfoPlist?, + schemes: [Scheme] = [], + dependencies: [TargetDependency] = [], + resources: ProjectDescription.ResourceFileElements? = nil, + coreDataModels: [CoreDataModel] = [] + ) -> Project { + return Project( + name: name, + organizationName: organizationName, + targets: [ + .target( + name: name, + destinations: [.iPhone], + product: product, + bundleId: bundleID, + deploymentTargets: .iOS("17.0"), + infoPlist: infoPlist, + sources: ["Sources/**"], + resources: resources, + dependencies: dependencies, + coreDataModels: coreDataModels + ), + .target( + name: "\(name)Tests", + destinations: [.iPhone], + product: .unitTests, + bundleId: bundleID, + deploymentTargets: .iOS("17.0"), + infoPlist: infoPlist, + sources: "Tests/**", + dependencies: [ + .target(name: "\(name)") + ] + ) + ], + schemes: schemes + ) + } + + public static func app ( + name: String, + organizationName: String, + infoPlist: InfoPlist?, + dependencies: [TargetDependency] = [], + resources: ProjectDescription.ResourceFileElements? = nil + ) -> Project { + return self.project( + name: "RL\(name)", + organizationName: organizationName, + product: .app, + bundleID: "com.\(organizationName).\(name)", + infoPlist: infoPlist, + dependencies: dependencies, + resources: resources + ) + } + + public static func framework( + name: String, + organizationName: String, + infoPlist: InfoPlist?, + dependencies: [TargetDependency] = [], + resources: ProjectDescription.ResourceFileElements? = nil, + coreDataModels: [CoreDataModel] = [] + ) -> Project { + return .project( + name: "RL\(name)", + organizationName: organizationName, + product: .framework, + bundleID: "com.\(organizationName).RL\(name)", + infoPlist: infoPlist, + dependencies: dependencies, + resources: resources, + coreDataModels: coreDataModels + ) + } +} + +public extension ProjectDescription.ResourceFileElements { + + static let `default`: ProjectDescription.ResourceFileElements = ["Resources/**"] + +} diff --git a/RunLog/Tuist/ProjectDescriptionHelpers/ProjectName.swift b/RunLog/Tuist/ProjectDescriptionHelpers/ProjectName.swift new file mode 100644 index 0000000..8dfec75 --- /dev/null +++ b/RunLog/Tuist/ProjectDescriptionHelpers/ProjectName.swift @@ -0,0 +1,44 @@ +import ProjectDescription + +public enum Module { + case app + case data + case presentation + case domain + case designSystem + case util + case inject +} + +extension Module { + public var name: String { + switch self { + case .app: + "App" + case .data: + "Data" + case .presentation: + "Presentation" + case .domain: + "Domain" + case .designSystem: + "DesignSystem" + case .util: + "Util" + case .inject: + "Inject" + } + } + + public static let organizationName: String = "ESTSOFTiOSTEAM1" + + public var path: ProjectDescription.Path { + .relativeToRoot("Projects/" + self.name) + } + + public var project: TargetDependency { + .project(target: "RL\(self.name)", path: self.path) + } +} + +extension Module: CaseIterable { } diff --git a/RunLog/Workspace.swift b/RunLog/Workspace.swift new file mode 100644 index 0000000..0a8b193 --- /dev/null +++ b/RunLog/Workspace.swift @@ -0,0 +1,7 @@ +import ProjectDescription +import ProjectDescriptionHelpers + +let workspace = Workspace( + name: "RunLog", + projects: Module.allCases.map(\.path) +)