-
Notifications
You must be signed in to change notification settings - Fork 0
Issue #3: ViewModelからUserDefaultsへの直接アクセスをPreferenceRepositoryパターンに修正 #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Warning Rate limit exceeded@harutiro has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 47 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (13)
Walkthroughアプリ内の設定/状態保存をUserDefaults直叩きからPreferenceRepositoryに統一。新規プロトコルと実装を追加し、各Usecase/ViewModel/Router/TestsへDIで導入。フロアマップ情報、校正結果、接続統計、セッションフラグ、移行フラグ等の保存/読込/削除ロジックをRepository経由に置換。 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as ユーザー
participant VM as ViewModel各種
participant Pref as PreferenceRepository
participant UD as UserDefaults
User->>VM: 状態保存/読込操作
VM->>Pref: save*/load*/set*/get*
Pref->>UD: setObject/getObject(エンコード/デコード含む)
UD-->>Pref: 値
Pref-->>VM: 結果
VM-->>User: UI更新/遷移
sequenceDiagram
autonumber
participant Mig as DataMigrationUsecase
participant Pref as PreferenceRepository
participant Store as UserDefaults
Mig->>Pref: isMigrationCompleted(key)
Pref->>Store: getBool(key)
Store-->>Pref: 状態
Pref-->>Mig: フラグ
alt 未完了
Mig->>Mig: データ変換/移行
Mig->>Pref: setMigrationCompleted(key, true)
Pref->>Store: setBool(true)
else 完了済み
Mig->>Mig: 何もしない/後処理
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
UWBViewerSystem/Presentation/Scenes/FloorMapTab/FloorMapViewModel.swift (1)
244-251: currentFloorMapInfoの更新/削除漏れにより不整合の恐れアクティブなフロアマップ削除時にRepository側のcurrentFloorMapInfoが更新/削除されず、後続画面が古い情報を復元する可能性があります。以下の修正を推奨。
- if floorMaps.isEmpty { - preferenceRepository.setHasFloorMapConfigured(false) - selectedFloorMap = nil - } else if map.isActive && !floorMaps.isEmpty { - floorMaps[0].isActive = true - selectedFloorMap = floorMaps[0] - } + if floorMaps.isEmpty { + preferenceRepository.setHasFloorMapConfigured(false) + preferenceRepository.removeCurrentFloorMapInfo() + selectedFloorMap = nil + } else if map.isActive { + floorMaps[0].isActive = true + let newSelected = floorMaps[0] + selectedFloorMap = newSelected + updateCurrentFloorMapInfo(newSelected.toFloorMapInfo()) + preferenceRepository.setHasFloorMapConfigured(true) + }
🧹 Nitpick comments (17)
UWBViewerSystem/Domain/Usecase/ObservationDataUsecase.swift (2)
69-71: PreferenceRepositoryのDIは適切だが、デフォルト実装の直接生成はドメイン層の純度を下げますComposition Rootから必須依存として注入し、ここではデフォルト値を持たせない方がテスト容易性・拡張性が上がります。
- public init( - dataRepository: DataRepositoryProtocol, - uwbManager: UWBDataManager, - preferenceRepository: PreferenceRepositoryProtocol = PreferenceRepository() - ) { + public init( + dataRepository: DataRepositoryProtocol, + uwbManager: UWBDataManager, + preferenceRepository: PreferenceRepositoryProtocol + ) {
374-375: ObservationSession.floorMapIdはString?です — 型の整合を確認してくださいObservationSessionの定義(UWBViewerSystem/Domain/Entity/ObservationData.swift)は
public let floorMapId: String?です。AntennaPositionData や SwiftDataRepository 等はfloorMapId: Stringを前提にしている箇所があるため、ObservationSessionを非Optionalにするか、使用側で明示的にunwrap/代替処理を入れて型を揃えてください。UWBViewerSystem/Presentation/Router/SensingFlowNavigator.swift (1)
20-25: preferenceRepositoryを注入したなら、UserDefaults直参照を段階的に置換しましょう現状、saveFlowState/loadFlowStateや各completionチェックがUserDefaults直参照のままです。少なくとも hasExecutedSensingSession(Line 404)はRepository経由に変更し、将来的にはフロー状態(currentStep/completedSteps/isFlowCompleted)も型安全なAPIに集約してください。
参考(変更は該当関数内で実施):
// 例: センシング実行フラグの取得 private func checkSensingExecutionCompletion() -> Bool { preferenceRepository.getBool(forKey: "hasExecutedSensingSession") }フロー状態は、PreferenceRepositoryに専用メソッド(例: saveSensingFlowState/loadSensingFlowState)を追加してキー隠蔽・型安全化するのが望ましいです。API追加可否をご確認ください。
UWBViewerSystemTests/SimpleCalibrationViewModelTests.swift (2)
19-21: テストの分離性向上: PreferenceRepositoryを分離ストアで初期化標準UserDefaults共有はテスト間干渉の温床です。RepositoryがUserDefaultsを注入可能であれば、suiteNameを分けたUserDefaultsで生成してください。なければテスト用のMock/インメモリ実装を用意しましょう。
24-33: UserDefaults直接操作をRepository経由へ寄せるcreateIsolatedTestViewModel内のクリア処理は、同じRepositoryインスタンスでremoveObjectする方が今後の実装変更に強いです。
@MainActor private func createIsolatedTestViewModel() -> SimpleCalibrationViewModel { - // テスト用のMockDataRepositoryを作成 - let mockRepository = MockDataRepository() - let mockPreferenceRepository = PreferenceRepository() - - // UserDefaultsをクリア - UserDefaults.standard.removeObject(forKey: "currentFloorMapInfo") - - let viewModel = SimpleCalibrationViewModel(dataRepository: mockRepository, preferenceRepository: mockPreferenceRepository) + let mockRepository = MockDataRepository() + let mockPreferenceRepository = PreferenceRepository() + // Repository経由でクリア(APIがある前提。なければ追加検討) + mockPreferenceRepository.removeObject(forKey: "currentFloorMapInfo") + let viewModel = SimpleCalibrationViewModel( + dataRepository: mockRepository, + preferenceRepository: mockPreferenceRepository + ) return viewModel }UWBViewerSystem/Presentation/Scenes/SensingTab/SensingManagementPage/SensingManagementViewModel.swift (1)
197-200: フロー連携フラグの保存をRepositoryへ移行できていますSensingFlowNavigator側の参照もRepositoryに統一すると整合性が取りやすいです。
UWBViewerSystem/Presentation/Scenes/SensingTab/TrajectoryViewPage/TrajectoryViewModel.swift (3)
103-107: セッション一覧のRepository読込は適切ですキー文字列の集中管理(定数化 or Repository専用API)を検討ください。
215-228: フロア寸法が不正な場合のゼロ除算防止を追加width/depthが0以下のケースにフォールバックしましょう。
- let canvasSize = CGSize(width: 500, height: 500) // マップキャンバスのサイズ - let scaleX = Double(canvasSize.width) / floorMapInfo.width - let scaleY = Double(canvasSize.height) / floorMapInfo.depth + let canvasSize = CGSize(width: 500, height: 500) // マップキャンバスのサイズ + guard floorMapInfo.width > 0, floorMapInfo.depth > 0 else { + return CGPoint(x: 50, y: 50) + } + let scaleX = Double(canvasSize.width) / floorMapInfo.width + let scaleY = Double(canvasSize.height) / floorMapInfo.depth
36-45: デフォルトの時間フィルタで軌跡が0件になりやすいstartTimeFilter/endTimeFilterがともにDate()初期化だと現在時刻”のみ”に絞られます。初期表示は全件表示にした方が自然です(例: distantPast/distantFuture)。
例(該当プロパティ宣言部の変更案・抜粋):
@Published var startTimeFilter = Date.distantPast @Published var endTimeFilter = Date.distantFutureUWBViewerSystem/Presentation/Scenes/SensingTab/SensingViewModel.swift (1)
46-49: ストリングキーの散在を避け、リポジトリの型安全なAPIを使ってください
hasFloorMapConfigured/hasDeviceConnected は既にリポジトリ側に専用メソッドがあるため、SensingViewModel で文字列キーを直接使わずそちらを呼び出してください。
修正例(UWBViewerSystem/Presentation/Scenes/SensingTab/SensingViewModel.swift 行47–48):
- preferenceRepository.getBool(forKey: "hasFloorMapConfigured") → preferenceRepository.getHasFloorMapConfigured()
- preferenceRepository.getBool(forKey: "hasDeviceConnected") → dataRepository.loadHasDeviceConnected()(または該当リポジトリのメソッド)
参照実装: UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (getHasFloorMapConfigured / setHasFloorMapConfigured), UWBViewerSystem/Domain/Repository/DataRepository.swift (loadHasDeviceConnected / saveHasDeviceConnected), テスト: UWBViewerSystemTests/TestHelpers/MockDataRepository.swiftUWBViewerSystem/Presentation/Scenes/FloorMapTab/FloorMapSettingPage/FloorMapSettingViewModel.swift (1)
288-290: 保存完了時に構成フラグを立てるフロアマップ保存成功後に構成済みフラグも立てておくと初回導線が安定します(他画面のフォールバックと整合)。
// フロアマップ情報を保存 preferenceRepository.saveCurrentFloorMapInfo(info) + preferenceRepository.setHasFloorMapConfigured(true)UWBViewerSystem/Presentation/Scenes/SensingTab/ConnectionManagementPage/ConnectionManagementViewModel.swift (1)
221-229: Int64の切り捨て回避と型安全化
- dataTransferredをIntへ変換して保存すると環境によっては桁あふれリスク。NSNumber経由でInt64として保存/復元を推奨。
- 可能なら辞書ではなくCodableな構造体での保存に寄せましょう(Repositoryの汎用setData/getDataが活用可)。
private func saveStatistics() { - let statistics = [ + let statistics: [String: Any] = [ "totalConnections": totalConnections, "totalMessages": totalMessages, - "dataTransferred": Int(dataTransferred), + "dataTransferred": dataTransferred, // Int64としてNSNumberにブリッジされる ] preferenceRepository.saveConnectionStatistics(statistics) } private func loadStatistics() { - if let statistics = preferenceRepository.loadConnectionStatistics() { - totalConnections = statistics["totalConnections"] as? Int ?? 0 - totalMessages = statistics["totalMessages"] as? Int ?? 0 - dataTransferred = Int64(statistics["dataTransferred"] as? Int ?? 0) + if let statistics = preferenceRepository.loadConnectionStatistics() { + totalConnections = statistics["totalConnections"] as? Int ?? 0 + totalMessages = statistics["totalMessages"] as? Int ?? 0 + if let n = statistics["dataTransferred"] as? NSNumber { + dataTransferred = n.int64Value + } else { + dataTransferred = 0 + } } }型安全化(参考・別ファイル修正が必要):
// モデル struct ConnectionStatistics: Codable { let totalConnections: Int let totalMessages: Int let dataTransferred: Int64 } // Repositoryに型付きAPIを追加 func saveConnectionStatistics(_ stats: ConnectionStatistics) { try? setData(stats, forKey: "ConnectionStatisticsV2") } func loadConnectionStatisticsV2() -> ConnectionStatistics? { getData(ConnectionStatistics.self, forKey: "ConnectionStatisticsV2") }Also applies to: 232-236
UWBViewerSystem/Presentation/Scenes/FloorMapTab/SystemCalibrationPage/SimpleCalibrationViewModel.swift (1)
558-567: FloorMapChanged通知も監視して即時反映をUserDefaults全体の変更監視に加え、FloorMapViewModelが投げる"FloorMapChanged"をピンポイントで購読すると反映がより確実です。
private func setupDataObserver() { // UserDefaultsの "currentFloorMapInfo" キーの変更を監視 NotificationCenter.default.publisher(for: UserDefaults.didChangeNotification) .sink { [weak self] _ in Task { @MainActor in self?.loadCurrentFloorMapData() } } .store(in: &cancellables) + + // FloorMap変更のドメイン通知を監視 + NotificationCenter.default.publisher(for: .init("FloorMapChanged")) + .sink { [weak self] notification in + guard let self else { return } + if let info = notification.object as? FloorMapInfo { + Task { @MainActor in + self.currentFloorMapId = info.id + self.currentFloorMapInfo = info + self.loadFloorMapImage(for: info.id) + } + } else { + Task { @MainActor in + self.loadCurrentFloorMapData() + } + } + } + .store(in: &cancellables) }UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (3)
249-256: setDataのシグネチャはジェネリック化を推奨引数での
some Codableは最新ツールチェイン依存です。T: CodableでgetDataと対称にしておくと互換性が高まります。- public func setData(_ value: some Codable, forKey key: String) throws { + public func setData<T: Codable>(_ value: T, forKey key: String) throws { let encoded = try JSONEncoder().encode(value) userDefaults.set(encoded, forKey: key) }
205-211: 接続統計は型付き保存を検討
[String: Any]は呼び出し側での取り扱いが不安定です。Codableな構造体(例: ConnectionStatistics)でV2キー保存へ移行し、旧形式は移行用に読み出す方針を推奨。
156-171: シンプル型はUserDefaultsのネイティブ型での保存も可
currentStepやcompletedStepsはsetString/userDefaults.set([String])で足ります。JSON化は過剰なので、必要性がなければ単純化を検討ください(互換性配慮の上で)。UWBViewerSystem/Presentation/Scenes/SensingTab/DataCollectionPage/DataCollectionViewModel.swift (1)
159-165: SensingSessionはCodableで保存は問題なし — 文字列キーはRepository専用メソッドへ移譲してくださいSensingSessionがCodableであることを確認しました(UWBViewerSystem/Domain/Entity/SensingSession.swift)。DataCollectionViewModelのsaveRecentSessionsは現在 "RecentSensingSessions" を直接指定しているため、PreferenceRepositoryに saveRecentSensingSessions(_:) / loadRecentSensingSessions() のような専用APIを追加してキー管理を一元化してください。該当: UWBViewerSystem/Presentation/Scenes/SensingTab/DataCollectionPage/DataCollectionViewModel.swift (159–165, 167–171).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift(1 hunks)UWBViewerSystem/Domain/Usecase/DataMigrationUsecase.swift(3 hunks)UWBViewerSystem/Domain/Usecase/ObservationDataUsecase.swift(3 hunks)UWBViewerSystem/Presentation/Router/SensingFlowNavigator.swift(1 hunks)UWBViewerSystem/Presentation/Scenes/FloorMapTab/FloorMapSettingPage/FloorMapSettingViewModel.swift(3 hunks)UWBViewerSystem/Presentation/Scenes/FloorMapTab/FloorMapViewModel.swift(7 hunks)UWBViewerSystem/Presentation/Scenes/FloorMapTab/SystemCalibrationPage/SimpleCalibrationViewModel.swift(3 hunks)UWBViewerSystem/Presentation/Scenes/SensingTab/ConnectionManagementPage/ConnectionManagementViewModel.swift(2 hunks)UWBViewerSystem/Presentation/Scenes/SensingTab/DataCollectionPage/DataCollectionViewModel.swift(3 hunks)UWBViewerSystem/Presentation/Scenes/SensingTab/SensingManagementPage/SensingManagementViewModel.swift(3 hunks)UWBViewerSystem/Presentation/Scenes/SensingTab/SensingViewModel.swift(2 hunks)UWBViewerSystem/Presentation/Scenes/SensingTab/TrajectoryViewPage/TrajectoryViewModel.swift(4 hunks)UWBViewerSystemTests/SimpleCalibrationViewModelTests.swift(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (11)
UWBViewerSystem/Presentation/Scenes/SensingTab/ConnectionManagementPage/ConnectionManagementViewModel.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (2)
saveConnectionStatistics(205-207)loadConnectionStatistics(209-211)
UWBViewerSystem/Domain/Usecase/DataMigrationUsecase.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (3)
isMigrationCompleted(219-221)setMigrationCompleted(215-217)removeObject(259-261)
UWBViewerSystem/Domain/Usecase/ObservationDataUsecase.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (1)
loadCurrentFloorMapInfo(87-89)
UWBViewerSystem/Presentation/Scenes/FloorMapTab/FloorMapViewModel.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (3)
loadCurrentFloorMapInfo(87-89)setHasFloorMapConfigured(110-112)saveCurrentFloorMapInfo(79-85)
UWBViewerSystem/Presentation/Scenes/SensingTab/SensingViewModel.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (1)
getBool(229-231)
UWBViewerSystem/Presentation/Scenes/FloorMapTab/FloorMapSettingPage/FloorMapSettingViewModel.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (3)
loadLastFloorSettings(102-108)saveLastFloorSettings(95-100)saveCurrentFloorMapInfo(79-85)
UWBViewerSystemTests/SimpleCalibrationViewModelTests.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (1)
removeObject(259-261)
UWBViewerSystem/Presentation/Scenes/SensingTab/DataCollectionPage/DataCollectionViewModel.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (2)
setData(249-252)getData(254-257)
UWBViewerSystem/Presentation/Scenes/SensingTab/SensingManagementPage/SensingManagementViewModel.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (1)
setHasExecutedSensingSession(179-181)
UWBViewerSystem/Presentation/Scenes/FloorMapTab/SystemCalibrationPage/SimpleCalibrationViewModel.swift (1)
UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (1)
loadCurrentFloorMapInfo(87-89)
UWBViewerSystem/Presentation/Scenes/SensingTab/TrajectoryViewPage/TrajectoryViewModel.swift (2)
UWBViewerSystem/Presentation/Scenes/FloorMapTab/SystemCalibrationPage/SimpleCalibrationViewModel.swift (2)
loadInitialData(169-173)loadAntennaPositions(460-493)UWBViewerSystem/Domain/Repository/PreferenceRepository.swift (2)
getData(254-257)loadCurrentFloorMapInfo(87-89)
🔇 Additional comments (19)
UWBViewerSystem/Domain/Usecase/ObservationDataUsecase.swift (1)
79-87: 初期化子へのPreferenceRepository導入は妥当です依存の明確化・テスト性の向上に寄与しています。
UWBViewerSystem/Domain/Usecase/DataMigrationUsecase.swift (3)
11-22: MigrationフラグのPreferenceRepository移行は適切ですドメインユースケースの責務に集中できています。
110-112: UserDefaultsキー確認("sensingSessions")
リポジトリ検索で参照は削除箇所(UWBViewerSystem/Domain/Usecase/DataMigrationUsecase.swift:111)のみでした。旧バージョンや別モジュールで使われていないか、実際に保存されるデータかを確認してください。
48-49: 移行完了フラグ書き込みはOK — migrationKeyの一貫利用を全コードベースで確認してください
場所: UWBViewerSystem/Domain/Usecase/DataMigrationUsecase.swift(48–49)
自動検索で関連参照が見つかりませんでした。migrationKeyの重複・誤綴りがないか、リポジトリ全体で 'migrationKey' と 'setMigrationCompleted'(および既存の完了フラグ名)を検索して確認してください。UWBViewerSystem/Presentation/Scenes/SensingTab/SensingManagementPage/SensingManagementViewModel.swift (2)
18-22: DI対応の方針は適切ですUseCaseとPreferenceRepositoryの明示注入で責務が明確になっています。
30-35: 初期化子の拡張も妥当です既存呼び出しへの影響を最小化しつつ拡張できています。
UWBViewerSystem/Presentation/Scenes/SensingTab/SensingViewModel.swift (1)
30-34: PreferenceRepositoryの導入は適切です参照の集中で将来のストア変更にも強くなります。
UWBViewerSystem/Presentation/Scenes/SensingTab/TrajectoryViewPage/TrajectoryViewModel.swift (2)
50-55: DI導入と初期データ読み込みの整理は良いです初期化時のロードで画面表示の初期状態が安定します。
127-143: アンテナ位置のRepository読込は適切です座標→画面座標変換も分離されていて読みやすいです。
UWBViewerSystem/Presentation/Scenes/SensingTab/DataCollectionPage/DataCollectionViewModel.swift (1)
23-27: DI導入は妥当ですUseCase/Repositoryの直接注入への移行は明確で影響範囲も限定的。デフォルト引数で後方互換も担保できています。
Also applies to: 32-34, 43-43
UWBViewerSystem/Presentation/Scenes/FloorMapTab/FloorMapViewModel.swift (3)
65-69: PreferenceRepositoryのDI導入は適切です初期化子の簡潔さとデフォルト実装の提供が良いです。
161-175: フォールバック時の復元ロジックは妥当ですRepository状態のトレース出力とselectedFloorMapの同期まで一貫しています。
209-214: 変更通知の発行は適切ですRepository更新後にNotificationを飛ばしており、依存側の同期に有用です。
UWBViewerSystem/Presentation/Scenes/FloorMapTab/FloorMapSettingPage/FloorMapSettingViewModel.swift (2)
18-18: DI導入は適切ですPreferenceRepositoryの注入でテスト容易性が向上しています。
Also applies to: 68-73
254-272: 設定値の読み戻しはOKnil/空文字の扱いと既定値維持の方針が明確です。
UWBViewerSystem/Presentation/Scenes/SensingTab/ConnectionManagementPage/ConnectionManagementViewModel.swift (1)
67-70: RepositoryのDI導入と初期ロードは良いです統計の初期ロードをinit/initializeConnection双方で呼ぶ点も安全側で良いです。
Also applies to: 77-89
UWBViewerSystem/Presentation/Scenes/FloorMapTab/SystemCalibrationPage/SimpleCalibrationViewModel.swift (2)
140-146: PreferenceRepositoryのDI導入はOK初期データロードの流れと整合しています。
309-340: 確認済: FloorMapInfo.image は拡張で計算プロパティ(Codable に含まれない)FloorMapInfo は CommonTypes.swift に定義され、プラットフォーム別 extension で image (NSImage?/UIImage?) が計算プロパティとして実装されているため、Codable のエンコード対象ではなく現在の参照は問題ありません。
場所: UWBViewerSystem/Domain/Entity/CommonTypes.swiftUWBViewerSystem/Domain/Repository/PreferenceRepository.swift (1)
87-107: lastFloorSettingsのOptional復元方針は妥当0初期化を避け、未設定を明確化できています。現状の実装で問題ありません。
## 変更内容 - PreferenceRepositoryProtocol/PreferenceRepositoryを新規作成し、UserDefaultsアクセスを抽象化 - 主要ViewModelクラス(FloorMapSettingViewModel、FloorMapViewModel、SimpleCalibrationViewModel等)での依存性注入対応 - UsecaseクラスでのUserDefaults直接アクセスをPreferenceRepository経由に変更 - テストファイルの依存性注入対応 ## 技術的改善 - Clean Architectureの原則に従ったRepository層の分離 - プロトコル指向プログラミングによるテスタビリティの向上 - 依存性注入パターンの適用で疎結合なアーキテクチャを実現 ## 検証済み - ビルド成功確認 - アプリケーション起動確認完了 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
…vationDataUsecaseに包括的なSwiftDocコメントを追加 - PreferenceRepositoryProtocol: アプリケーション設定管理の全メソッドにドキュメント追加 - PreferenceRepository: UserDefaults実装クラスに詳細な設計方針と使用例を追加 - DataMigrationUsecase: データ移行プロセスの説明と冪等性保証の文書化 - ObservationDataUsecase: UWB観測データ収集の包括的なドキュメント追加 - 各メソッドのパラメータ、戻り値、エラーハンドリングを詳細に説明 - 使用例とアーキテクチャにおける位置づけを明記 80%のDocstring Coverageを目指した包括的なドキュメント改善を実施。 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
a7520a6 to
346dedc
Compare
Summary
Issue #3「アーキテクチャ違反の修正」に対応し、ViewModelからUserDefaultsへの直接アクセス(68箇所)をClean Architectureに準拠したPreferenceRepositoryパターンに修正しました。
Key Changes
PreferenceRepositoryProtocol/PreferenceRepositoryを新規作成
主要ViewModelクラスの依存性注入対応
Usecaseクラスの修正
テスト対応
Technical Improvements
Test Plan
🤖 Generated with Claude Code
Summary by CodeRabbit
改善
リファクタリング