Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion Application/Presentation/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ let project = Project(
.target(
name: "PresentationShared",
destinations: .iOS,
product: .staticFramework,
product: .framework,
bundleId: "com.opfic.DevLog.PresentationShared",
infoPlist: .file(path: frameworkInfoPlistPath),
sources: ["PresentationShared/Sources/**/*.swift"],
Expand Down Expand Up @@ -97,6 +97,50 @@ let project = Project(
]
)
),
.target(
name: "TodayTab",
destinations: .iOS,
product: .staticFramework,
bundleId: "com.opfic.DevLog.TodayTab",
infoPlist: .file(path: frameworkInfoPlistPath),
sources: ["TodayTab/Sources/**/*.swift"],
scripts: [
DevLogScripts.swiftLint(
sourcePath: "TodayTab/Sources",
configPath: "TodayTab/Sources/.swiftlint.yml"
)
],
dependencies: [
.project(target: "Domain", path: "../Domain"),
.project(target: "Core", path: "../Core"),
.target(name: "PresentationShared")
],
settings: frameworkBuildSettings
),
.target(
name: "TodayTabTests",
destinations: .iOS,
product: .unitTests,
bundleId: "com.opfic.DevLog.TodayTabTests",
infoPlist: .file(path: testsInfoPlistPath),
sources: ["TodayTab/Tests/**/*.swift"],
scripts: [
DevLogScripts.swiftLint(
sourcePath: "TodayTab/Tests",
configPath: "TodayTab/Tests/.swiftlint.yml"
)
],
dependencies: [
.target(name: "TodayTab"),
.target(name: "PresentationShared")
],
Comment thread
opficdev marked this conversation as resolved.
settings: .devlog(
base: [
"ENABLE_USER_SCRIPT_SANDBOXING": "NO",
"TEST_TARGET_NAME": "TodayTab"
]
)
),
.target(
name: "Presentation",
destinations: .iOS,
Expand All @@ -114,6 +158,7 @@ let project = Project(
.project(target: "Domain", path: "../Domain"),
.project(target: "Core", path: "../Core"),
.target(name: "HomeTab"),
.target(name: "TodayTab"),
.target(name: "PresentationShared")
],
settings: frameworkBuildSettings
Expand Down
1 change: 1 addition & 0 deletions Application/Presentation/Sources/Main/MainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Core
import Domain
import HomeTab
import PresentationShared
import TodayTab

struct MainView: View {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
Expand Down
1 change: 1 addition & 0 deletions Application/Presentation/TodayTab/Sources/.swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
parent_config: ../../../../.swiftlint.yml
12 changes: 12 additions & 0 deletions Application/Presentation/TodayTab/Sources/Today/TodayRoute.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// TodayRoute.swift
// Presentation
//
// Created by opfic on 7/5/26.
//

import PresentationShared

public enum TodayRoute: Hashable {
case todo(TodoIdItem)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import Core
import Domain
import PresentationShared

struct TodayView: View {
public struct TodayView: View {
@Bindable var store: StoreOf<TodayFeature>
let coordinator: TodayViewCoordinator
let isCompactLayout: Bool

init(
public init(
coordinator: TodayViewCoordinator,
isCompactLayout: Bool
) {
Expand All @@ -24,7 +24,7 @@ struct TodayView: View {
self.store = coordinator.store
}

var body: some View {
public var body: some View {
List {
summarySection
if store.sections.isEmpty, !store.isLoading {
Expand Down Expand Up @@ -208,10 +208,6 @@ struct TodayView: View {
}
}

enum TodayRoute: Hashable {
case todo(TodoIdItem)
}

private extension TodayDisplayOptions.DueDateVisibility {
var title: String {
switch self {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import PresentationShared

@MainActor
@Observable
final class TodayViewCoordinator {
public final class TodayViewCoordinator {
let store: StoreOf<TodayFeature>
let router = NavigationRouter<TodayRoute>()
public let router = NavigationRouter<TodayRoute>()

init(container: DIContainer) {
public init(container: DIContainer) {
let fetchDisplayOptionsUseCase = container.resolve(FetchTodayDisplayOptionsUseCase.self)
self.store = Store(
initialState: TodayFeature.State(
Comment thread
opficdev marked this conversation as resolved.
Expand All @@ -33,7 +33,7 @@ final class TodayViewCoordinator {
}
}

func fetchData() {
public func fetchData() {
store.send(.fetchData)
}
}
1 change: 1 addition & 0 deletions Application/Presentation/TodayTab/Tests/.swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
parent_config: ../../../../.swiftlint-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Testing
import Core
import Domain
@testable import Presentation
@testable import TodayTab

@MainActor
private func waitUntilTodayMainActor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation
import PresentationShared
import Core
import Domain
@testable import Presentation
@testable import TodayTab

enum TodayTestError: Error {
case failure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation
import Core
import Domain
@testable import Presentation
@testable import TodayTab

final class TodayFetchTodosUseCaseSpy: FetchTodosUseCase {
var pagesByFilter: [TodoQuery.DueDateFilter: TodoPage]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Testing
import Foundation
import Core
@testable import Presentation
@testable import TodayTab

@MainActor
struct TodayFeatureTests {
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Todo, 저장 링크, 오늘 할 일, 받은 알림, 누적 활동을 하나의
## 아키텍처

`DevLog.xcworkspace` 안에서 Application, Widget 모듈을 분리하고 화면, 상태, 비즈니스 로직, 외부 의존성 경계를 나눈 `Clean Architecture` 기반 구성
`Presentation`은 tab shell/root composition을 유지하고, 공통 UI 흐름은 `PresentationShared`, 탭 단위 흐름은 `HomeTab`, `TodayTab` target이 소유함

<table>
<tr>
Expand Down Expand Up @@ -237,7 +238,11 @@ DevLog_iOS/
│ ├── Data/ # Repository 구현, DTO, Mapper, Data 계층 Protocol
│ ├── Infra/ # Firebase, 소셜 로그인, 네트워크, 메타데이터 서비스 구현
│ ├── Persistence/ # UserDefaults, 이미지 저장소, 앱 로컬 영속성 처리
│ ├── Presentation/ # SwiftUI 화면, ViewModel, Store, Coordinator
│ ├── Presentation/ # SwiftUI tab shell, root composition
│ │ ├── PresentationShared/ # 공통 UI 흐름, 공통 presentation structure
│ │ ├── HomeTab/ # Home 탭 화면, feature, coordinator, 테스트
│ │ ├── TodayTab/ # Today 탭 화면, feature, coordinator, 테스트
│ │ └── Sources/ # Main, Root, Settings 등 앱 presentation shell
│ └── Widget/ # 앱-위젯 브릿지, 위젯 동기화 이벤트, 스냅샷 갱신
├── Widget/
│ ├── WidgetCore/ # 위젯 스냅샷 모델, Factory, App Group 상수
Expand Down
Binary file modified docs/graph.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading