diff --git a/.github/workflows/ci_local_package.yml b/.github/workflows/ci_local_package.yml
new file mode 100644
index 00000000..eb4bf418
--- /dev/null
+++ b/.github/workflows/ci_local_package.yml
@@ -0,0 +1,46 @@
+name: local_package_test
+
+on:
+ push:
+ branches: ["main"]
+ paths:
+ - "LocalPackage/**"
+ pull_request:
+ branches: ["**"]
+ paths:
+ - "LocalPackage/**"
+ workflow_dispatch:
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ env:
+ SWIFT_VERSION: "6.2"
+ SWIFT_TOOLCHAIN_DIR: /opt/hostedtoolcache/swift-Ubuntu
+ steps:
+ - uses: actions/checkout@v4.2.2
+
+ - name: Cache Swift toolchain
+ id: cache-swift
+ uses: actions/cache@v4
+ with:
+ path: ${{ env.SWIFT_TOOLCHAIN_DIR }}
+ key: swift-toolchain-${{ runner.os }}-${{ env.SWIFT_VERSION }}
+
+ - name: Setup Swift
+ if: steps.cache-swift.outputs.cache-hit != 'true'
+ uses: swift-actions/setup-swift@v2
+ with:
+ swift-version: ${{ env.SWIFT_VERSION }}
+
+ - name: Restore Swift PATH from cache
+ if: steps.cache-swift.outputs.cache-hit == 'true'
+ run: |
+ SWIFT_BIN=$(find ${{ env.SWIFT_TOOLCHAIN_DIR }} -name swift -type f -path "*/usr/bin/swift" | head -1)
+ echo "$(dirname "$SWIFT_BIN")" >> $GITHUB_PATH
+
+ - name: Show Swift version
+ run: swift --version
+
+ - name: Run tests
+ run: swift test --package-path LocalPackage
diff --git a/.prefire.yml b/.prefire.yml
index 99b43a4a..c65d76b6 100644
--- a/.prefire.yml
+++ b/.prefire.yml
@@ -15,3 +15,5 @@ test_configuration:
- UIKit
- SwiftUI
- MultipeerConnectivity
+ - HometeDomain
+
diff --git a/CI.xctestplan b/CI.xctestplan
index d3e9b3f6..410271cc 100644
--- a/CI.xctestplan
+++ b/CI.xctestplan
@@ -31,13 +31,6 @@
"identifier" : "BC1BB2672E909B8C001D168F",
"name" : "hometeSnapshotTests"
}
- },
- {
- "target" : {
- "containerPath" : "container:homete.xcodeproj",
- "identifier" : "BCC854012DB74BBF00C9A44B",
- "name" : "hometeTests"
- }
}
],
"version" : 1
diff --git a/LocalPackage/.swiftpm/xcode/xcshareddata/xcschemes/HometeDomain.xcscheme b/LocalPackage/.swiftpm/xcode/xcshareddata/xcschemes/HometeDomain.xcscheme
new file mode 100644
index 00000000..969323f0
--- /dev/null
+++ b/LocalPackage/.swiftpm/xcode/xcshareddata/xcschemes/HometeDomain.xcscheme
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LocalPackage/Package.swift b/LocalPackage/Package.swift
index 51ae1520..27ef927d 100644
--- a/LocalPackage/Package.swift
+++ b/LocalPackage/Package.swift
@@ -5,19 +5,20 @@ import PackageDescription
let package = Package(
name: "LocalPackage",
+ platforms: [.iOS(.v17), .macOS(.v15)],
products: [
.library(
- name: "LocalPackage",
- targets: ["LocalPackage"]
+ name: "HometeDomain",
+ targets: ["HometeDomain"]
),
],
targets: [
.target(
- name: "LocalPackage"
+ name: "HometeDomain"
),
.testTarget(
- name: "LocalPackageTests",
- dependencies: ["LocalPackage"]
+ name: "HometeDomainTests",
+ dependencies: ["HometeDomain"]
),
]
)
diff --git a/LocalPackage/Sources/HometeDomain/Account/Account.swift b/LocalPackage/Sources/HometeDomain/Account/Account.swift
new file mode 100644
index 00000000..d8b5eef0
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Account/Account.swift
@@ -0,0 +1,30 @@
+//
+// Account.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/03.
+//
+
+// TODO: ダミー
+public struct Account: Equatable, Codable, Sendable {
+
+ public let id: String
+ public let userName: String
+ public let fcmToken: String?
+ public let cohabitantId: String?
+
+ public init(id: String, userName: String, fcmToken: String?, cohabitantId: String?) {
+ self.id = id
+ self.userName = userName
+ self.fcmToken = fcmToken
+ self.cohabitantId = cohabitantId
+ }
+}
+
+public extension Account {
+
+ static func initial(auth: AccountAuthResult, userName: UserName, fcmToken: String?) -> Self {
+
+ return .init(id: auth.id, userName: userName.value, fcmToken: fcmToken, cohabitantId: nil)
+ }
+}
diff --git a/homete/Model/Domain/Account/AccountStore.swift b/LocalPackage/Sources/HometeDomain/Account/AccountStore.swift
similarity index 75%
rename from homete/Model/Domain/Account/AccountStore.swift
rename to LocalPackage/Sources/HometeDomain/Account/AccountStore.swift
index 46de8488..e981f6dd 100644
--- a/homete/Model/Domain/Account/AccountStore.swift
+++ b/LocalPackage/Sources/HometeDomain/Account/AccountStore.swift
@@ -5,58 +5,58 @@
// Created by 佐藤汰一 on 2025/08/03.
//
-import SwiftUI
+import Observation
@MainActor
@Observable
-final class AccountStore {
-
- private(set) var account: Account?
-
+public final class AccountStore {
+
+ public private(set) var account: Account?
+
private let accountInfoClient: AccountInfoClient
-
- init(
- appDependencies: AppDependencies,
+
+ public init(
+ accountInfoClient: AccountInfoClient = .previewValue,
account: Account? = nil
) {
-
- accountInfoClient = appDependencies.accountInfoClient
+
+ self.accountInfoClient = accountInfoClient
self.account = account
}
-
+
/// アカウント情報をロードし、オンメモリにキャッシュする
/// - Returns: ロードしたアカウント情報を返す(アカウントがない場合はnilを返す)
@discardableResult
- func load(_ auth: AccountAuthResult) async -> Account? {
-
+ public func load(_ auth: AccountAuthResult) async -> Account? {
+
do {
-
+
account = try await accountInfoClient.fetch(auth.id)
}
catch {
-
+
print("failed to fetch account info: \(error)")
}
-
+
return account
}
-
- func registerAccount(auth: AccountAuthResult, userName: UserName) async throws -> Account {
-
+
+ public func registerAccount(auth: AccountAuthResult, userName: UserName) async throws -> Account {
+
let newAccount = Account(id: auth.id, userName: userName.value, fcmToken: nil, cohabitantId: nil)
try await accountInfoClient.insertOrUpdate(newAccount)
account = newAccount
return newAccount
}
-
- func updateFcmTokenIfNeeded(_ fcmToken: String) async {
-
+
+ public func updateFcmTokenIfNeeded(_ fcmToken: String) async {
+
// 保持しているFCMトークンと異なるFCMトークンに変わった場合は、アカウント情報も新しいトークンに更新する
guard let account,
account.fcmToken != fcmToken else { return }
-
+
do {
-
+
let updatedAccount = Account(
id: account.id,
userName: account.userName,
@@ -67,18 +67,18 @@ final class AccountStore {
self.account = updatedAccount
}
catch {
-
+
print("failed to update fcmToken: \(error)")
}
}
-
- func registerCohabitantId(_ cohabitantId: String) async throws {
-
+
+ public func registerCohabitantId(_ cohabitantId: String) async throws {
+
guard let account else {
-
+
preconditionFailure("Not found account.")
}
-
+
let updatedAccount = Account(
id: account.id,
userName: account.userName,
diff --git a/LocalPackage/Sources/HometeDomain/Account/LoginContext.swift b/LocalPackage/Sources/HometeDomain/Account/LoginContext.swift
new file mode 100644
index 00000000..0b2149b5
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Account/LoginContext.swift
@@ -0,0 +1,18 @@
+//
+// LoginContext.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/12/27.
+//
+
+public struct LoginContext: Equatable {
+
+ public let account: Account
+
+ /// パートナー登録済みかどうか
+ public var hasCohabitant: Bool { account.cohabitantId != nil }
+
+ public init(account: Account) {
+ self.account = account
+ }
+}
diff --git a/homete/Model/Domain/Account/UserName.swift b/LocalPackage/Sources/HometeDomain/Account/UserName.swift
similarity index 54%
rename from homete/Model/Domain/Account/UserName.swift
rename to LocalPackage/Sources/HometeDomain/Account/UserName.swift
index efa58f02..0c6ce812 100644
--- a/homete/Model/Domain/Account/UserName.swift
+++ b/LocalPackage/Sources/HometeDomain/Account/UserName.swift
@@ -5,20 +5,24 @@
// Created by 佐藤汰一 on 2025/12/27.
//
-struct UserName {
- var value = ""
-
+public struct UserName {
+ public var value = ""
+
private static let limitCharacters = 10
-
- var remainingCharacters: Int {
+
+ public var remainingCharacters: Int {
return Self.limitCharacters - value.count
}
-
- var isOverLimitCharacters: Bool {
+
+ public var isOverLimitCharacters: Bool {
return Self.limitCharacters < value.count
}
-
- var canRegistration: Bool {
+
+ public var canRegistration: Bool {
return !value.isEmpty && !isOverLimitCharacters
}
+
+ public init(value: String = "") {
+ self.value = value
+ }
}
diff --git a/homete/Model/Domain/AnalyticsLog/AnalyticsEvent.swift b/LocalPackage/Sources/HometeDomain/AnalyticsLog/AnalyticsEvent.swift
similarity index 65%
rename from homete/Model/Domain/AnalyticsLog/AnalyticsEvent.swift
rename to LocalPackage/Sources/HometeDomain/AnalyticsLog/AnalyticsEvent.swift
index ec4d480b..03d6b11a 100644
--- a/homete/Model/Domain/AnalyticsLog/AnalyticsEvent.swift
+++ b/LocalPackage/Sources/HometeDomain/AnalyticsLog/AnalyticsEvent.swift
@@ -5,32 +5,37 @@
// Created by 佐藤汰一 on 2025/08/09.
//
-struct AnalyticsEvent: Equatable {
-
- let name: String
- let parameters: [String: String]
+public struct AnalyticsEvent: Equatable {
+
+ public let name: String
+ public let parameters: [String: String]
+
+ public init(name: String, parameters: [String: String]) {
+ self.name = name
+ self.parameters = parameters
+ }
}
-extension AnalyticsEvent {
-
+public extension AnalyticsEvent {
+
static func login(isSuccess: Bool) -> Self {
-
+
return .init(
name: "login",
parameters: ["isSuccess": "\(isSuccess)"]
)
}
-
+
static func logout() -> Self {
-
+
return .init(
name: "logout",
parameters: [:]
)
}
-
+
static func deleteAccount() -> Self {
-
+
return .init(
name: "delete_account",
parameters: [:]
diff --git a/LocalPackage/Sources/HometeDomain/Authentification/AccountAuthInfo.swift b/LocalPackage/Sources/HometeDomain/Authentification/AccountAuthInfo.swift
new file mode 100644
index 00000000..a8a47220
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Authentification/AccountAuthInfo.swift
@@ -0,0 +1,18 @@
+//
+// AccountAuthInfo.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/12/31.
+//
+
+public struct AccountAuthInfo: Equatable, Sendable {
+ public let result: AccountAuthResult?
+ public let alreadyLoadedAtInitiate: Bool
+
+ public static let initial = AccountAuthInfo(result: nil, alreadyLoadedAtInitiate: false)
+
+ public init(result: AccountAuthResult?, alreadyLoadedAtInitiate: Bool) {
+ self.result = result
+ self.alreadyLoadedAtInitiate = alreadyLoadedAtInitiate
+ }
+}
diff --git a/LocalPackage/Sources/HometeDomain/Authentification/AccountAuthResult.swift b/LocalPackage/Sources/HometeDomain/Authentification/AccountAuthResult.swift
new file mode 100644
index 00000000..d6504897
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Authentification/AccountAuthResult.swift
@@ -0,0 +1,15 @@
+//
+// AccountAuthResult.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/09.
+//
+
+public struct AccountAuthResult: Equatable, Sendable {
+
+ public let id: String
+
+ public init(id: String) {
+ self.id = id
+ }
+}
diff --git a/homete/Model/Domain/Authentification/AccountAuthStore.swift b/LocalPackage/Sources/HometeDomain/Authentification/AccountAuthStore.swift
similarity index 72%
rename from homete/Model/Domain/Authentification/AccountAuthStore.swift
rename to LocalPackage/Sources/HometeDomain/Authentification/AccountAuthStore.swift
index 8b7b4659..86e290d2 100644
--- a/homete/Model/Domain/Authentification/AccountAuthStore.swift
+++ b/LocalPackage/Sources/HometeDomain/Authentification/AccountAuthStore.swift
@@ -5,96 +5,99 @@
// Created by 佐藤汰一 on 2025/08/09.
//
-import SwiftUI
+import Observation
@MainActor
@Observable
-final class AccountAuthStore {
-
- private(set) var currentAuth: AccountAuthInfo
-
+public final class AccountAuthStore {
+
+ public private(set) var currentAuth: AccountAuthInfo
+
private let accountAuthClient: AccountAuthClient
private let analyticsClient: AnalyticsClient
private let signInWithAppleClient: SignInWithAppleClient
private let nonceGenerationClient: NonceGenerationClient
private let listener: AccountListenerStream
-
- init(
- appDependencies: AppDependencies,
+
+ public init(
+ accountAuthClient: AccountAuthClient = .previewValue,
+ analyticsClient: AnalyticsClient = .previewValue,
+ signInWithAppleClient: SignInWithAppleClient = .previewValue,
+ nonceGenerationClient: NonceGenerationClient = .previewValue,
currentAuth: AccountAuthInfo = .initial
) {
-
- accountAuthClient = appDependencies.accountAuthClient
- analyticsClient = appDependencies.analyticsClient
- signInWithAppleClient = appDependencies.signInWithAppleClient
- nonceGenerationClient = appDependencies.nonceGeneratorClient
+
+ self.accountAuthClient = accountAuthClient
+ self.analyticsClient = analyticsClient
+ self.signInWithAppleClient = signInWithAppleClient
+ self.nonceGenerationClient = nonceGenerationClient
self.currentAuth = currentAuth
-
+
listener = accountAuthClient.makeListener()
-
+
Task {
-
+
await listen()
}
}
-
- func login(_ signInResult: SignInWithAppleResult) async throws {
-
+
+ public func login(_ signInResult: SignInWithAppleResult) async throws {
+
do {
-
+
let authInfo = try await accountAuthClient.signIn(signInResult.tokenId, signInResult.nonce)
analyticsClient.setId(authInfo.id)
analyticsClient.log(.login(isSuccess: true))
}
catch {
-
+
analyticsClient.log(.login(isSuccess: false))
throw error
}
}
-
- func logOut() {
-
+
+ public func logOut() {
+
currentAuth = .init(result: nil, alreadyLoadedAtInitiate: true)
analyticsClient.log(.logout())
-
+
do {
-
+
try accountAuthClient.signOut()
}
catch {
-
+
print("occurred error: \(error)")
}
}
-
- func deleteAccount() async throws {
-
+
+ public func deleteAccount() async throws {
+
// 1. 再認証
let nonce = nonceGenerationClient()
let signInWithAppleResult = try await signInWithAppleClient.reauthentication(nonce)
try await accountAuthClient.reauthenticateWithApple(signInWithAppleResult)
-
+
// 2. アカウント削除
try await accountAuthClient.deleteAccount()
-
+
// 3. トークンRevoke
try await accountAuthClient.revokeAppleToken(signInWithAppleResult.authorizationCode)
-
+
// 4. ログ記録
analyticsClient.log(.deleteAccount())
-
+
// 5. 状態更新
currentAuth = .init(result: nil, alreadyLoadedAtInitiate: true)
}
}
private extension AccountAuthStore {
-
+
func listen() async {
-
+
for await value in listener.values {
-
+
currentAuth = .init(result: value, alreadyLoadedAtInitiate: true)
print("currentAuth snapshot: \(String(describing: currentAuth))")
}
diff --git a/homete/Model/Domain/Authentification/AccountListenerStream.swift b/LocalPackage/Sources/HometeDomain/Authentification/AccountListenerStream.swift
similarity index 72%
rename from homete/Model/Domain/Authentification/AccountListenerStream.swift
rename to LocalPackage/Sources/HometeDomain/Authentification/AccountListenerStream.swift
index 743b3f71..3db9c180 100644
--- a/homete/Model/Domain/Authentification/AccountListenerStream.swift
+++ b/LocalPackage/Sources/HometeDomain/Authentification/AccountListenerStream.swift
@@ -7,25 +7,25 @@
import Foundation
-struct AccountListenerStream {
-
- let values: AsyncStream
- let listenerToken: any NSObjectProtocol
+public struct AccountListenerStream {
+
+ public let values: AsyncStream
+ public let listenerToken: any NSObjectProtocol
private let continuation: AsyncStream.Continuation
-
- init(
+
+ public init(
values: AsyncStream,
listenerToken: any NSObjectProtocol,
continuation: AsyncStream.Continuation
) {
-
+
self.values = values
self.listenerToken = listenerToken
self.continuation = continuation
}
-
- func stopListening() {
-
+
+ public func stopListening() {
+
continuation.finish()
}
}
diff --git a/homete/Model/Domain/Authentification/LaunchState.swift b/LocalPackage/Sources/HometeDomain/Authentification/LaunchState.swift
similarity index 84%
rename from homete/Model/Domain/Authentification/LaunchState.swift
rename to LocalPackage/Sources/HometeDomain/Authentification/LaunchState.swift
index 73625e46..c88f346f 100644
--- a/homete/Model/Domain/Authentification/LaunchState.swift
+++ b/LocalPackage/Sources/HometeDomain/Authentification/LaunchState.swift
@@ -5,8 +5,8 @@
// Created by 佐藤汰一 on 2025/09/02.
//
-enum LaunchState: Equatable {
-
+public enum LaunchState: Equatable {
+
/// 起動中
case launching
/// 仮ログイン(アカウント未作成)
@@ -15,9 +15,9 @@ enum LaunchState: Equatable {
case loggedIn(context: LoginContext)
/// 未ログイン
case notLoggedIn
-
- var isLoggedIn: Bool {
-
+
+ public var isLoggedIn: Bool {
+
if case .loggedIn = self { return true }
return false
}
diff --git a/LocalPackage/Sources/HometeDomain/Authentification/SignInWithAppleNonce.swift b/LocalPackage/Sources/HometeDomain/Authentification/SignInWithAppleNonce.swift
new file mode 100644
index 00000000..da647668
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Authentification/SignInWithAppleNonce.swift
@@ -0,0 +1,17 @@
+//
+// SignInWithAppleNonce.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/04.
+//
+
+public struct SignInWithAppleNonce: Equatable, Sendable {
+
+ public let original: String
+ public let sha256: String
+
+ public init(original: String, sha256: String) {
+ self.original = original
+ self.sha256 = sha256
+ }
+}
diff --git a/LocalPackage/Sources/HometeDomain/Authentification/SignInWithAppleResult.swift b/LocalPackage/Sources/HometeDomain/Authentification/SignInWithAppleResult.swift
new file mode 100644
index 00000000..94fd6670
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Authentification/SignInWithAppleResult.swift
@@ -0,0 +1,19 @@
+//
+// SignInWithAppleResult.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/09.
+//
+
+public struct SignInWithAppleResult: Equatable, Sendable {
+
+ public let tokenId: String
+ public let nonce: String
+ public let authorizationCode: String
+
+ public init(tokenId: String, nonce: String, authorizationCode: String) {
+ self.tokenId = tokenId
+ self.nonce = nonce
+ self.authorizationCode = authorizationCode
+ }
+}
diff --git a/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantData.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantData.swift
new file mode 100644
index 00000000..c035c421
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantData.swift
@@ -0,0 +1,21 @@
+//
+// CohabitantData.swift
+// homete
+//
+// Created by 佐藤汰一 on 2026/01/04.
+//
+
+public struct CohabitantData: Codable, Sendable {
+
+ public static let idField = "id"
+
+ /// 家族グループのID
+ public let id: String
+ /// 参加しているメンバーのユーザーID
+ public let members: [String]
+
+ public init(id: String, members: [String]) {
+ self.id = id
+ self.members = members
+ }
+}
diff --git a/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantMember.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantMember.swift
new file mode 100644
index 00000000..0ad8d2f8
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantMember.swift
@@ -0,0 +1,19 @@
+//
+// CohabitantMember.swift
+// homete
+//
+// Created by 佐藤汰一 on 2026/01/04.
+//
+
+public struct CohabitantMember: Equatable, Hashable, Sendable {
+
+ /// メンバーのユーザーID
+ public let id: String
+ /// メンバーのユーザー名
+ public let userName: String
+
+ public init(id: String, userName: String) {
+ self.id = id
+ self.userName = userName
+ }
+}
diff --git a/homete/Model/Domain/Cohabitant/CohabitantMemberList.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantMemberList.swift
similarity index 65%
rename from homete/Model/Domain/Cohabitant/CohabitantMemberList.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantMemberList.swift
index 6f1591b4..7f2afcc0 100644
--- a/homete/Model/Domain/Cohabitant/CohabitantMemberList.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantMemberList.swift
@@ -5,29 +5,33 @@
// Created by 佐藤汰一 on 2026/01/04.
//
-struct CohabitantMemberList {
-
- private(set) var value: Set
-
- mutating func insert(_ element: CohabitantMember) {
-
+public struct CohabitantMemberList: Sendable {
+
+ public private(set) var value: Set
+
+ public init(value: Set) {
+ self.value = value
+ }
+
+ public mutating func insert(_ element: CohabitantMember) {
+
value.insert(element)
}
-
+
/// 与えられたユーザーID配列の中から、まだvalueに存在しないユーザーIDのみを返します。
/// - Parameter userIds: 追加するユーザーIDの候補の配列
/// - Returns: 追加が必要なユーザーIDの配列
- func missingMemberIds(from userIds: Set) -> Set {
-
+ public func missingMemberIds(from userIds: Set) -> Set {
+
let existingIds = value.map(\.id)
return userIds.filter { !existingIds.contains($0) }
}
-
+
/// 現在の家族グループの中から指定のユーザーIDの名前を取得する
/// - Parameter id: ユーザーID
/// - Returns: ユーザー名
- func userName(_ id: String) -> String? {
-
+ public func userName(_ id: String) -> String? {
+
return value.first { $0.id == id }?.userName
}
}
diff --git a/homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationMessage.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationMessage.swift
similarity index 74%
rename from homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationMessage.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationMessage.swift
index 8f99b3e7..ac9983be 100644
--- a/homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationMessage.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationMessage.swift
@@ -7,12 +7,12 @@
import Foundation
-struct CohabitantRegistrationMessage: Codable, Equatable {
-
- let type: CommunicateType
-
- enum CommunicateType: Codable, Equatable {
-
+public struct CohabitantRegistrationMessage: Codable, Equatable, Sendable {
+
+ public let type: CommunicateType
+
+ public enum CommunicateType: Codable, Equatable, Sendable {
+
/// 登録を行うメンバーが確定したかどうかの確認
case fixedMember(isOK: Bool)
/// アカウントIDの共有
@@ -22,62 +22,66 @@ struct CohabitantRegistrationMessage: Codable, Equatable {
/// 登録完了したかどうかの確認
case complete
}
-
+
/// 登録メンバーが確定したかどうか
- var isFixedMember: Bool? {
-
+ public var isFixedMember: Bool? {
+
guard case .fixedMember(let isOK) = type else {
return nil
}
return isOK
}
-
+
/// メンバーの役割
- var memberRole: CohabitantRegistrationRole? {
-
+ public var memberRole: CohabitantRegistrationRole? {
+
guard case .preRegistration(let role) = type else {
-
+
return nil
}
return role
}
-
+
/// 同居人ID
- var cohabitantId: String? {
-
+ public var cohabitantId: String? {
+
guard case .shareCohabitantId(let id) = type else {
-
+
return nil
}
return id
}
-
+
/// 登録処理が完了したかどうか
- var isComplete: Bool? {
-
+ public var isComplete: Bool? {
+
guard case .complete = type else {
-
+
return nil
}
return true
}
-
- func encodedData() -> Data {
-
+
+ public func encodedData() -> Data {
+
guard let encodedData = try? JSONEncoder().encode(self) else {
-
+
preconditionFailure("Invalid message structure(\(self)).")
}
return encodedData
}
+
+ public init(type: CommunicateType) {
+ self.type = type
+ }
}
-extension CohabitantRegistrationMessage {
-
+public extension CohabitantRegistrationMessage {
+
init(_ data: Data) {
-
+
guard let message = try? JSONDecoder().decode(CohabitantRegistrationMessage.self, from: data) else {
-
+
preconditionFailure("Invalid data(\(data)).")
}
self = message
diff --git a/homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationRole.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationRole.swift
similarity index 73%
rename from homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationRole.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationRole.swift
index fd95989f..497580d9 100644
--- a/homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationRole.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationRole.swift
@@ -5,21 +5,21 @@
// Created by 佐藤汰一 on 2025/08/30.
//
-enum CohabitantRegistrationRole: Codable, Equatable {
-
+public enum CohabitantRegistrationRole: Codable, Equatable, Sendable {
+
/// フォロワーはアカウントIDを渡す
case follower(accountId: String)
case lead
-
- var isLeader: Bool {
-
+
+ public var isLeader: Bool {
+
return self == .lead
}
-
- var accountId: String {
-
+
+ public var accountId: String {
+
guard case let .follower(accountId) = self else {
-
+
preconditionFailure("Please pre checking role is follower.")
}
return accountId
diff --git a/homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationState.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationState.swift
similarity index 86%
rename from homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationState.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationState.swift
index c14cf40c..16d813d9 100644
--- a/homete/Model/Domain/Cohabitant/CohabitantRegistration/CohabitantRegistrationState.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/CohabitantRegistrationState.swift
@@ -5,8 +5,8 @@
// Created by 佐藤汰一 on 2025/08/26.
//
-enum CohabitantRegistrationState: Equatable {
-
+public enum CohabitantRegistrationState: Equatable {
+
/// 同居人となるメンバーを探している状態
case scanning
/// 同居人を登録する処理を行っている状態
diff --git a/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/ConfirmedRegistrationPeers.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/ConfirmedRegistrationPeers.swift
new file mode 100644
index 00000000..03d5c768
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantRegistration/ConfirmedRegistrationPeers.swift
@@ -0,0 +1,33 @@
+//
+// ConfirmedRegistrationPeers.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/30.
+//
+
+#if canImport(MultipeerConnectivity)
+import MultipeerConnectivity
+
+public struct ConfirmedRegistrationPeers: Equatable {
+
+ private var peers: Set
+
+ public init(peers: Set) {
+
+ self.peers = peers
+ }
+
+ public mutating func addPeer(_ peer: MCPeerID) {
+
+ peers.insert(peer)
+ }
+
+ public func isLeadPeer(connectedPeers: Set, myPeerID: MCPeerID) -> Bool? {
+
+ guard peers == connectedPeers else { return nil }
+ let firstPeerID = ([myPeerID] + connectedPeers)
+ .sorted { $0.displayName < $1.displayName }.first
+ return firstPeerID == myPeerID
+ }
+}
+#endif
diff --git a/homete/Model/Domain/Cohabitant/CohabitantStore.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantStore.swift
similarity index 72%
rename from homete/Model/Domain/Cohabitant/CohabitantStore.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantStore.swift
index 08d56c7a..250234f3 100644
--- a/homete/Model/Domain/Cohabitant/CohabitantStore.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/CohabitantStore.swift
@@ -5,70 +5,74 @@
// Created by 佐藤汰一 on 2026/01/04.
//
-import SwiftUI
+import Observation
@MainActor
@Observable
-final class CohabitantStore {
-
- private(set) var members: CohabitantMemberList
+public final class CohabitantStore {
+
+ public private(set) var members: CohabitantMemberList
private var listenerTask: Task?
-
+
private let cohabitantListenerKey = "cohabitantListenerKey"
-
+
// MARK: Dependencies
-
+
private let cohabitantClient: CohabitantClient
private let accountInfoClient: AccountInfoClient
-
- init(
+
+ public init(
members: CohabitantMemberList = .init(value: []),
- appDependencies: AppDependencies = .previewValue
+ cohabitantClient: CohabitantClient = .previewValue,
+ accountInfoClient: AccountInfoClient = .previewValue
) {
+
self.members = members
- cohabitantClient = appDependencies.cohabitantClient
- accountInfoClient = appDependencies.accountInfoClient
+ self.cohabitantClient = cohabitantClient
+ self.accountInfoClient = accountInfoClient
}
-
- func addSnapshotListenerIfNeeded(_ cohabitantId: String) async {
-
+
+ public func addSnapshotListenerIfNeeded(_ cohabitantId: String) async {
+
// すでに監視中の場合は何もしない
if listenerTask != nil { return }
-
+
let stream = await cohabitantClient.addSnapshotListener(
cohabitantListenerKey,
cohabitantId
)
-
+
listenerTask = Task {
-
+
for await cohabitantDataList in stream {
-
+
guard let cohabitantData = cohabitantDataList.first else { continue }
-
+
for member in self.members.missingMemberIds(from: .init(cohabitantData.members)) {
-
+
do {
-
+
guard let account = try await accountInfoClient.fetch(member) else {
-
+
print("Not found account(cohabitantId: \(cohabitantId), userId: \(member))")
continue
}
members.insert(.init(id: member, userName: account.userName))
} catch {
-
+
print("error occurred: \(error)")
}
}
}
-
+
print("finish listening cohabitant snapshot.")
}
}
-
- func removeSnapshotListener() async {
-
+
+ public func removeSnapshotListener() async {
+
+ listenerTask?.cancel()
+ await listenerTask?.value
listenerTask = nil
await cohabitantClient.removeSnapshotListener(cohabitantListenerKey)
}
diff --git a/homete/Model/Domain/Cohabitant/Housework/DailyHouseworkList.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/DailyHouseworkList.swift
similarity index 55%
rename from homete/Model/Domain/Cohabitant/Housework/DailyHouseworkList.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/DailyHouseworkList.swift
index c4a5d194..ef459b50 100644
--- a/homete/Model/Domain/Cohabitant/Housework/DailyHouseworkList.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/DailyHouseworkList.swift
@@ -7,29 +7,34 @@
import Foundation
-struct DailyHouseworkList: Equatable, Sendable {
-
- let items: [HouseworkItem]
- let metaData: DailyHouseworkMetaData
-
- static func makeInitialValue(
+public struct DailyHouseworkList: Equatable, Sendable {
+
+ public let items: [HouseworkItem]
+ public let metaData: DailyHouseworkMetaData
+
+ public static func makeInitialValue(
selectedDate: Date,
items: [HouseworkItem],
calendar: Calendar
) -> Self {
-
+
return .init(
items: items,
metaData: .init(selectedDate: selectedDate, calendar: calendar)
)
}
-
+
/// この日付の家事情報がすでに登録済みであること
- var isRegistered: Bool { !items.isEmpty }
-
+ public var isRegistered: Bool { !items.isEmpty }
+
/// すでに同じ家事が登録されているかどうか
- func isAlreadyRegistered(_ item: HouseworkItem) -> Bool {
-
+ public func isAlreadyRegistered(_ item: HouseworkItem) -> Bool {
+
return items.contains { $0.title == item.title }
}
+
+ public init(items: [HouseworkItem], metaData: DailyHouseworkMetaData) {
+ self.items = items
+ self.metaData = metaData
+ }
}
diff --git a/homete/Model/Domain/Cohabitant/Housework/DailyHouseworkMetaData.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/DailyHouseworkMetaData.swift
similarity index 55%
rename from homete/Model/Domain/Cohabitant/Housework/DailyHouseworkMetaData.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/DailyHouseworkMetaData.swift
index 54d59c20..89936bb5 100644
--- a/homete/Model/Domain/Cohabitant/Housework/DailyHouseworkMetaData.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/DailyHouseworkMetaData.swift
@@ -7,16 +7,21 @@
import Foundation
-struct DailyHouseworkMetaData: Equatable {
-
- let indexedDate: HouseworkIndexedDate
- let expiredAt: Date
+public struct DailyHouseworkMetaData: Equatable, Sendable {
+
+ public let indexedDate: HouseworkIndexedDate
+ public let expiredAt: Date
+
+ public init(indexedDate: HouseworkIndexedDate, expiredAt: Date) {
+ self.indexedDate = indexedDate
+ self.expiredAt = expiredAt
+ }
}
-extension DailyHouseworkMetaData {
-
+public extension DailyHouseworkMetaData {
+
init(selectedDate: Date, calendar: Calendar) {
-
+
let indexedDate = HouseworkIndexedDate(selectedDate, calendar: calendar)
let expiredAt = calendar.date(byAdding: .month, value: 1, to: selectedDate) ?? selectedDate
self.init(indexedDate: indexedDate, expiredAt: expiredAt)
diff --git a/homete/Model/Domain/Cohabitant/Housework/HouseworkBoardList.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkBoardList.swift
similarity index 64%
rename from homete/Model/Domain/Cohabitant/Housework/HouseworkBoardList.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkBoardList.swift
index abbf5571..7910eb9b 100644
--- a/homete/Model/Domain/Cohabitant/Housework/HouseworkBoardList.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkBoardList.swift
@@ -7,24 +7,28 @@
import Foundation
-struct HouseworkBoardList: Equatable {
-
- private(set) var items: [HouseworkItem]
-
- func items(matching state: HouseworkState) -> [HouseworkItem] {
+public struct HouseworkBoardList: Equatable {
+
+ public private(set) var items: [HouseworkItem]
+
+ public func items(matching state: HouseworkState) -> [HouseworkItem] {
print("HouseworkBoardList filtering(state: \(state), items: \(items))")
return items.filter { $0.state == state }
}
+
+ public init(items: [HouseworkItem]) {
+ self.items = items
+ }
}
-extension HouseworkBoardList {
-
+public extension HouseworkBoardList {
+
init(
dailyList: [DailyHouseworkList],
selectedDate: Date,
calendar: Calendar
) {
-
+
items = dailyList
.first {
$0.metaData.indexedDate == .init(selectedDate, calendar: calendar)
diff --git a/homete/Model/Domain/Cohabitant/Housework/HouseworkHistoryList.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkHistoryList.swift
similarity index 76%
rename from homete/Model/Domain/Cohabitant/Housework/HouseworkHistoryList.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkHistoryList.swift
index 567d0d50..485dd5e9 100644
--- a/homete/Model/Domain/Cohabitant/Housework/HouseworkHistoryList.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkHistoryList.swift
@@ -7,30 +7,34 @@
import Foundation
-struct HouseworkHistoryList: Equatable {
-
- private(set) var items: [String]
-
+public struct HouseworkHistoryList: Equatable {
+
+ public private(set) var items: [String]
+
+ public init(items: [String]) {
+ self.items = items
+ }
+
/// 履歴があるかどうか
- var hasHistory: Bool { !items.isEmpty }
-
+ public var hasHistory: Bool { !items.isEmpty }
+
/// 引数に受け取った文字列が `items` に存在する場合、その要素を先頭へ移動します。
/// - Parameter value: 先頭へ移動したい要素の文字列
- mutating func moveToFrontIfExists(_ value: String) {
-
+ public mutating func moveToFrontIfExists(_ value: String) {
+
guard let index = items.firstIndex(of: value) else { return }
// 既に先頭なら何もしない
if index == items.startIndex { return }
let element = items.remove(at: index)
items.insert(element, at: 0)
}
-
+
/// 引数に受け取った文字列を `items`の先頭に追加する
/// - Parameter value: 新しい履歴文字
- mutating func addNewHistory(_ value: String) {
-
+ public mutating func addNewHistory(_ value: String) {
+
guard items.contains(value) else {
-
+
items.insert(value, at: 0)
return
}
@@ -39,40 +43,40 @@ struct HouseworkHistoryList: Equatable {
}
extension HouseworkHistoryList: Codable {
-
+
enum CodingKeys: String, CodingKey {
case items
}
-
- func encode(to encoder: any Encoder) throws {
+
+ public func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(items, forKey: .items)
}
-
- init(from decoder: any Decoder) throws {
+
+ public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
items = try container.decode(Array.self, forKey: .items)
}
}
extension HouseworkHistoryList: RawRepresentable {
-
- init?(rawValue: String) {
-
+
+ public init?(rawValue: String) {
+
guard let data = rawValue.data(using: .utf8),
let decoded = try? JSONDecoder().decode(HouseworkHistoryList.self, from: data) else {
-
+
return nil
}
self = decoded
}
-
- var rawValue: String {
-
+
+ public var rawValue: String {
+
guard
let data = try? JSONEncoder().encode(self),
let jsonString = String(data: data, encoding: .utf8) else {
-
+
return ""
}
return jsonString
diff --git a/homete/Model/Domain/Cohabitant/Housework/HouseworkIndexedDate.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkIndexedDate.swift
similarity index 81%
rename from homete/Model/Domain/Cohabitant/Housework/HouseworkIndexedDate.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkIndexedDate.swift
index 89756700..05fd06a3 100644
--- a/homete/Model/Domain/Cohabitant/Housework/HouseworkIndexedDate.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkIndexedDate.swift
@@ -7,32 +7,36 @@
import Foundation
-struct HouseworkIndexedDate: Equatable, Codable, Hashable {
-
- let value: String
-
- static func calcTargetPeriod(
+public struct HouseworkIndexedDate: Equatable, Codable, Hashable, Sendable {
+
+ public let value: String
+
+ public init(value: String) {
+ self.value = value
+ }
+
+ public static func calcTargetPeriod(
anchorDate: Date,
offsetDays: Int,
calendar: Calendar
) -> [[String: String]] {
-
+
let base = calendar.startOfDay(for: anchorDate)
guard offsetDays >= 0 else {
-
+
return [["value": HouseworkIndexedDate(base, calendar: calendar).value]]
}
// -offset ... +offset の範囲を列挙
return (-offsetDays...offsetDays).compactMap { delta in
-
+
guard let date = calendar.date(byAdding: .day, value: delta, to: base) else { return nil }
return ["value": HouseworkIndexedDate(date, calendar: calendar).value]
}
}
}
-extension HouseworkIndexedDate {
-
+public extension HouseworkIndexedDate {
+
init(_ date: Date, calendar: Calendar) {
let formatStyle = Date.FormatStyle(
date: .numeric,
diff --git a/homete/Model/Domain/Cohabitant/Housework/HouseworkItem.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkItem.swift
similarity index 63%
rename from homete/Model/Domain/Cohabitant/Housework/HouseworkItem.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkItem.swift
index 81310b69..c2d09522 100644
--- a/homete/Model/Domain/Cohabitant/Housework/HouseworkItem.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkItem.swift
@@ -7,43 +7,69 @@
import Foundation
-struct HouseworkItem: Identifiable, Equatable, Sendable, Hashable, Codable {
-
- let id: String
+public struct HouseworkItem: Identifiable, Equatable, Sendable, Hashable, Codable {
+
+ public let id: String
/// 家事の日付情報
- let indexedDate: HouseworkIndexedDate
+ public let indexedDate: HouseworkIndexedDate
/// 家事のタイトル
- let title: String
+ public let title: String
/// 家事ポイント
- let point: Int
+ public let point: Int
/// 家事ステータス
- let state: HouseworkState
+ public let state: HouseworkState
/// 実行者のユーザID
- let executorId: String?
+ public let executorId: String?
/// 実行日時
- let executedAt: Date?
+ public let executedAt: Date?
/// 確認者のユーザID
- let reviewerId: String?
+ public let reviewerId: String?
/// 承認日時
- let approvedAt: Date?
+ public let approvedAt: Date?
/// 確認コメント
- let reviewerComment: String?
+ public let reviewerComment: String?
/// 有効期限
- let expiredAt: Date
-
- var formattedIndexedDate: String {
-
+ public let expiredAt: Date
+
+ public init(
+ id: String,
+ indexedDate: HouseworkIndexedDate,
+ title: String,
+ point: Int,
+ state: HouseworkState,
+ executorId: String?,
+ executedAt: Date?,
+ reviewerId: String?,
+ approvedAt: Date?,
+ reviewerComment: String?,
+ expiredAt: Date
+ ) {
+ self.id = id
+ self.indexedDate = indexedDate
+ self.title = title
+ self.point = point
+ self.state = state
+ self.executorId = executorId
+ self.executedAt = executedAt
+ self.reviewerId = reviewerId
+ self.approvedAt = approvedAt
+ self.reviewerComment = reviewerComment
+ self.expiredAt = expiredAt
+ }
+
+ public var formattedIndexedDate: String {
+
return indexedDate.value
}
-
+
/// レビュー可能かどうか
- func canReview(ownUserId: String) -> Bool {
-
+ public func canReview(ownUserId: String) -> Bool {
+
return executorId != ownUserId && state != .completed
}
-
- func updatePendingApproval(at now: Date, changer: String) -> Self {
-
+
+ public func updatePendingApproval(at now: Date, changer: String) -> Self {
+
return .init(
id: id,
indexedDate: indexedDate,
@@ -58,9 +84,9 @@ struct HouseworkItem: Identifiable, Equatable, Sendable, Hashable, Codable {
expiredAt: expiredAt
)
}
-
- func updateApproved(at now: Date, reviewer: String, comment: String) -> Self {
-
+
+ public func updateApproved(at now: Date, reviewer: String, comment: String) -> Self {
+
return .init(
id: id,
indexedDate: indexedDate,
@@ -75,9 +101,9 @@ struct HouseworkItem: Identifiable, Equatable, Sendable, Hashable, Codable {
expiredAt: expiredAt
)
}
-
- func updateRejected(at now: Date, reviewer: String, comment: String) -> Self {
-
+
+ public func updateRejected(at now: Date, reviewer: String, comment: String) -> Self {
+
return .init(
id: id,
indexedDate: indexedDate,
@@ -92,9 +118,9 @@ struct HouseworkItem: Identifiable, Equatable, Sendable, Hashable, Codable {
expiredAt: expiredAt
)
}
-
- func updateIncomplete() -> Self {
-
+
+ public func updateIncomplete() -> Self {
+
return .init(
id: id,
indexedDate: indexedDate,
@@ -111,8 +137,8 @@ struct HouseworkItem: Identifiable, Equatable, Sendable, Hashable, Codable {
}
}
-extension HouseworkItem {
-
+public extension HouseworkItem {
+
init(
id: String,
title: String,
@@ -125,7 +151,7 @@ extension HouseworkItem {
approvedAt: Date? = nil,
reviewerComment: String? = nil
) {
-
+
self.init(
id: id,
indexedDate: metaData.indexedDate,
diff --git a/homete/Model/Domain/Cohabitant/Housework/HouseworkListStore.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkListStore.swift
similarity index 77%
rename from homete/Model/Domain/Cohabitant/Housework/HouseworkListStore.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkListStore.swift
index 0675b857..d564c152 100644
--- a/homete/Model/Domain/Cohabitant/Housework/HouseworkListStore.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkListStore.swift
@@ -5,56 +5,60 @@
// Created by 佐藤汰一 on 2025/09/27.
//
-import SwiftUI
+import Foundation
+import Observation
@MainActor
@Observable
-final class HouseworkListStore {
-
- private(set) var items: StoredAllHouseworkList
+public final class HouseworkListStore {
+
+ public private(set) var items: StoredAllHouseworkList
private var cohabitantId: String
-
+
+ private var observeTask: Task?
+
private let houseworkClient: HouseworkClient
private let cohabitantPushNotificationClient: CohabitantPushNotificationClient
-
+
private let houseworkObserveKey = "houseworkObserveKey"
-
- init(
+
+ public init(
houseworkClient: HouseworkClient = .previewValue,
cohabitantPushNotificationClient: CohabitantPushNotificationClient = .previewValue,
items: [DailyHouseworkList] = [],
cohabitantId: String = ""
) {
-
+
self.houseworkClient = houseworkClient
self.cohabitantPushNotificationClient = cohabitantPushNotificationClient
self.items = .init(value: items)
self.cohabitantId = cohabitantId
}
-
- func loadHouseworkList(currentTime: Date, cohabitantId: String, calendar: Calendar) async {
-
+
+ public func loadHouseworkList(currentTime: Date, cohabitantId: String, calendar: Calendar) async {
+
self.cohabitantId = cohabitantId
-
+
guard !cohabitantId.isEmpty else {
-
+
await clear()
return
}
-
+
+ observeTask?.cancel()
await houseworkClient.removeListener(houseworkObserveKey)
-
+
let houseworkListStream = await houseworkClient.snapshotListener(
houseworkObserveKey,
cohabitantId,
currentTime,
3
)
-
- Task {
-
+
+ observeTask = Task {
+
for await currentItems in houseworkListStream {
-
+
items = StoredAllHouseworkList.makeMultiDateList(
items: currentItems,
calendar: calendar
@@ -62,19 +66,19 @@ final class HouseworkListStore {
}
}
}
-
- func register(_ newItem: HouseworkItem) async throws {
-
+
+ public func register(_ newItem: HouseworkItem) async throws {
+
try await houseworkClient.insertOrUpdateItem(newItem, cohabitantId)
-
+
Task.detached {
-
+
let notificationContent = PushNotificationContent.addNewHouseworkItem(newItem.title)
try await self.cohabitantPushNotificationClient.send(self.cohabitantId, notificationContent)
}
}
-
- func requestReview(target: HouseworkItem, now: Date, executor: String) async throws {
+
+ public func requestReview(target: HouseworkItem, now: Date, executor: String) async throws {
try await updateAndSave(target: target) {
$0.updatePendingApproval(at: now, changer: executor)
@@ -82,8 +86,8 @@ final class HouseworkListStore {
.requestReviewMessage(houseworkTitle: target.title)
}
}
-
- func approved(target: HouseworkItem, now: Date, reviwer: Account, comment: String) async throws {
+
+ public func approved(target: HouseworkItem, now: Date, reviwer: Account, comment: String) async throws {
try await updateAndSave(target: target) {
$0.updateApproved(at: now, reviewer: reviwer.id, comment: comment)
@@ -92,7 +96,7 @@ final class HouseworkListStore {
}
}
- func rejected(target: HouseworkItem, now: Date, reviwer: Account, comment: String) async throws {
+ public func rejected(target: HouseworkItem, now: Date, reviwer: Account, comment: String) async throws {
try await updateAndSave(target: target) {
$0.updateRejected(at: now, reviewer: reviwer.id, comment: comment)
@@ -101,23 +105,31 @@ final class HouseworkListStore {
}
}
- func returnToIncomplete(target: HouseworkItem) async throws {
+ public func returnToIncomplete(target: HouseworkItem) async throws {
try await updateAndSave(target: target) {
$0.updateIncomplete()
}
}
-
- func remove(_ target: HouseworkItem) async throws {
-
+
+ public func remove(_ target: HouseworkItem) async throws {
+
try await houseworkClient.removeItem(target, cohabitantId)
}
+
+ public func stopObserving() async {
+
+ observeTask?.cancel()
+ await observeTask?.value
+ observeTask = nil
+ }
}
private extension HouseworkListStore {
func clear() async {
+ await stopObserving()
await houseworkClient.removeListener(houseworkObserveKey)
items.removeAll()
}
diff --git a/homete/Model/Domain/Cohabitant/Housework/HouseworkState.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkState.swift
similarity index 58%
rename from homete/Model/Domain/Cohabitant/Housework/HouseworkState.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkState.swift
index 3ed3278d..176b1b1f 100644
--- a/homete/Model/Domain/Cohabitant/Housework/HouseworkState.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/HouseworkState.swift
@@ -5,11 +5,11 @@
// Created by 佐藤汰一 on 2025/09/06.
//
-enum HouseworkState: CaseIterable, Identifiable, Codable, Sendable {
-
+public enum HouseworkState: CaseIterable, Identifiable, Codable, Sendable {
+
case incomplete
case pendingApproval
case completed
-
- var id: Self { self }
+
+ public var id: Self { self }
}
diff --git a/homete/Model/Domain/Cohabitant/Housework/StoredAllHouseworkList.swift b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/StoredAllHouseworkList.swift
similarity index 67%
rename from homete/Model/Domain/Cohabitant/Housework/StoredAllHouseworkList.swift
rename to LocalPackage/Sources/HometeDomain/Cohabitant/Housework/StoredAllHouseworkList.swift
index 0758c3bc..50c7a737 100644
--- a/homete/Model/Domain/Cohabitant/Housework/StoredAllHouseworkList.swift
+++ b/LocalPackage/Sources/HometeDomain/Cohabitant/Housework/StoredAllHouseworkList.swift
@@ -7,15 +7,19 @@
import Foundation
-struct StoredAllHouseworkList: Equatable, Sendable {
-
- private(set) var value: [DailyHouseworkList]
-
- static func makeMultiDateList(items: [HouseworkItem], calendar: Calendar) -> Self {
-
+public struct StoredAllHouseworkList: Equatable, Sendable {
+
+ public private(set) var value: [DailyHouseworkList]
+
+ public init(value: [DailyHouseworkList]) {
+ self.value = value
+ }
+
+ public static func makeMultiDateList(items: [HouseworkItem], calendar: Calendar) -> Self {
+
let items: [DailyHouseworkList] = Dictionary(grouping: items) { $0.formattedIndexedDate }
.compactMap {
-
+
guard let firstItem = $1.first else { return nil }
return .init(
items: $1,
@@ -24,17 +28,17 @@ struct StoredAllHouseworkList: Equatable, Sendable {
}
return .init(value: items)
}
-
- func item(_ item: HouseworkItem) -> HouseworkItem? {
-
+
+ public func item(_ item: HouseworkItem) -> HouseworkItem? {
+
guard let targetDayList = value.first(
where: { $0.metaData.indexedDate == item.indexedDate }
),
let targetItem = targetDayList.items.first(where: { $0.id == item.id }) else { return nil }
return targetItem
}
-
- mutating func removeAll() {
+
+ public mutating func removeAll() {
value = []
}
}
diff --git a/LocalPackage/Sources/HometeDomain/Dependencies/AccountAuthClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/AccountAuthClient.swift
new file mode 100644
index 00000000..3ea5fc8d
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/AccountAuthClient.swift
@@ -0,0 +1,45 @@
+//
+// AccountListener.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/03.
+//
+
+import Foundation
+
+public struct AccountAuthClient: Sendable {
+
+ public let signIn: @Sendable (String, String) async throws -> AccountAuthResult
+ public let signOut: @Sendable () throws -> Void
+ public let makeListener: @Sendable () -> AccountListenerStream
+ public let reauthenticateWithApple: @Sendable (_ signInWithAppleResult: SignInWithAppleResult) async throws -> Void
+ public let revokeAppleToken: @Sendable (_ authorizationCode: String) async throws -> Void
+ public let deleteAccount: @Sendable () async throws -> Void
+
+ public init(
+ signIn: @Sendable @escaping (String, String) async throws -> AccountAuthResult = { _, _ in .init(id: "id") },
+ signOut: @Sendable @escaping () throws -> Void = {},
+ makeListener: @Sendable @escaping () -> AccountListenerStream = {
+
+ let (stream, continuation) = AsyncStream.makeStream()
+ return AccountListenerStream(values: stream,
+ listenerToken: NSObject(),
+ continuation: continuation)
+ },
+ reauthenticateWithApple: @Sendable @escaping (_: SignInWithAppleResult) async throws -> Void = { _ in },
+ revokeAppleToken: @Sendable @escaping (_: String) async throws -> Void = { _ in },
+ deleteAccount: @Sendable @escaping () async throws -> Void = {}
+ ) {
+
+ self.signIn = signIn
+ self.signOut = signOut
+ self.makeListener = makeListener
+ self.reauthenticateWithApple = reauthenticateWithApple
+ self.revokeAppleToken = revokeAppleToken
+ self.deleteAccount = deleteAccount
+ }
+}
+
+public extension AccountAuthClient {
+ static let previewValue = AccountAuthClient()
+}
diff --git a/LocalPackage/Sources/HometeDomain/Dependencies/AccountInfoClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/AccountInfoClient.swift
new file mode 100644
index 00000000..e55da1d3
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/AccountInfoClient.swift
@@ -0,0 +1,25 @@
+//
+// AccountInfoClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/09.
+//
+
+public struct AccountInfoClient: Sendable {
+
+ public let insertOrUpdate: @Sendable (Account) async throws -> Void
+ public let fetch: @Sendable (String) async throws -> Account?
+
+ public init(
+ insertOrUpdate: @Sendable @escaping (Account) async throws -> Void = { _ in },
+ fetch: @Sendable @escaping (String) async throws -> Account? = { _ in nil }
+ ) {
+ self.insertOrUpdate = insertOrUpdate
+ self.fetch = fetch
+ }
+}
+
+public extension AccountInfoClient {
+
+ static let previewValue: AccountInfoClient = .init()
+}
diff --git a/LocalPackage/Sources/HometeDomain/Dependencies/AnalyticsClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/AnalyticsClient.swift
new file mode 100644
index 00000000..78e63773
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/AnalyticsClient.swift
@@ -0,0 +1,26 @@
+//
+// AnalyticsClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/09.
+//
+
+public struct AnalyticsClient: Sendable {
+
+ public let setId: @Sendable (String) -> Void
+ public let log: @Sendable (AnalyticsEvent) -> Void
+
+ public init(
+ setId: @Sendable @escaping (String) -> Void = { _ in },
+ log: @Sendable @escaping (AnalyticsEvent) -> Void = { _ in }
+ ) {
+
+ self.setId = setId
+ self.log = log
+ }
+}
+
+public extension AnalyticsClient {
+
+ static let previewValue = AnalyticsClient()
+}
diff --git a/LocalPackage/Sources/HometeDomain/Dependencies/CohabitantClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/CohabitantClient.swift
new file mode 100644
index 00000000..f35d8629
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/CohabitantClient.swift
@@ -0,0 +1,35 @@
+//
+// CohabitantClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/18.
+//
+
+public struct CohabitantClient: Sendable {
+
+ public let register: @Sendable (CohabitantData) async throws -> Void
+ public let addSnapshotListener: @Sendable (
+ _ listenerId: String,
+ _ cohabitantId: String
+ ) async -> AsyncStream<[CohabitantData]>
+ public let removeSnapshotListener: @Sendable (_ listenerId: String) async -> Void
+
+ public init(
+ register: @Sendable @escaping (CohabitantData) async throws -> Void = { _ in },
+ addSnapshotListener: @Sendable @escaping (
+ _: String,
+ _: String
+ ) async -> AsyncStream<[CohabitantData]> = { _, _ in .init { nil } },
+ removeSnapshotListener: @Sendable @escaping (_ listenerId: String) async -> Void = { _ in }
+ ) {
+
+ self.register = register
+ self.addSnapshotListener = addSnapshotListener
+ self.removeSnapshotListener = removeSnapshotListener
+ }
+}
+
+public extension CohabitantClient {
+
+ static let previewValue: CohabitantClient = .init()
+}
diff --git a/LocalPackage/Sources/HometeDomain/Dependencies/CohabitantPushNotificationClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/CohabitantPushNotificationClient.swift
new file mode 100644
index 00000000..45418c88
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/CohabitantPushNotificationClient.swift
@@ -0,0 +1,19 @@
+//
+// CohabitantPushNotificationClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/11/12.
+//
+
+public struct CohabitantPushNotificationClient: Sendable {
+ public let send: @Sendable (_ id: String, _ content: PushNotificationContent) async throws -> Void
+
+ public init(send: @Sendable @escaping (_ id: String, _ content: PushNotificationContent) async throws -> Void) {
+ self.send = send
+ }
+}
+
+public extension CohabitantPushNotificationClient {
+
+ static let previewValue: CohabitantPushNotificationClient = .init { _, _ in }
+}
diff --git a/homete/Model/Dependencies/DependencyClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/DependencyClient.swift
similarity index 79%
rename from homete/Model/Dependencies/DependencyClient.swift
rename to LocalPackage/Sources/HometeDomain/Dependencies/DependencyClient.swift
index d5205b35..1145595a 100644
--- a/homete/Model/Dependencies/DependencyClient.swift
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/DependencyClient.swift
@@ -5,8 +5,8 @@
// Created by 佐藤汰一 on 2025/08/04.
//
-protocol DependencyClient: Sendable {
-
+public protocol DependencyClient: Sendable {
+
static var liveValue: Self { get }
static var previewValue: Self { get }
}
diff --git a/LocalPackage/Sources/HometeDomain/Dependencies/HouseworkClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/HouseworkClient.swift
new file mode 100644
index 00000000..9251b46e
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/HouseworkClient.swift
@@ -0,0 +1,50 @@
+//
+// HouseworkClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/09/07.
+//
+
+import Foundation
+
+public struct HouseworkClient: Sendable {
+
+ public let insertOrUpdateItem: @Sendable (_ item: HouseworkItem, _ cohabitantId: String) async throws -> Void
+ public let removeItem: @Sendable (_ item: HouseworkItem, _ cohabitantId: String) async throws -> Void
+ public let snapshotListener: @Sendable (
+ _ id: String,
+ _ cohabitantId: String,
+ _ anchorDate: Date,
+ _ offset: Int
+ ) async -> AsyncStream<[HouseworkItem]>
+ public let removeListener: @Sendable (_ id: String) async -> Void
+}
+
+public extension HouseworkClient {
+
+ init(
+ insertOrUpdateItemHandler: @escaping @Sendable (
+ _ item: HouseworkItem,
+ _ cohabitantId: String
+ ) async throws -> Void = { _, _ in },
+ removeItemHandler: @escaping @Sendable (
+ _ item: HouseworkItem,
+ _ cohabitantId: String
+ ) async throws -> Void = { _, _ in },
+ snapshotListenerHandler: @escaping @Sendable (
+ _ id: String,
+ _ cohabitantId: String,
+ _ anchorDate: Date,
+ _ offset: Int
+ ) async -> AsyncStream<[HouseworkItem]> = { _, _, _, _ in .makeStream().stream },
+ removeListenerHandler: @escaping @Sendable (_ id: String) async -> Void = { _ in }
+ ) {
+
+ insertOrUpdateItem = insertOrUpdateItemHandler
+ removeItem = removeItemHandler
+ snapshotListener = snapshotListenerHandler
+ removeListener = removeListenerHandler
+ }
+
+ static let previewValue = HouseworkClient()
+}
diff --git a/LocalPackage/Sources/HometeDomain/Dependencies/NonceGenerationClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/NonceGenerationClient.swift
new file mode 100644
index 00000000..43594936
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/NonceGenerationClient.swift
@@ -0,0 +1,29 @@
+//
+// NonceGenerationClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/03.
+//
+
+import Foundation
+
+public struct NonceGenerationClient: Sendable {
+
+ public let value: @Sendable () -> SignInWithAppleNonce
+ public func callAsFunction() -> SignInWithAppleNonce {
+
+ return value()
+ }
+
+ public init(value: @Sendable @escaping () -> SignInWithAppleNonce) {
+ self.value = value
+ }
+}
+
+public extension NonceGenerationClient {
+
+ static let previewValue: NonceGenerationClient = .init {
+
+ return .init(original: "preview", sha256: "preview sha256")
+ }
+}
diff --git a/LocalPackage/Sources/HometeDomain/Dependencies/SignInWithAppleClient.swift b/LocalPackage/Sources/HometeDomain/Dependencies/SignInWithAppleClient.swift
new file mode 100644
index 00000000..c5db031d
--- /dev/null
+++ b/LocalPackage/Sources/HometeDomain/Dependencies/SignInWithAppleClient.swift
@@ -0,0 +1,23 @@
+//
+// SignInWithAppleClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/12/31.
+//
+
+public struct SignInWithAppleClient: Sendable {
+ public let reauthentication: @MainActor (_ nonce: SignInWithAppleNonce) async throws -> SignInWithAppleResult
+
+ public init(
+ reauthentication: @MainActor @escaping (_ nonce: SignInWithAppleNonce)
+ async throws -> SignInWithAppleResult = { _ in preconditionFailure() }
+ ) {
+
+ self.reauthentication = reauthentication
+ }
+}
+
+public extension SignInWithAppleClient {
+
+ static let previewValue = SignInWithAppleClient()
+}
diff --git a/homete/Model/Domain/DomainError.swift b/LocalPackage/Sources/HometeDomain/DomainError.swift
similarity index 77%
rename from homete/Model/Domain/DomainError.swift
rename to LocalPackage/Sources/HometeDomain/DomainError.swift
index b8668556..5430daaf 100644
--- a/homete/Model/Domain/DomainError.swift
+++ b/LocalPackage/Sources/HometeDomain/DomainError.swift
@@ -5,17 +5,17 @@
// Created by 佐藤汰一 on 2025/08/09.
//
-enum DomainError: Error, Equatable {
-
+public enum DomainError: Error, Equatable, Sendable {
+
case failAuth
case noNetwork
case other
}
-extension DomainError {
-
+public extension DomainError {
+
static func make(_ error: (any Error)?) -> Self? {
-
+
guard let error else { return nil }
return error as? DomainError ?? .other
}
diff --git a/homete/Model/Domain/PushNotificationContent.swift b/LocalPackage/Sources/HometeDomain/PushNotificationContent.swift
similarity index 79%
rename from homete/Model/Domain/PushNotificationContent.swift
rename to LocalPackage/Sources/HometeDomain/PushNotificationContent.swift
index d8a01041..c6d6e3be 100644
--- a/homete/Model/Domain/PushNotificationContent.swift
+++ b/LocalPackage/Sources/HometeDomain/PushNotificationContent.swift
@@ -5,12 +5,17 @@
// Created by 佐藤汰一 on 2025/11/12.
//
-struct PushNotificationContent: Equatable {
- let title: String
- let message: String
+public struct PushNotificationContent: Equatable, Sendable {
+ public let title: String
+ public let message: String
+
+ public init(title: String, message: String) {
+ self.title = title
+ self.message = message
+ }
}
-extension PushNotificationContent {
+public extension PushNotificationContent {
static func addNewHouseworkItem(_ houseworkTitle: String) -> Self {
return .init(
diff --git a/homete/Model/Domain/Setting/SettingMenuItem.swift b/LocalPackage/Sources/HometeDomain/Setting/SettingMenuItem.swift
similarity index 75%
rename from homete/Model/Domain/Setting/SettingMenuItem.swift
rename to LocalPackage/Sources/HometeDomain/Setting/SettingMenuItem.swift
index a1c7f035..6fc12f43 100644
--- a/homete/Model/Domain/Setting/SettingMenuItem.swift
+++ b/LocalPackage/Sources/HometeDomain/Setting/SettingMenuItem.swift
@@ -5,37 +5,41 @@
// Created by 佐藤汰一 on 2025/08/11.
//
+#if canImport(SwiftUI)
import SwiftUI
+#endif
+
+public enum SettingMenuItem: Equatable, CaseIterable {
-enum SettingMenuItem: Equatable, CaseIterable {
-
case taskTemplate
case privacyPolicy
case license
-
- var title: LocalizedStringKey {
-
+
+ #if canImport(SwiftUI)
+ public var title: LocalizedStringKey {
+
switch self {
case .taskTemplate:
return "家事テンプレート"
-
+
case .privacyPolicy:
return "プライバシーポリシー"
-
+
case .license:
return "ライセンス"
}
}
-
- var iconName: String {
-
+ #endif
+
+ public var iconName: String {
+
switch self {
case .taskTemplate:
return "house"
-
+
case .privacyPolicy:
return "hand.raised"
-
+
case .license:
return "cube.box"
}
diff --git a/LocalPackage/Sources/LocalPackage/LocalPackage.swift b/LocalPackage/Sources/LocalPackage/LocalPackage.swift
deleted file mode 100644
index 08b22b80..00000000
--- a/LocalPackage/Sources/LocalPackage/LocalPackage.swift
+++ /dev/null
@@ -1,2 +0,0 @@
-// The Swift Programming Language
-// https://docs.swift.org/swift-book
diff --git a/hometeTests/Domain/AccountAuthStoreTest.swift b/LocalPackage/Tests/HometeDomainTests/AccountAuthStoreTest.swift
similarity index 61%
rename from hometeTests/Domain/AccountAuthStoreTest.swift
rename to LocalPackage/Tests/HometeDomainTests/AccountAuthStoreTest.swift
index 231b6c23..4e832b53 100644
--- a/hometeTests/Domain/AccountAuthStoreTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/AccountAuthStoreTest.swift
@@ -5,9 +5,8 @@
// Created by 佐藤汰一 on 2025/08/09.
//
-import os
import Testing
-@testable import homete
+@testable import HometeDomain
@MainActor
struct AccountAuthStoreTest {
@@ -21,7 +20,7 @@ struct AccountAuthStoreTest {
try await confirmation(expectedCount: 4) { confirmation in
- let store = AccountAuthStore(appDependencies: .init(
+ let store = AccountAuthStore(
accountAuthClient: .init(
signIn: { tokenId, nonce in
@@ -48,49 +47,49 @@ struct AccountAuthStoreTest {
#expect(event == .login(isSuccess: true))
}
)
- ))
+ )
try await store.login(.init(tokenId: inputTokenId, nonce: inputNonce, authorizationCode: "code"))
}
}
@Test("ログアウト時はローカルのログイン状態をログアウトにしてログアウト処理を行い、イベントログを送信する")
- func test_logout() throws {
-
- let isCallSignOut = OSAllocatedUnfairLock(initialState: false)
- let isCallAnalyticsLog = OSAllocatedUnfairLock(initialState: false)
-
- let store = AccountAuthStore(
- appDependencies: .init(
+ func test_logout() async throws {
+
+ try await confirmation(expectedCount: 3) { confirmation in
+
+ let store = AccountAuthStore(
accountAuthClient: .init(
signIn: { _, _ in
-
+
Issue.record()
return .init(id: "")
},
- signOut: { isCallSignOut.withLock { $0 = true } },
- makeListener: { .defaultValue() }
+ signOut: { confirmation() },
+ makeListener: {
+
+ confirmation()
+ return .defaultValue()
+ }
),
analyticsClient: .init(
setId: { _ in
-
+
Issue.record()
},
log: { event in
-
- isCallAnalyticsLog.withLock { $0 = true }
+
+ confirmation()
#expect(event == .logout())
}
- )
- ),
- currentAuth: .init(result: .init(id: "test"), alreadyLoadedAtInitiate: true)
- )
-
- store.logOut()
-
- #expect(isCallSignOut.withLock { $0 })
- #expect(isCallAnalyticsLog.withLock { $0 })
- #expect(store.currentAuth == .init(result: nil, alreadyLoadedAtInitiate: true))
+ ),
+ currentAuth: .init(result: .init(id: "test"), alreadyLoadedAtInitiate: true)
+ )
+
+ store.logOut()
+
+ #expect(store.currentAuth == .init(result: nil, alreadyLoadedAtInitiate: true))
+ }
}
@Test("再認証を行った後にアカウントを削除し認証トークンの無効化を行いログアウト状態にすることで、退会処理を完了させる")
@@ -107,42 +106,40 @@ struct AccountAuthStoreTest {
try await confirmation(expectedCount: 6) { confirmation in
let store = AccountAuthStore(
- appDependencies: .init(
- nonceGeneratorClient: .init {
+ accountAuthClient: .init(
+ reauthenticateWithApple: { result in
confirmation()
- return inputNonce
+ #expect(result == inputSignInWithAppleResult)
},
- accountAuthClient: .init(
- reauthenticateWithApple: { result in
-
- confirmation()
- #expect(result == inputSignInWithAppleResult)
- },
- revokeAppleToken: { code in
-
- confirmation()
- #expect(code == inputSignInWithAppleResult.authorizationCode)
- },
- deleteAccount: {
-
- confirmation()
- },
- ),
- analyticsClient: .init(
- log: { event in
-
- confirmation()
- #expect(event == .deleteAccount())
- }
- ),
- signInWithAppleClient: .init { nonce in
+ revokeAppleToken: { code in
confirmation()
- #expect(nonce == inputNonce)
- return inputSignInWithAppleResult
+ #expect(code == inputSignInWithAppleResult.authorizationCode)
+ },
+ deleteAccount: {
+
+ confirmation()
+ },
+ ),
+ analyticsClient: .init(
+ log: { event in
+
+ confirmation()
+ #expect(event == .deleteAccount())
}
),
+ signInWithAppleClient: .init { nonce in
+
+ confirmation()
+ #expect(nonce == inputNonce)
+ return inputSignInWithAppleResult
+ },
+ nonceGenerationClient: .init {
+
+ confirmation()
+ return inputNonce
+ },
currentAuth: .init(result: .init(id: "test"), alreadyLoadedAtInitiate: true)
)
diff --git a/hometeTests/Domain/AccountStoreTest.swift b/LocalPackage/Tests/HometeDomainTests/AccountStoreTest.swift
similarity index 92%
rename from hometeTests/Domain/AccountStoreTest.swift
rename to LocalPackage/Tests/HometeDomainTests/AccountStoreTest.swift
index e5038694..81cb2beb 100644
--- a/hometeTests/Domain/AccountStoreTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/AccountStoreTest.swift
@@ -6,7 +6,7 @@
//
import Testing
-@testable import homete
+@testable import HometeDomain
@MainActor
struct AccountStoreTest {
@@ -32,7 +32,7 @@ struct AccountStoreTest {
#expect($0 == inputAuthResult.id)
return inputAccount
})
- let store = AccountStore(appDependencies: .init(accountInfoClient: accountInfoClient))
+ let store = AccountStore(accountInfoClient: accountInfoClient)
// Act
let actual = await store.load(inputAuthResult)
@@ -62,7 +62,7 @@ struct AccountStoreTest {
#expect($0 == expectedAccount)
})
let store = AccountStore(
- appDependencies: .init(accountInfoClient: accountInfoClient),
+ accountInfoClient: accountInfoClient,
account: initialAccount
)
@@ -99,7 +99,7 @@ struct AccountStoreTest {
#expect($0 == expectedAccount)
})
let store = AccountStore(
- appDependencies: .init(accountInfoClient: accountInfoClient),
+ accountInfoClient: accountInfoClient,
account: initialAccount
)
diff --git a/hometeTests/Domain/CohabitantRegistration/CohabitantRegistrationMessageTests.swift b/LocalPackage/Tests/HometeDomainTests/CohabitantRegistration/CohabitantRegistrationMessageTests.swift
similarity index 99%
rename from hometeTests/Domain/CohabitantRegistration/CohabitantRegistrationMessageTests.swift
rename to LocalPackage/Tests/HometeDomainTests/CohabitantRegistration/CohabitantRegistrationMessageTests.swift
index d55600f2..79a37684 100644
--- a/hometeTests/Domain/CohabitantRegistration/CohabitantRegistrationMessageTests.swift
+++ b/LocalPackage/Tests/HometeDomainTests/CohabitantRegistration/CohabitantRegistrationMessageTests.swift
@@ -7,7 +7,7 @@
import Foundation
import Testing
-@testable import homete
+@testable import HometeDomain
struct CohabitantRegistrationMessageTests {
diff --git a/hometeTests/Domain/CohabitantStoreTest.swift b/LocalPackage/Tests/HometeDomainTests/CohabitantStoreTest.swift
similarity index 69%
rename from hometeTests/Domain/CohabitantStoreTest.swift
rename to LocalPackage/Tests/HometeDomainTests/CohabitantStoreTest.swift
index a94bea94..88919205 100644
--- a/hometeTests/Domain/CohabitantStoreTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/CohabitantStoreTest.swift
@@ -7,7 +7,7 @@
import Testing
import Observation
-@testable import homete
+@testable import HometeDomain
@MainActor
struct CohabitantStoreTest {
@@ -36,23 +36,21 @@ struct CohabitantStoreTest {
let (stream, continuation) = AsyncStream<[CohabitantData]>.makeStream()
let store = CohabitantStore(
- appDependencies: .init(
- accountInfoClient: .init(fetch: { userId in
-
- // Assert
-
- #expect(userId == newMemberId)
- return expectedAccount
- }),
- cohabitantClient: .init(
- addSnapshotListener: { listenerId, cohabitantId in
-
- #expect(listenerId == inputListenerId)
- #expect(cohabitantId == inputCohabitantId)
- return stream
- }
- )
- )
+ cohabitantClient: .init(
+ addSnapshotListener: { listenerId, cohabitantId in
+
+ #expect(listenerId == inputListenerId)
+ #expect(cohabitantId == inputCohabitantId)
+ return stream
+ }
+ ),
+ accountInfoClient: .init(fetch: { userId in
+
+ // Assert
+
+ #expect(userId == newMemberId)
+ return expectedAccount
+ })
)
// Act
@@ -63,9 +61,7 @@ struct CohabitantStoreTest {
let waiterForUpdateMembers = Task {
await withCheckedContinuation { continuation in
- ObservationHelper.continuousObservationTracking {
- store.members
- } onChange: {
+ ObservationHelper.continuousObservationTracking({ store.members }) {
continuation.resume(returning: ())
}
}
@@ -74,6 +70,7 @@ struct CohabitantStoreTest {
continuation.yield([inputCohabitantData])
await waiterForUpdateMembers.value
continuation.finish()
+ await store.removeSnapshotListener()
#expect(store.members.value.count == 1)
#expect(store.members.value.contains(.init(id: newMemberId, userName: newMemberUserName)))
diff --git a/hometeTests/Domain/Housework/DailyHouseworkListTest.swift b/LocalPackage/Tests/HometeDomainTests/Housework/DailyHouseworkListTest.swift
similarity index 99%
rename from hometeTests/Domain/Housework/DailyHouseworkListTest.swift
rename to LocalPackage/Tests/HometeDomainTests/Housework/DailyHouseworkListTest.swift
index e2e9736a..654a7879 100644
--- a/hometeTests/Domain/Housework/DailyHouseworkListTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/Housework/DailyHouseworkListTest.swift
@@ -8,7 +8,7 @@
import Foundation
import Testing
-@testable import homete
+@testable import HometeDomain
// swiftlint:disable:next convenience_type
struct DailyHouseworkListTest {
diff --git a/hometeTests/Domain/Housework/HouseworkBoardListTest.swift b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkBoardListTest.swift
similarity index 98%
rename from hometeTests/Domain/Housework/HouseworkBoardListTest.swift
rename to LocalPackage/Tests/HometeDomainTests/Housework/HouseworkBoardListTest.swift
index bda8aede..cc2fb36d 100644
--- a/hometeTests/Domain/Housework/HouseworkBoardListTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkBoardListTest.swift
@@ -8,7 +8,7 @@
import Foundation
import Testing
-@testable import homete
+@testable import HometeDomain
struct HouseworkBoardListTest {
diff --git a/hometeTests/Domain/Housework/HouseworkHistoryListTest.swift b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkHistoryListTest.swift
similarity index 98%
rename from hometeTests/Domain/Housework/HouseworkHistoryListTest.swift
rename to LocalPackage/Tests/HometeDomainTests/Housework/HouseworkHistoryListTest.swift
index 64485e54..1c73ded5 100644
--- a/hometeTests/Domain/Housework/HouseworkHistoryListTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkHistoryListTest.swift
@@ -6,7 +6,7 @@
//
import Testing
-@testable import homete
+@testable import HometeDomain
// swiftlint:disable:next convenience_type
struct HouseworkHistoryListTest {
diff --git a/hometeTests/Domain/Housework/HouseworkIndexedDate.swift b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkIndexedDate.swift
similarity index 98%
rename from hometeTests/Domain/Housework/HouseworkIndexedDate.swift
rename to LocalPackage/Tests/HometeDomainTests/Housework/HouseworkIndexedDate.swift
index c71084b1..7a89f321 100644
--- a/hometeTests/Domain/Housework/HouseworkIndexedDate.swift
+++ b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkIndexedDate.swift
@@ -7,7 +7,7 @@
import Foundation
import Testing
-@testable import homete
+@testable import HometeDomain
enum HouseworkIndexedDateTest {
diff --git a/hometeTests/Domain/Housework/HouseworkItemTest.swift b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkItemTest.swift
similarity index 99%
rename from hometeTests/Domain/Housework/HouseworkItemTest.swift
rename to LocalPackage/Tests/HometeDomainTests/Housework/HouseworkItemTest.swift
index 4ec1eb20..6a446531 100644
--- a/hometeTests/Domain/Housework/HouseworkItemTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkItemTest.swift
@@ -8,7 +8,7 @@
import Foundation
import Testing
-@testable import homete
+@testable import HometeDomain
enum HouseworkItemTest {
diff --git a/hometeTests/Domain/Housework/HouseworkListStoreTest.swift b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkListStoreTest.swift
similarity index 98%
rename from hometeTests/Domain/Housework/HouseworkListStoreTest.swift
rename to LocalPackage/Tests/HometeDomainTests/Housework/HouseworkListStoreTest.swift
index 101fdbf0..52ae4fdb 100644
--- a/hometeTests/Domain/Housework/HouseworkListStoreTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/Housework/HouseworkListStoreTest.swift
@@ -8,7 +8,7 @@
import Foundation
import Testing
-@testable import homete
+@testable import HometeDomain
@MainActor
struct HouseworkListStoreTest {
@@ -55,9 +55,7 @@ struct HouseworkListStoreTest {
let waiterForUpdateItems = Task {
await withCheckedContinuation { continuation in
- ObservationHelper.continuousObservationTracking {
- store.items
- } onChange: {
+ ObservationHelper.continuousObservationTracking({ store.items }) {
continuation.resume(returning: ())
}
}
@@ -69,6 +67,7 @@ struct HouseworkListStoreTest {
continuation.yield(inputHouseworkList)
await waiterForUpdateItems.value
continuation.finish()
+ await store.stopObserving()
#expect(
store.items == .init(value: [
diff --git a/hometeTests/Domain/Housework/StoredAllHouseworkListTest.swift b/LocalPackage/Tests/HometeDomainTests/Housework/StoredAllHouseworkListTest.swift
similarity index 98%
rename from hometeTests/Domain/Housework/StoredAllHouseworkListTest.swift
rename to LocalPackage/Tests/HometeDomainTests/Housework/StoredAllHouseworkListTest.swift
index 7c58f494..b05fc108 100644
--- a/hometeTests/Domain/Housework/StoredAllHouseworkListTest.swift
+++ b/LocalPackage/Tests/HometeDomainTests/Housework/StoredAllHouseworkListTest.swift
@@ -7,7 +7,7 @@
import Foundation
import Testing
-@testable import homete
+@testable import HometeDomain
struct StoredAllHouseworkListTest {
diff --git a/hometeTests/TestHelper/AccountListenerStreamCreater.swift b/LocalPackage/Tests/HometeDomainTests/TestHelper/AccountListenerStreamCreater.swift
similarity index 92%
rename from hometeTests/TestHelper/AccountListenerStreamCreater.swift
rename to LocalPackage/Tests/HometeDomainTests/TestHelper/AccountListenerStreamCreater.swift
index 0f07c944..858e2ddc 100644
--- a/hometeTests/TestHelper/AccountListenerStreamCreater.swift
+++ b/LocalPackage/Tests/HometeDomainTests/TestHelper/AccountListenerStreamCreater.swift
@@ -6,7 +6,7 @@
//
import Foundation
-@testable import homete
+@testable import HometeDomain
extension AccountListenerStream {
diff --git a/hometeTests/TestHelper/CalendarHelper.swift b/LocalPackage/Tests/HometeDomainTests/TestHelper/CalendarHelper.swift
similarity index 100%
rename from hometeTests/TestHelper/CalendarHelper.swift
rename to LocalPackage/Tests/HometeDomainTests/TestHelper/CalendarHelper.swift
diff --git a/hometeTests/TestHelper/DailyHouseworkListHelper.swift b/LocalPackage/Tests/HometeDomainTests/TestHelper/DailyHouseworkListHelper.swift
similarity index 93%
rename from hometeTests/TestHelper/DailyHouseworkListHelper.swift
rename to LocalPackage/Tests/HometeDomainTests/TestHelper/DailyHouseworkListHelper.swift
index 34a03a70..445c2ffa 100644
--- a/hometeTests/TestHelper/DailyHouseworkListHelper.swift
+++ b/LocalPackage/Tests/HometeDomainTests/TestHelper/DailyHouseworkListHelper.swift
@@ -5,7 +5,7 @@
// Created by 佐藤汰一 on 2025/10/02.
//
-@testable import homete
+@testable import HometeDomain
extension DailyHouseworkList {
diff --git a/hometeTests/TestHelper/DateHelper.swift b/LocalPackage/Tests/HometeDomainTests/TestHelper/DateHelper.swift
similarity index 100%
rename from hometeTests/TestHelper/DateHelper.swift
rename to LocalPackage/Tests/HometeDomainTests/TestHelper/DateHelper.swift
diff --git a/hometeTests/TestHelper/HouseworkItemHelper.swift b/LocalPackage/Tests/HometeDomainTests/TestHelper/HouseworkItemHelper.swift
similarity index 98%
rename from hometeTests/TestHelper/HouseworkItemHelper.swift
rename to LocalPackage/Tests/HometeDomainTests/TestHelper/HouseworkItemHelper.swift
index 7517c4d3..3e0d3b0b 100644
--- a/hometeTests/TestHelper/HouseworkItemHelper.swift
+++ b/LocalPackage/Tests/HometeDomainTests/TestHelper/HouseworkItemHelper.swift
@@ -6,7 +6,7 @@
//
import Foundation
-@testable import homete
+@testable import HometeDomain
extension HouseworkItem {
diff --git a/hometeTests/TestHelper/LocaleHelper.swift b/LocalPackage/Tests/HometeDomainTests/TestHelper/LocaleHelper.swift
similarity index 100%
rename from hometeTests/TestHelper/LocaleHelper.swift
rename to LocalPackage/Tests/HometeDomainTests/TestHelper/LocaleHelper.swift
diff --git a/hometeTests/TestHelper/ObservationHelper.swift b/LocalPackage/Tests/HometeDomainTests/TestHelper/ObservationHelper.swift
similarity index 55%
rename from hometeTests/TestHelper/ObservationHelper.swift
rename to LocalPackage/Tests/HometeDomainTests/TestHelper/ObservationHelper.swift
index 086e4c1a..d4059a64 100644
--- a/hometeTests/TestHelper/ObservationHelper.swift
+++ b/LocalPackage/Tests/HometeDomainTests/TestHelper/ObservationHelper.swift
@@ -13,15 +13,18 @@ enum ObservationHelper {
/// - Parameters:
/// - apply: 変更を検知したいプロパティを返す
/// - onChange: 変更検知時に発火するクロージャ
- static func continuousObservationTracking(
- _ apply: @escaping () -> T,
- onChange: @escaping (@Sendable () -> Void)
+ @MainActor
+ static func continuousObservationTracking(
+ _ apply: @escaping @MainActor @Sendable () -> T,
+ onChange: @escaping @Sendable () -> Void
) {
- _ = withObservationTracking(apply) {
+ _ = withObservationTracking({ apply() }) {
onChange()
- continuousObservationTracking(apply, onChange: onChange)
+ Task { @MainActor in
+ continuousObservationTracking(apply, onChange: onChange)
+ }
}
}
}
diff --git a/hometeTests/TestHelper/TimeZoneHelper.swift b/LocalPackage/Tests/HometeDomainTests/TestHelper/TimeZoneHelper.swift
similarity index 100%
rename from hometeTests/TestHelper/TimeZoneHelper.swift
rename to LocalPackage/Tests/HometeDomainTests/TestHelper/TimeZoneHelper.swift
diff --git a/LocalPackage/Tests/LocalPackageTests/LocalPackageTests.swift b/LocalPackage/Tests/LocalPackageTests/LocalPackageTests.swift
deleted file mode 100644
index f1376e7e..00000000
--- a/LocalPackage/Tests/LocalPackageTests/LocalPackageTests.swift
+++ /dev/null
@@ -1,6 +0,0 @@
-import Testing
-@testable import LocalPackage
-
-@Test func example() async throws {
- // Write your test here and use APIs like `#expect(...)` to check expected conditions.
-}
diff --git a/homete.xcodeproj/project.pbxproj b/homete.xcodeproj/project.pbxproj
index 08c52b64..71dd7397 100644
--- a/homete.xcodeproj/project.pbxproj
+++ b/homete.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 04B371992F40526F00820C62 /* HometeDomain in Frameworks */ = {isa = PBXBuildFile; productRef = 04B371982F40526F00820C62 /* HometeDomain */; };
BC0CF70D2E77B3A500DC31CA /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = BC0CF70C2E77B3A500DC31CA /* FirebaseMessaging */; };
BC0CF7122E7863B500DC31CA /* FirebaseFunctions in Frameworks */ = {isa = PBXBuildFile; productRef = BC0CF7112E7863B500DC31CA /* FirebaseFunctions */; };
BC1BB2722E909B99001D168F /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = BC1BB2712E909B99001D168F /* SnapshotTesting */; };
@@ -29,13 +30,6 @@
remoteGlobalIDString = BCC853F42DB74BBC00C9A44B;
remoteInfo = homete;
};
- BCC854032DB74BBF00C9A44B /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = BCC853ED2DB74BBC00C9A44B /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = BCC853F42DB74BBC00C9A44B;
- remoteInfo = homete;
- };
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
@@ -46,7 +40,6 @@
BC5204662DB7BEFD0097472D /* homete.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = homete.xctestplan; sourceTree = ""; };
BC7469462DBCBE71007E4222 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; };
BCC853F52DB74BBC00C9A44B /* homete.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = homete.app; sourceTree = BUILT_PRODUCTS_DIR; };
- BCC854022DB74BBF00C9A44B /* hometeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = hometeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
@@ -73,11 +66,6 @@
path = homete;
sourceTree = "";
};
- BCC854052DB74BBF00C9A44B /* hometeTests */ = {
- isa = PBXFileSystemSynchronizedRootGroup;
- path = hometeTests;
- sourceTree = "";
- };
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
@@ -100,17 +88,11 @@
BC0CF70D2E77B3A500DC31CA /* FirebaseMessaging in Frameworks */,
BC0CF7122E7863B500DC31CA /* FirebaseFunctions in Frameworks */,
BC2E372C2E3DE189005BD910 /* FirebaseAuth in Frameworks */,
+ 04B371992F40526F00820C62 /* HometeDomain in Frameworks */,
BCB8DB182E37B3F900FFB4E1 /* FirebaseCrashlytics in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- BCC853FF2DB74BBF00C9A44B /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -130,7 +112,6 @@
BC7469462DBCBE71007E4222 /* PrivacyInfo.xcprivacy */,
BC5204662DB7BEFD0097472D /* homete.xctestplan */,
BCC853F72DB74BBC00C9A44B /* homete */,
- BCC854052DB74BBF00C9A44B /* hometeTests */,
BC1BB2692E909B8C001D168F /* hometeSnapshotTests */,
BCB8DB162E37B3F900FFB4E1 /* Frameworks */,
BCC853F62DB74BBC00C9A44B /* Products */,
@@ -141,7 +122,6 @@
isa = PBXGroup;
children = (
BCC853F52DB74BBC00C9A44B /* homete.app */,
- BCC854022DB74BBF00C9A44B /* hometeTests.xctest */,
BC1BB2682E909B8C001D168F /* hometeSnapshotTests.xctest */,
);
name = Products;
@@ -202,34 +182,12 @@
BC0CF70C2E77B3A500DC31CA /* FirebaseMessaging */,
BC0CF7112E7863B500DC31CA /* FirebaseFunctions */,
BCADFE1C2EACB62E00DF4AAA /* Prefire */,
+ 04B371982F40526F00820C62 /* HometeDomain */,
);
productName = homete;
productReference = BCC853F52DB74BBC00C9A44B /* homete.app */;
productType = "com.apple.product-type.application";
};
- BCC854012DB74BBF00C9A44B /* hometeTests */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = BCC854192DB74BBF00C9A44B /* Build configuration list for PBXNativeTarget "hometeTests" */;
- buildPhases = (
- BCC853FE2DB74BBF00C9A44B /* Sources */,
- BCC853FF2DB74BBF00C9A44B /* Frameworks */,
- BCC854002DB74BBF00C9A44B /* Resources */,
- );
- buildRules = (
- );
- dependencies = (
- BCC854042DB74BBF00C9A44B /* PBXTargetDependency */,
- );
- fileSystemSynchronizedGroups = (
- BCC854052DB74BBF00C9A44B /* hometeTests */,
- );
- name = hometeTests;
- packageProductDependencies = (
- );
- productName = hometeTests;
- productReference = BCC854022DB74BBF00C9A44B /* hometeTests.xctest */;
- productType = "com.apple.product-type.bundle.unit-test";
- };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -247,11 +205,6 @@
BCC853F42DB74BBC00C9A44B = {
CreatedOnToolsVersion = 16.3;
};
- BCC854012DB74BBF00C9A44B = {
- CreatedOnToolsVersion = 16.3;
- LastSwiftMigration = 1640;
- TestTargetID = BCC853F42DB74BBC00C9A44B;
- };
};
};
buildConfigurationList = BCC853F02DB74BBC00C9A44B /* Build configuration list for PBXProject "homete" */;
@@ -268,6 +221,7 @@
BCB8DAFC2E36FC7100FFB4E1 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
BC1BB2612E909B50001D168F /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */,
BC4701F92E9A0F3D006CC530 /* XCRemoteSwiftPackageReference "Prefire" */,
+ 04B371972F40526F00820C62 /* XCLocalSwiftPackageReference "LocalPackage" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = BCC853F62DB74BBC00C9A44B /* Products */;
@@ -275,7 +229,6 @@
projectRoot = "";
targets = (
BCC853F42DB74BBC00C9A44B /* homete */,
- BCC854012DB74BBF00C9A44B /* hometeTests */,
BC1BB2672E909B8C001D168F /* hometeSnapshotTests */,
);
};
@@ -299,13 +252,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- BCC854002DB74BBF00C9A44B /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -369,13 +315,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
- BCC853FE2DB74BBF00C9A44B /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -388,11 +327,6 @@
isa = PBXTargetDependency;
productRef = BC4701FC2E9A0F49006CC530 /* PrefireTestsPlugin */;
};
- BCC854042DB74BBF00C9A44B /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = BCC853F42DB74BBC00C9A44B /* homete */;
- targetProxy = BCC854032DB74BBF00C9A44B /* PBXContainerItemProxy */;
- };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@@ -668,57 +602,6 @@
};
name = Release;
};
- BCC8541A2DB74BBF00C9A44B /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = 56LYVN6DMF;
- ENABLE_USER_SCRIPT_SANDBOXING = NO;
- GENERATE_INFOPLIST_FILE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 17.0;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = taichi.satou.hometeTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
- SUPPORTS_MACCATALYST = NO;
- SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
- SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
- SWIFT_EMIT_LOC_STRINGS = NO;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/homete.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/homete";
- };
- name = Debug;
- };
- BCC8541B2DB74BBF00C9A44B /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = 56LYVN6DMF;
- ENABLE_USER_SCRIPT_SANDBOXING = NO;
- GENERATE_INFOPLIST_FILE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 17.0;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = taichi.satou.hometeTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
- SUPPORTS_MACCATALYST = NO;
- SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
- SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
- SWIFT_EMIT_LOC_STRINGS = NO;
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/homete.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/homete";
- };
- name = Release;
- };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -749,17 +632,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- BCC854192DB74BBF00C9A44B /* Build configuration list for PBXNativeTarget "hometeTests" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- BCC8541A2DB74BBF00C9A44B /* Debug */,
- BCC8541B2DB74BBF00C9A44B /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
/* End XCConfigurationList section */
+/* Begin XCLocalSwiftPackageReference section */
+ 04B371972F40526F00820C62 /* XCLocalSwiftPackageReference "LocalPackage" */ = {
+ isa = XCLocalSwiftPackageReference;
+ relativePath = LocalPackage;
+ };
+/* End XCLocalSwiftPackageReference section */
+
/* Begin XCRemoteSwiftPackageReference section */
BC1BB2612E909B50001D168F /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = {
isa = XCRemoteSwiftPackageReference;
@@ -788,6 +669,10 @@
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
+ 04B371982F40526F00820C62 /* HometeDomain */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = HometeDomain;
+ };
BC0CF70C2E77B3A500DC31CA /* FirebaseMessaging */ = {
isa = XCSwiftPackageProductDependency;
package = BCB8DAFC2E36FC7100FFB4E1 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
diff --git a/homete.xctestplan b/homete.xctestplan
index d9dcc27e..0a4ab649 100644
--- a/homete.xctestplan
+++ b/homete.xctestplan
@@ -31,11 +31,10 @@
},
"testTargets" : [
{
- "parallelizable" : true,
"target" : {
- "containerPath" : "container:homete.xcodeproj",
- "identifier" : "BCC854012DB74BBF00C9A44B",
- "name" : "hometeTests"
+ "containerPath" : "container:LocalPackage",
+ "identifier" : "HometeDomainTests",
+ "name" : "HometeDomainTests"
}
}
],
diff --git a/homete/Model/AppDependencies.swift b/homete/Model/AppDependencies.swift
index dc46e4de..f28d7a8d 100644
--- a/homete/Model/AppDependencies.swift
+++ b/homete/Model/AppDependencies.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/08/03.
//
+import HometeDomain
import SwiftUI
struct AppDependencies {
diff --git a/homete/Model/Dependencies/AnalyticsClient.swift b/homete/Model/Dependencies/AnalyticsClient.swift
deleted file mode 100644
index c7ff90d3..00000000
--- a/homete/Model/Dependencies/AnalyticsClient.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// AnalyticsClient.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/08/09.
-//
-
-import FirebaseAnalytics
-import FirebaseCrashlytics
-
-struct AnalyticsClient {
-
- let setId: @Sendable (String) -> Void
- let log: @Sendable (AnalyticsEvent) -> Void
-
- init(
- setId: @Sendable @escaping (String) -> Void = { _ in },
- log: @Sendable @escaping (AnalyticsEvent) -> Void = { _ in }
- ) {
-
- self.setId = setId
- self.log = log
- }
-}
-
-extension AnalyticsClient: DependencyClient {
-
- static let liveValue: AnalyticsClient = .init { userId in
-
- Analytics.setUserID(userId)
- Crashlytics.crashlytics().setUserID(userId)
- } log: { event in
-
- Analytics.logEvent(event.name, parameters: event.parameters)
- }
-
- static let previewValue = AnalyticsClient()
-}
diff --git a/homete/Model/Dependencies/CohabitantClient.swift b/homete/Model/Dependencies/CohabitantClient.swift
deleted file mode 100644
index b467c297..00000000
--- a/homete/Model/Dependencies/CohabitantClient.swift
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// CohabitantClient.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/08/18.
-//
-
-import FirebaseFirestore
-
-struct CohabitantClient {
-
- let register: @Sendable (CohabitantData) async throws -> Void
- let addSnapshotListener: @Sendable (
- _ listenerId: String,
- _ cohabitantId: String
- ) async -> AsyncStream<[CohabitantData]>
- let removeSnapshotListener: @Sendable (_ listenerId: String) async -> Void
-
- init(
- register: @Sendable @escaping (CohabitantData) async throws -> Void = { _ in },
- addSnapshotListener: @Sendable @escaping (
- _: String,
- _: String
- ) async -> AsyncStream<[CohabitantData]> = { _, _ in .init { nil } },
- removeSnapshotListener: @Sendable @escaping (_ listenerId: String) async -> Void = { _ in }
- ) {
-
- self.register = register
- self.addSnapshotListener = addSnapshotListener
- self.removeSnapshotListener = removeSnapshotListener
- }
-}
-
-extension CohabitantClient: DependencyClient {
-
- static let liveValue: CohabitantClient = .init { data in
-
- try await FirestoreService.shared.insertOrUpdate(data: data) {
-
- return $0.cohabitantRef(id: data.id)
- }
- } addSnapshotListener: { listenerId, cohabitantId in
-
- return await FirestoreService.shared.addSnapshotListener(id: listenerId) {
- $0.collection(path: .cohabitant)
- .whereField(CohabitantData.idField, isEqualTo: cohabitantId)
- }
- } removeSnapshotListener: { listenerId in
-
- await FirestoreService.shared.removeSnapshotListener(id: listenerId)
- }
-
- static let previewValue: CohabitantClient = .init()
-}
diff --git a/homete/Model/Dependencies/HouseworkClient.swift b/homete/Model/Dependencies/HouseworkClient.swift
deleted file mode 100644
index af3f77d1..00000000
--- a/homete/Model/Dependencies/HouseworkClient.swift
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-// HouseworkClient.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/09/07.
-//
-
-import FirebaseFirestore
-
-struct HouseworkClient {
-
- let insertOrUpdateItem: @Sendable (_ item: HouseworkItem, _ cohabitantId: String) async throws -> Void
- let removeItem: @Sendable (_ item: HouseworkItem, _ cohabitantId: String) async throws -> Void
- let snapshotListener: @Sendable (
- _ id: String,
- _ cohabitantId: String,
- _ anchorDate: Date,
- _ offset: Int
- ) async -> AsyncStream<[HouseworkItem]>
- let removeListener: @Sendable (_ id: String) async -> Void
-}
-
-extension HouseworkClient: DependencyClient {
-
- init(
- insertOrUpdateItemHandler: @escaping @Sendable (
- _ item: HouseworkItem,
- _ cohabitantId: String
- ) async throws -> Void = { _, _ in },
- removeItemHandler: @escaping @Sendable (
- _ item: HouseworkItem,
- _ cohabitantId: String
- ) async throws -> Void = { _, _ in },
- snapshotListenerHandler: @escaping @Sendable (
- _ id: String,
- _ cohabitantId: String,
- _ anchorDate: Date,
- _ offset: Int
- ) async -> AsyncStream<[HouseworkItem]> = { _, _, _, _ in .makeStream().stream },
- removeListenerHandler: @escaping @Sendable (_ id: String) async -> Void = { _ in }
- ) {
-
- insertOrUpdateItem = insertOrUpdateItemHandler
- removeItem = removeItemHandler
- snapshotListener = snapshotListenerHandler
- removeListener = removeListenerHandler
- }
-
- static let liveValue = HouseworkClient { item, cohabitantId in
-
- try await FirestoreService.shared.insertOrUpdate(data: item) {
-
- return $0
- .houseworkListRef(id: cohabitantId)
- .document(item.id)
- }
- } removeItem: { item, cohabitantId in
-
- try await FirestoreService.shared.delete {
-
- return $0
- .houseworkListRef(id: cohabitantId)
- .document(item.id)
- }
- } snapshotListener: { id, cohabitantId, anchorDate, offset in
-
- let targetDateList = HouseworkIndexedDate.calcTargetPeriod(
- anchorDate: anchorDate,
- offsetDays: offset,
- calendar: .autoupdatingCurrent
- )
-
- return await FirestoreService.shared.addSnapshotListener(id: id) {
-
- return $0.houseworkListRef(id: cohabitantId)
- .whereField("indexedDate", in: targetDateList)
- }
- } removeListener: { id in
-
- await FirestoreService.shared.removeSnapshotListener(id: id)
- }
-
- static let previewValue = HouseworkClient()
-}
diff --git a/homete/Model/Dependencies/SignInWithAppleClient.swift b/homete/Model/Dependencies/SignInWithAppleClient.swift
deleted file mode 100644
index 08ade17f..00000000
--- a/homete/Model/Dependencies/SignInWithAppleClient.swift
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// SignInWithAppleClient.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/12/31.
-//
-
-import AuthenticationServices
-
-struct SignInWithAppleClient {
- let reauthentication: @MainActor (_ nonce: SignInWithAppleNonce) async throws -> SignInWithAppleResult
-
- init(
- reauthentication: @MainActor @escaping (_ nonce: SignInWithAppleNonce)
- async throws -> SignInWithAppleResult = { _ in preconditionFailure() }
- ) {
-
- self.reauthentication = reauthentication
- }
-}
-
-extension SignInWithAppleClient: DependencyClient {
-
- static let liveValue = SignInWithAppleClient { nonce in
-
- let signInWithApple = SignInWithApple()
- let appleIDCredential = try await signInWithApple(nonce)
- return try SignInWithAppleResultFactory.make(appleIDCredential, nonce)
- }
-
- static let previewValue = SignInWithAppleClient()
-}
diff --git a/homete/Model/Domain/Account/Account.swift b/homete/Model/Domain/Account/Account.swift
deleted file mode 100644
index d5032127..00000000
--- a/homete/Model/Domain/Account/Account.swift
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Account.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/08/03.
-//
-
-struct Account: Equatable, Codable {
-
- let id: String
- let userName: String
- let fcmToken: String?
- let cohabitantId: String?
-}
-
-extension Account {
-
- static func initial(auth: AccountAuthResult, userName: UserName, fcmToken: String?) -> Self {
-
- return .init(id: auth.id, userName: userName.value, fcmToken: fcmToken, cohabitantId: nil)
- }
-}
diff --git a/homete/Model/Domain/Authentification/AccountAuthInfo.swift b/homete/Model/Domain/Authentification/AccountAuthInfo.swift
deleted file mode 100644
index 5e52d3ac..00000000
--- a/homete/Model/Domain/Authentification/AccountAuthInfo.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// AccountAuthInfo.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/12/31.
-//
-
-struct AccountAuthInfo: Equatable {
- let result: AccountAuthResult?
- let alreadyLoadedAtInitiate: Bool
-
- static let initial = AccountAuthInfo(result: nil, alreadyLoadedAtInitiate: false)
-}
diff --git a/homete/Model/Domain/Authentification/AccountAuthResult.swift b/homete/Model/Domain/Authentification/AccountAuthResult.swift
deleted file mode 100644
index 693873ec..00000000
--- a/homete/Model/Domain/Authentification/AccountAuthResult.swift
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// AccountAuthResult.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/08/09.
-//
-
-struct AccountAuthResult: Equatable {
-
- let id: String
-}
diff --git a/homete/Model/Domain/Authentification/SignInWithAppleNonce.swift b/homete/Model/Domain/Authentification/SignInWithAppleNonce.swift
deleted file mode 100644
index a605680d..00000000
--- a/homete/Model/Domain/Authentification/SignInWithAppleNonce.swift
+++ /dev/null
@@ -1,12 +0,0 @@
-//
-// SignInWithAppleNonce.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/08/04.
-//
-
-struct SignInWithAppleNonce: Equatable {
-
- let original: String
- let sha256: String
-}
diff --git a/homete/Model/Domain/Authentification/SignInWithAppleResult.swift b/homete/Model/Domain/Authentification/SignInWithAppleResult.swift
deleted file mode 100644
index f26ffc2e..00000000
--- a/homete/Model/Domain/Authentification/SignInWithAppleResult.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// SignInWithAppleResult.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/08/09.
-//
-
-struct SignInWithAppleResult: Equatable {
-
- let tokenId: String
- let nonce: String
- let authorizationCode: String
-}
diff --git a/homete/Model/Domain/Cohabitant/CohabitantData.swift b/homete/Model/Domain/Cohabitant/CohabitantData.swift
deleted file mode 100644
index f929ef27..00000000
--- a/homete/Model/Domain/Cohabitant/CohabitantData.swift
+++ /dev/null
@@ -1,16 +0,0 @@
-//
-// CohabitantData.swift
-// homete
-//
-// Created by 佐藤汰一 on 2026/01/04.
-//
-
-struct CohabitantData: Codable {
-
- static let idField = "id"
-
- /// 家族グループのID
- let id: String
- /// 参加しているメンバーのユーザーID
- let members: [String]
-}
diff --git a/homete/Model/Domain/Cohabitant/CohabitantMember.swift b/homete/Model/Domain/Cohabitant/CohabitantMember.swift
deleted file mode 100644
index a7e7107d..00000000
--- a/homete/Model/Domain/Cohabitant/CohabitantMember.swift
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// CohabitantMember.swift
-// homete
-//
-// Created by 佐藤汰一 on 2026/01/04.
-//
-
-struct CohabitantMember: Equatable, Hashable {
-
- /// メンバーのユーザーID
- let id: String
- /// メンバーのユーザー名
- let userName: String
-}
diff --git a/homete/Model/Dependencies/AccountAuthClient.swift b/homete/Model/ImplDependencies/ImplAccountAuthClient.swift
similarity index 57%
rename from homete/Model/Dependencies/AccountAuthClient.swift
rename to homete/Model/ImplDependencies/ImplAccountAuthClient.swift
index 57ee5646..00c1035e 100644
--- a/homete/Model/Dependencies/AccountAuthClient.swift
+++ b/homete/Model/ImplDependencies/ImplAccountAuthClient.swift
@@ -5,42 +5,10 @@
// Created by 佐藤汰一 on 2025/08/03.
//
+import HometeDomain
import FirebaseAuth
-struct AccountAuthClient {
-
- let signIn: @Sendable (String, String) async throws -> AccountAuthResult
- let signOut: @Sendable () throws -> Void
- let makeListener: @Sendable () -> AccountListenerStream
- let reauthenticateWithApple: @Sendable (_ signInWithAppleResult: SignInWithAppleResult) async throws -> Void
- let revokeAppleToken: @Sendable (_ authorizationCode: String) async throws -> Void
- let deleteAccount: @Sendable () async throws -> Void
-
- init(
- signIn: @Sendable @escaping (String, String) async throws -> AccountAuthResult = { _, _ in .init(id: "id") },
- signOut: @Sendable @escaping () throws -> Void = {},
- makeListener: @Sendable @escaping () -> AccountListenerStream = {
-
- let (stream, continuation) = AsyncStream.makeStream()
- return AccountListenerStream(values: stream,
- listenerToken: NSObject(),
- continuation: continuation)
- },
- reauthenticateWithApple: @Sendable @escaping (_: SignInWithAppleResult) async throws -> Void = { _ in },
- revokeAppleToken: @Sendable @escaping (_: String) async throws -> Void = { _ in },
- deleteAccount: @Sendable @escaping () async throws -> Void = {}
- ) {
-
- self.signIn = signIn
- self.signOut = signOut
- self.makeListener = makeListener
- self.reauthenticateWithApple = reauthenticateWithApple
- self.revokeAppleToken = revokeAppleToken
- self.deleteAccount = deleteAccount
- }
-}
-
-extension AccountAuthClient: DependencyClient {
+extension AccountAuthClient {
static let liveValue: AccountAuthClient = .init(
signIn: { tokenId, nonce in
@@ -80,8 +48,6 @@ extension AccountAuthClient: DependencyClient {
try await user.delete()
}
)
-
- static let previewValue = AccountAuthClient()
}
private extension AccountAuthClient {
diff --git a/homete/Model/Dependencies/AccountInfoClient.swift b/homete/Model/ImplDependencies/ImplAccountInfoClient.swift
similarity index 52%
rename from homete/Model/Dependencies/AccountInfoClient.swift
rename to homete/Model/ImplDependencies/ImplAccountInfoClient.swift
index 89e71b89..9d74b283 100644
--- a/homete/Model/Dependencies/AccountInfoClient.swift
+++ b/homete/Model/ImplDependencies/ImplAccountInfoClient.swift
@@ -6,22 +6,9 @@
//
import FirebaseFirestore
+import HometeDomain
-struct AccountInfoClient {
-
- let insertOrUpdate: @Sendable (Account) async throws -> Void
- let fetch: @Sendable (String) async throws -> Account?
-
- init(
- insertOrUpdate: @Sendable @escaping (Account) async throws -> Void = { _ in },
- fetch: @Sendable @escaping (String) async throws -> Account? = { _ in nil }
- ) {
- self.insertOrUpdate = insertOrUpdate
- self.fetch = fetch
- }
-}
-
-extension AccountInfoClient: DependencyClient {
+extension AccountInfoClient {
private static let collectionPath = "Account"
private static let primaryKey = "id"
@@ -39,6 +26,4 @@ extension AccountInfoClient: DependencyClient {
return $0.accountRef(id: id)
}
}
-
- static let previewValue: AccountInfoClient = .init()
}
diff --git a/homete/Model/ImplDependencies/ImplAnalyticsClient.swift b/homete/Model/ImplDependencies/ImplAnalyticsClient.swift
new file mode 100644
index 00000000..9f1af32d
--- /dev/null
+++ b/homete/Model/ImplDependencies/ImplAnalyticsClient.swift
@@ -0,0 +1,22 @@
+//
+// AnalyticsClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/09.
+//
+
+import FirebaseAnalytics
+import FirebaseCrashlytics
+import HometeDomain
+
+extension AnalyticsClient {
+
+ static let liveValue: AnalyticsClient = .init { userId in
+
+ Analytics.setUserID(userId)
+ Crashlytics.crashlytics().setUserID(userId)
+ } log: { event in
+
+ Analytics.logEvent(event.name, parameters: event.parameters)
+ }
+}
diff --git a/homete/Model/ImplDependencies/ImplCohabitantClient.swift b/homete/Model/ImplDependencies/ImplCohabitantClient.swift
new file mode 100644
index 00000000..34c07770
--- /dev/null
+++ b/homete/Model/ImplDependencies/ImplCohabitantClient.swift
@@ -0,0 +1,29 @@
+//
+// CohabitantClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/08/18.
+//
+
+import FirebaseFirestore
+import HometeDomain
+
+extension CohabitantClient {
+
+ static let liveValue: CohabitantClient = .init { data in
+
+ try await FirestoreService.shared.insertOrUpdate(data: data) {
+
+ return $0.cohabitantRef(id: data.id)
+ }
+ } addSnapshotListener: { listenerId, cohabitantId in
+
+ return await FirestoreService.shared.addSnapshotListener(id: listenerId) {
+ $0.collection(path: .cohabitant)
+ .whereField(CohabitantData.idField, isEqualTo: cohabitantId)
+ }
+ } removeSnapshotListener: { listenerId in
+
+ await FirestoreService.shared.removeSnapshotListener(id: listenerId)
+ }
+}
diff --git a/homete/Model/Dependencies/CohabitantPushNotificationClient.swift b/homete/Model/ImplDependencies/ImplCohabitantPushNotificationClient.swift
similarity index 62%
rename from homete/Model/Dependencies/CohabitantPushNotificationClient.swift
rename to homete/Model/ImplDependencies/ImplCohabitantPushNotificationClient.swift
index 0c536610..bb6a650e 100644
--- a/homete/Model/Dependencies/CohabitantPushNotificationClient.swift
+++ b/homete/Model/ImplDependencies/ImplCohabitantPushNotificationClient.swift
@@ -6,12 +6,9 @@
//
import FirebaseFunctions
+import HometeDomain
-struct CohabitantPushNotificationClient {
- let send: @Sendable (_ id: String, _ content: PushNotificationContent) async throws -> Void
-}
-
-extension CohabitantPushNotificationClient: DependencyClient {
+extension CohabitantPushNotificationClient {
static let liveValue: CohabitantPushNotificationClient = .init { id, content in
_ = try await Functions.functions()
@@ -22,6 +19,4 @@ extension CohabitantPushNotificationClient: DependencyClient {
"body": content.message
])
}
-
- static let previewValue: CohabitantPushNotificationClient = .init { _, _ in }
}
diff --git a/homete/Model/ImplDependencies/ImplHouseworkClient.swift b/homete/Model/ImplDependencies/ImplHouseworkClient.swift
new file mode 100644
index 00000000..40a0e590
--- /dev/null
+++ b/homete/Model/ImplDependencies/ImplHouseworkClient.swift
@@ -0,0 +1,46 @@
+//
+// HouseworkClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/09/07.
+//
+
+import FirebaseFirestore
+import HometeDomain
+
+extension HouseworkClient {
+
+ static let liveValue = HometeDomain.HouseworkClient { item, cohabitantId in
+
+ try await FirestoreService.shared.insertOrUpdate(data: item) {
+
+ return $0
+ .houseworkListRef(id: cohabitantId)
+ .document(item.id)
+ }
+ } removeItemHandler: { item, cohabitantId in
+
+ try await FirestoreService.shared.delete {
+
+ return $0
+ .houseworkListRef(id: cohabitantId)
+ .document(item.id)
+ }
+ } snapshotListenerHandler: { id, cohabitantId, anchorDate, offset in
+
+ let targetDateList = HouseworkIndexedDate.calcTargetPeriod(
+ anchorDate: anchorDate,
+ offsetDays: offset,
+ calendar: .autoupdatingCurrent
+ )
+
+ return await FirestoreService.shared.addSnapshotListener(id: id) {
+
+ return $0.houseworkListRef(id: cohabitantId)
+ .whereField("indexedDate", in: targetDateList)
+ }
+ } removeListenerHandler: { id in
+
+ await FirestoreService.shared.removeSnapshotListener(id: id)
+ }
+}
diff --git a/homete/Model/Dependencies/NonceGenerationClient.swift b/homete/Model/ImplDependencies/ImplNonceGenerationClient.swift
similarity index 76%
rename from homete/Model/Dependencies/NonceGenerationClient.swift
rename to homete/Model/ImplDependencies/ImplNonceGenerationClient.swift
index c99bf688..c49fb7cd 100644
--- a/homete/Model/Dependencies/NonceGenerationClient.swift
+++ b/homete/Model/ImplDependencies/ImplNonceGenerationClient.swift
@@ -7,17 +7,9 @@
import CryptoKit
import Foundation
+import HometeDomain
-struct NonceGenerationClient {
-
- let value: @Sendable () -> SignInWithAppleNonce
- func callAsFunction() -> SignInWithAppleNonce {
-
- return value()
- }
-}
-
-extension NonceGenerationClient: DependencyClient {
+extension NonceGenerationClient {
static let liveValue: NonceGenerationClient = .init {
@@ -49,9 +41,4 @@ extension NonceGenerationClient: DependencyClient {
let hashString = hashedData.compactMap { String(format: "%02x", $0) }.joined()
return hashString
}
-
- static let previewValue: NonceGenerationClient = .init {
-
- return .init(original: "preview", sha256: "preview sha256")
- }
}
diff --git a/homete/Model/ImplDependencies/ImplSignInWithAppleClient.swift b/homete/Model/ImplDependencies/ImplSignInWithAppleClient.swift
new file mode 100644
index 00000000..7bf66c38
--- /dev/null
+++ b/homete/Model/ImplDependencies/ImplSignInWithAppleClient.swift
@@ -0,0 +1,19 @@
+//
+// SignInWithAppleClient.swift
+// homete
+//
+// Created by 佐藤汰一 on 2025/12/31.
+//
+
+import AuthenticationServices
+import HometeDomain
+
+extension SignInWithAppleClient {
+
+ static let liveValue = SignInWithAppleClient { nonce in
+
+ let signInWithApple = SignInWithApple()
+ let appleIDCredential = try await signInWithApple(nonce)
+ return try SignInWithAppleResultFactory.make(appleIDCredential, nonce)
+ }
+}
diff --git a/homete/Model/Domain/Cohabitant/CohabitantRegistration/ConfirmedRegistrationPeers.swift b/homete/Model/Service/P2P/ConfirmedRegistrationPeers.swift
similarity index 79%
rename from homete/Model/Domain/Cohabitant/CohabitantRegistration/ConfirmedRegistrationPeers.swift
rename to homete/Model/Service/P2P/ConfirmedRegistrationPeers.swift
index fbec8f12..013835ff 100644
--- a/homete/Model/Domain/Cohabitant/CohabitantRegistration/ConfirmedRegistrationPeers.swift
+++ b/homete/Model/Service/P2P/ConfirmedRegistrationPeers.swift
@@ -1,28 +1,21 @@
-//
-// ConfirmedRegistrationPeers.swift
-// homete
-//
-// Created by 佐藤汰一 on 2025/08/30.
-//
-
import MultipeerConnectivity
struct ConfirmedRegistrationPeers: Equatable {
-
+
private var peers: Set
-
+
init(peers: Set) {
-
+
self.peers = peers
}
-
+
mutating func addPeer(_ peer: MCPeerID) {
-
+
peers.insert(peer)
}
-
+
func isLeadPeer(connectedPeers: Set, myPeerID: MCPeerID) -> Bool? {
-
+
guard peers == connectedPeers else { return nil }
let firstPeerID = ([myPeerID] + connectedPeers)
.sorted { $0.displayName < $1.displayName }.first
diff --git a/homete/Model/Service/SignInWithApple/SignInWithApple.swift b/homete/Model/Service/SignInWithApple/SignInWithApple.swift
index 537bb297..13f9c9b2 100644
--- a/homete/Model/Service/SignInWithApple/SignInWithApple.swift
+++ b/homete/Model/Service/SignInWithApple/SignInWithApple.swift
@@ -1,4 +1,5 @@
import AuthenticationServices
+import HometeDomain
final class SignInWithApple: NSObject, ASAuthorizationControllerDelegate {
diff --git a/homete/Model/Service/SignInWithApple/SignInWithAppleRequestFactory.swift b/homete/Model/Service/SignInWithApple/SignInWithAppleRequestFactory.swift
index 12bb1e4e..b51362a0 100644
--- a/homete/Model/Service/SignInWithApple/SignInWithAppleRequestFactory.swift
+++ b/homete/Model/Service/SignInWithApple/SignInWithAppleRequestFactory.swift
@@ -6,6 +6,7 @@
//
import AuthenticationServices
+import HometeDomain
enum SignInWithAppleRequestFactory {
diff --git a/homete/Model/Service/SignInWithApple/SignInWithAppleResultFactory.swift b/homete/Model/Service/SignInWithApple/SignInWithAppleResultFactory.swift
index 834c8ac2..07450f2b 100644
--- a/homete/Model/Service/SignInWithApple/SignInWithAppleResultFactory.swift
+++ b/homete/Model/Service/SignInWithApple/SignInWithAppleResultFactory.swift
@@ -6,6 +6,7 @@
//
import AuthenticationServices
+import HometeDomain
enum SignInWithAppleResultFactory {
static func make(
diff --git a/homete/Resouces/Localizable.xcstrings b/homete/Resouces/Localizable.xcstrings
index 864de677..5b5903c4 100644
--- a/homete/Resouces/Localizable.xcstrings
+++ b/homete/Resouces/Localizable.xcstrings
@@ -95,9 +95,6 @@
},
"はじめまして!" : {
- },
- "プライバシーポリシー" : {
-
},
"ポイント" : {
@@ -129,9 +126,6 @@
}
}
}
- },
- "ライセンス" : {
-
},
"ログアウト" : {
@@ -196,9 +190,6 @@
},
"家事がありません" : {
- },
- "家事テンプレート" : {
-
},
"家事のテンプレートが設定されていません" : {
diff --git a/homete/Views/Auth/Login/LoginView.swift b/homete/Views/Auth/Login/LoginView.swift
index f50c7a32..71b0d023 100644
--- a/homete/Views/Auth/Login/LoginView.swift
+++ b/homete/Views/Auth/Login/LoginView.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/08/03.
//
+import HometeDomain
import SwiftUI
struct LoginView: View {
@@ -65,5 +66,5 @@ private extension LoginView {
#Preview {
LoginView()
- .environment(AccountAuthStore(appDependencies: .previewValue))
+ .environment(AccountAuthStore())
}
diff --git a/homete/Views/Auth/Login/SignInUpWithAppleButton.swift b/homete/Views/Auth/Login/SignInUpWithAppleButton.swift
index 18ec72dc..0eee7a88 100644
--- a/homete/Views/Auth/Login/SignInUpWithAppleButton.swift
+++ b/homete/Views/Auth/Login/SignInUpWithAppleButton.swift
@@ -7,6 +7,7 @@
import AuthenticationServices
import SwiftUI
+import HometeDomain
struct SignInUpWithAppleButton: View {
@Environment(\.colorScheme) var colorScheme
diff --git a/homete/Views/Auth/RegistrationAccount/RegistrationAccountView.swift b/homete/Views/Auth/RegistrationAccount/RegistrationAccountView.swift
index af22a728..e64fcb7c 100644
--- a/homete/Views/Auth/RegistrationAccount/RegistrationAccountView.swift
+++ b/homete/Views/Auth/RegistrationAccount/RegistrationAccountView.swift
@@ -6,6 +6,7 @@
//
import SwiftUI
+import HometeDomain
struct RegistrationAccountView: View {
@Environment(AccountStore.self) var accountStore
@@ -86,14 +87,14 @@ private extension RegistrationAccountView {
}
#Preview("RegistrationAccountView_未入力") {
- RegistrationAccountView(authInfo: .init(id: ""))
- .environment(AccountStore(appDependencies: .previewValue))
+ RegistrationAccountView(authInfo: AccountAuthResult(id: ""))
+ .environment(AccountStore())
}
#Preview("RegistrationAccountView_入力済み") {
RegistrationAccountView(
loadingState: .init(store: .init(isLoading: true)),
- authInfo: .init(id: "Test")
+ authInfo: AccountAuthResult(id: "Test")
)
- .environment(AccountStore(appDependencies: .previewValue))
+ .environment(AccountStore())
}
diff --git a/homete/Views/Auth/RegistrationAccount/UserNameInputTextField.swift b/homete/Views/Auth/RegistrationAccount/UserNameInputTextField.swift
index 06c46ea2..9813c9b3 100644
--- a/homete/Views/Auth/RegistrationAccount/UserNameInputTextField.swift
+++ b/homete/Views/Auth/RegistrationAccount/UserNameInputTextField.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/12/27.
//
+import HometeDomain
import SwiftUI
struct UserNameInputTextField: View {
diff --git a/homete/Model/Domain/Account/LoginContext.swift b/homete/Views/Components/Environment/LoginContext+Environment.swift
similarity index 52%
rename from homete/Model/Domain/Account/LoginContext.swift
rename to homete/Views/Components/Environment/LoginContext+Environment.swift
index 7b03dc58..6bf24d9b 100644
--- a/homete/Model/Domain/Account/LoginContext.swift
+++ b/homete/Views/Components/Environment/LoginContext+Environment.swift
@@ -1,21 +1,14 @@
//
-// LoginContext.swift
+// LoginContext+Environment.swift
// homete
//
// Created by 佐藤汰一 on 2025/12/27.
//
+import HometeDomain
import SwiftUI
-struct LoginContext: Equatable {
-
- let account: Account
-
- /// パートナー登録済みかどうか
- var hasCohabitant: Bool { account.cohabitantId != nil }
-}
-
extension EnvironmentValues {
-
+
@Entry var loginContext = LoginContext(account: .init(id: "", userName: "", fcmToken: nil, cohabitantId: nil))
}
diff --git a/homete/Views/Components/PreviewUtil/HouseworkUtil.swift b/homete/Views/Components/PreviewUtil/HouseworkUtil.swift
index 00efe0c0..8a368869 100644
--- a/homete/Views/Components/PreviewUtil/HouseworkUtil.swift
+++ b/homete/Views/Components/PreviewUtil/HouseworkUtil.swift
@@ -6,6 +6,7 @@
//
import Foundation
+import HometeDomain
extension HouseworkItem {
diff --git a/homete/Views/HomeView/HomeView.swift b/homete/Views/HomeView/HomeView.swift
index b7cf8745..74c293bd 100644
--- a/homete/Views/HomeView/HomeView.swift
+++ b/homete/Views/HomeView/HomeView.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/08/11.
//
+import HometeDomain
import SwiftUI
struct HomeView: View {
diff --git a/homete/Views/HouseworkApproval/Components/HouseworkItemPropertyListContent.swift b/homete/Views/HouseworkApproval/Components/HouseworkItemPropertyListContent.swift
index 5914718b..1ad27f2f 100644
--- a/homete/Views/HouseworkApproval/Components/HouseworkItemPropertyListContent.swift
+++ b/homete/Views/HouseworkApproval/Components/HouseworkItemPropertyListContent.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/12/06.
//
+import HometeDomain
import SwiftUI
struct HouseworkItemPropertyListContent: View {
diff --git a/homete/Views/HouseworkApproval/HouseworkApprovalView.swift b/homete/Views/HouseworkApproval/HouseworkApprovalView.swift
index e2306f32..02b240cd 100644
--- a/homete/Views/HouseworkApproval/HouseworkApprovalView.swift
+++ b/homete/Views/HouseworkApproval/HouseworkApprovalView.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/11/23.
//
+import HometeDomain
import SwiftUI
struct HouseworkApprovalView: View {
diff --git a/homete/Views/HouseworkBoardView/HouseworkBoardView.swift b/homete/Views/HouseworkBoardView/HouseworkBoardView.swift
index 27f8d523..f97eb93d 100644
--- a/homete/Views/HouseworkBoardView/HouseworkBoardView.swift
+++ b/homete/Views/HouseworkBoardView/HouseworkBoardView.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/09/06.
//
+import HometeDomain
import SwiftUI
struct HouseworkBoardView: View {
diff --git a/homete/Views/HouseworkBoardView/SubViews/HouseBoardListRow.swift b/homete/Views/HouseworkBoardView/SubViews/HouseBoardListRow.swift
index 3e6fac6c..50826103 100644
--- a/homete/Views/HouseworkBoardView/SubViews/HouseBoardListRow.swift
+++ b/homete/Views/HouseworkBoardView/SubViews/HouseBoardListRow.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/10/28.
//
+import HometeDomain
import SwiftUI
struct HouseBoardListRow: View {
diff --git a/homete/Views/HouseworkBoardView/SubViews/HouseworkBoardListContent.swift b/homete/Views/HouseworkBoardView/SubViews/HouseworkBoardListContent.swift
index a2b67e79..45467497 100644
--- a/homete/Views/HouseworkBoardView/SubViews/HouseworkBoardListContent.swift
+++ b/homete/Views/HouseworkBoardView/SubViews/HouseworkBoardListContent.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/09/06.
//
+import HometeDomain
import SwiftUI
struct HouseworkBoardListContent: View {
diff --git a/homete/Views/HouseworkBoardView/SubViews/HouseworkBoardSegmentedControl.swift b/homete/Views/HouseworkBoardView/SubViews/HouseworkBoardSegmentedControl.swift
index 8c8bbfd4..46f5b67b 100644
--- a/homete/Views/HouseworkBoardView/SubViews/HouseworkBoardSegmentedControl.swift
+++ b/homete/Views/HouseworkBoardView/SubViews/HouseworkBoardSegmentedControl.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/09/06.
//
+import HometeDomain
import SwiftUI
struct HouseworkBoardSegmentedControl: View {
diff --git a/homete/Views/HouseworkDetailView/HouseworkDetailView.swift b/homete/Views/HouseworkDetailView/HouseworkDetailView.swift
index 72eac2e3..cae30be7 100644
--- a/homete/Views/HouseworkDetailView/HouseworkDetailView.swift
+++ b/homete/Views/HouseworkDetailView/HouseworkDetailView.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/11/08.
//
+import HometeDomain
import SwiftUI
struct HouseworkDetailView: View {
diff --git a/homete/Views/HouseworkDetailView/SubViews/HouseworkDetailActionContent.swift b/homete/Views/HouseworkDetailView/SubViews/HouseworkDetailActionContent.swift
index 2c4ce35f..a6c2df50 100644
--- a/homete/Views/HouseworkDetailView/SubViews/HouseworkDetailActionContent.swift
+++ b/homete/Views/HouseworkDetailView/SubViews/HouseworkDetailActionContent.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/11/16.
//
+import HometeDomain
import SwiftUI
struct HouseworkDetailActionContent: View {
diff --git a/homete/Views/HouseworkDetailView/SubViews/HouseworkDetailItemListContent.swift b/homete/Views/HouseworkDetailView/SubViews/HouseworkDetailItemListContent.swift
index 2952ee00..a737a7df 100644
--- a/homete/Views/HouseworkDetailView/SubViews/HouseworkDetailItemListContent.swift
+++ b/homete/Views/HouseworkDetailView/SubViews/HouseworkDetailItemListContent.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2026/01/04.
//
+import HometeDomain
import SwiftUI
struct HouseworkDetailItemListContent: View {
diff --git a/homete/Views/RegisterCohabitantView/CohabitantRegistrationView.swift b/homete/Views/RegisterCohabitantView/CohabitantRegistrationView.swift
index 840c42f1..69c3e361 100644
--- a/homete/Views/RegisterCohabitantView/CohabitantRegistrationView.swift
+++ b/homete/Views/RegisterCohabitantView/CohabitantRegistrationView.swift
@@ -6,6 +6,7 @@
//
import MultipeerConnectivity
+import HometeDomain
import SwiftUI
struct CohabitantRegistrationView: View {
diff --git a/homete/Views/RegisterCohabitantView/SubViews/CohabitantRegistrationSession.swift b/homete/Views/RegisterCohabitantView/SubViews/CohabitantRegistrationSession.swift
index 2f6a907c..e15f9a03 100644
--- a/homete/Views/RegisterCohabitantView/SubViews/CohabitantRegistrationSession.swift
+++ b/homete/Views/RegisterCohabitantView/SubViews/CohabitantRegistrationSession.swift
@@ -6,6 +6,7 @@
//
import MultipeerConnectivity
+import HometeDomain
import SwiftUI
struct CohabitantRegistrationSession: View {
diff --git a/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingFollowerView.swift b/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingFollowerView.swift
index 5f1c6547..20c7b850 100644
--- a/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingFollowerView.swift
+++ b/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingFollowerView.swift
@@ -6,6 +6,7 @@
//
import MultipeerConnectivity
+import HometeDomain
import SwiftUI
struct CohabitantRegistrationProcessingFollower: View {
diff --git a/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingLeader.swift b/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingLeader.swift
index 6c2a8041..c3eaf924 100644
--- a/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingLeader.swift
+++ b/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingLeader.swift
@@ -6,6 +6,7 @@
//
import MultipeerConnectivity
+import HometeDomain
import SwiftUI
struct CohabitantRegistrationProcessingLeader: View {
diff --git a/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingView.swift b/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingView.swift
index f183305c..7e1ea426 100644
--- a/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingView.swift
+++ b/homete/Views/RegisterCohabitantView/SubViews/ProcessingState/CohabitantRegistrationProcessingView.swift
@@ -7,6 +7,7 @@
import Combine
import MultipeerConnectivity
+import HometeDomain
import SwiftUI
struct CohabitantRegistrationProcessingView: View {
diff --git a/homete/Views/RegisterCohabitantView/SubViews/ScanningState/CohabitantRegistrationPeersListView.swift b/homete/Views/RegisterCohabitantView/SubViews/ScanningState/CohabitantRegistrationPeersListView.swift
index ef8c09d3..4d87b2f2 100644
--- a/homete/Views/RegisterCohabitantView/SubViews/ScanningState/CohabitantRegistrationPeersListView.swift
+++ b/homete/Views/RegisterCohabitantView/SubViews/ScanningState/CohabitantRegistrationPeersListView.swift
@@ -6,6 +6,7 @@
//
import MultipeerConnectivity
+import HometeDomain
import SwiftUI
struct CohabitantRegistrationPeersListView: View {
diff --git a/homete/Views/RegisterCohabitantView/SubViews/ScanningState/CohabitantRegistrationScanningStateView.swift b/homete/Views/RegisterCohabitantView/SubViews/ScanningState/CohabitantRegistrationScanningStateView.swift
index a5858295..7917e64e 100644
--- a/homete/Views/RegisterCohabitantView/SubViews/ScanningState/CohabitantRegistrationScanningStateView.swift
+++ b/homete/Views/RegisterCohabitantView/SubViews/ScanningState/CohabitantRegistrationScanningStateView.swift
@@ -6,6 +6,7 @@
//
import MultipeerConnectivity
+import HometeDomain
import SwiftUI
struct CohabitantRegistrationScanningStateView: View {
diff --git a/homete/Views/RegisterHouseworkView/RegisterHouseworkView.swift b/homete/Views/RegisterHouseworkView/RegisterHouseworkView.swift
index cca38464..a664ac48 100644
--- a/homete/Views/RegisterHouseworkView/RegisterHouseworkView.swift
+++ b/homete/Views/RegisterHouseworkView/RegisterHouseworkView.swift
@@ -5,8 +5,9 @@
// Created by 佐藤汰一 on 2025/09/07.
//
-import Prefire
import FirebaseFunctions
+import Prefire
+import HometeDomain
import SwiftUI
struct RegisterHouseworkView: View {
diff --git a/homete/Views/RootView/LaunchStateProxy.swift b/homete/Views/RootView/LaunchStateProxy.swift
index 3ca23f13..770d5da4 100644
--- a/homete/Views/RootView/LaunchStateProxy.swift
+++ b/homete/Views/RootView/LaunchStateProxy.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/12/27.
//
+import HometeDomain
import SwiftUI
struct LaunchStateProxy {
diff --git a/homete/Views/RootView/RootView.swift b/homete/Views/RootView/RootView.swift
index ec996313..423f9620 100644
--- a/homete/Views/RootView/RootView.swift
+++ b/homete/Views/RootView/RootView.swift
@@ -6,6 +6,7 @@
//
import FirebaseMessaging
+import HometeDomain
import SwiftUI
struct RootView: View {
@@ -60,13 +61,21 @@ extension RootView {
static func make() -> some View {
DependenciesInjectLayer {
RootView()
- .environment(AccountStore(appDependencies: $0))
- .environment(AccountAuthStore(appDependencies: $0))
+ .environment(AccountStore(accountInfoClient: $0.accountInfoClient))
+ .environment(AccountAuthStore(
+ accountAuthClient: $0.accountAuthClient,
+ analyticsClient: $0.analyticsClient,
+ signInWithAppleClient: $0.signInWithAppleClient,
+ nonceGenerationClient: $0.nonceGeneratorClient
+ ))
.environment(HouseworkListStore(
houseworkClient: $0.houseworkClient,
cohabitantPushNotificationClient: $0.cohabitantPushNotificationClient
))
- .environment(CohabitantStore(appDependencies: $0))
+ .environment(CohabitantStore(
+ cohabitantClient: $0.cohabitantClient,
+ accountInfoClient: $0.accountInfoClient
+ ))
}
}
}
diff --git a/homete/Views/SettingView/SettingView.swift b/homete/Views/SettingView/SettingView.swift
index 835a0869..3ca47d3e 100644
--- a/homete/Views/SettingView/SettingView.swift
+++ b/homete/Views/SettingView/SettingView.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/08/11.
//
+import HometeDomain
import SwiftUI
struct SettingView: View {
@@ -123,6 +124,6 @@ private extension SettingView {
#Preview {
SettingView()
- .environment(AccountAuthStore(appDependencies: .previewValue))
- .environment(AccountStore(appDependencies: .previewValue))
+ .environment(AccountAuthStore())
+ .environment(AccountStore())
}
diff --git a/homete/Views/SettingView/SubViews/SettingMenuItemButton.swift b/homete/Views/SettingView/SubViews/SettingMenuItemButton.swift
index c94ef0df..2f0a061a 100644
--- a/homete/Views/SettingView/SubViews/SettingMenuItemButton.swift
+++ b/homete/Views/SettingView/SubViews/SettingMenuItemButton.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/08/11.
//
+import HometeDomain
import SwiftUI
struct SettingMenuItemButton: View {
diff --git a/homete/Views/TabView/AppTabView.swift b/homete/Views/TabView/AppTabView.swift
index bdcda430..354c1fd6 100644
--- a/homete/Views/TabView/AppTabView.swift
+++ b/homete/Views/TabView/AppTabView.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/09/06.
//
+import HometeDomain
import SwiftUI
import UserNotifications
@@ -116,8 +117,8 @@ extension AppTabView {
#Preview {
AppTabView()
- .environment(AccountStore(appDependencies: .previewValue))
- .environment(AccountAuthStore(appDependencies: .previewValue))
+ .environment(AccountStore())
+ .environment(AccountAuthStore())
.environment(HouseworkListStore(
houseworkClient: .previewValue,
cohabitantPushNotificationClient: .previewValue
diff --git a/homete/Views/ViewUtilities/Alert/DomainErrorAlertContent.swift b/homete/Views/ViewUtilities/Alert/DomainErrorAlertContent.swift
index 40dd2386..0861c2d4 100644
--- a/homete/Views/ViewUtilities/Alert/DomainErrorAlertContent.swift
+++ b/homete/Views/ViewUtilities/Alert/DomainErrorAlertContent.swift
@@ -5,6 +5,7 @@
// Created by 佐藤汰一 on 2025/11/11.
//
+import HometeDomain
import SwiftUI
struct DomainErrorAlertContent {
diff --git a/homete/Views/ViewUtilities/Navigation/AppNavigationElement.swift b/homete/Views/ViewUtilities/Navigation/AppNavigationElement.swift
index 68f1c069..d09a5d15 100644
--- a/homete/Views/ViewUtilities/Navigation/AppNavigationElement.swift
+++ b/homete/Views/ViewUtilities/Navigation/AppNavigationElement.swift
@@ -5,6 +5,8 @@
// Created by 佐藤汰一 on 2025/11/08.
//
+import HometeDomain
+
enum AppNavigationElement: Hashable {
/// 家事詳細画面
case houseworkDetail(item: HouseworkItem)
diff --git a/hometeTests/Domain/CohabitantRegistration/ConfirmedRegistrationPeersTest.swift b/hometeTests/Domain/CohabitantRegistration/ConfirmedRegistrationPeersTest.swift
deleted file mode 100644
index 476dcb52..00000000
--- a/hometeTests/Domain/CohabitantRegistration/ConfirmedRegistrationPeersTest.swift
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-// ConfirmedRegistrationPeersTest.swift
-// hometeTests
-//
-// Created by 佐藤汰一 on 2025/08/31.
-//
-
-import MultipeerConnectivity
-import Testing
-@testable import homete
-
-struct ConfirmedRegistrationPeersTest {
-
- @Test("PeerIDの表示名の降順で一番最初のPeerIDになるデバイスがリードデバイスになる")
- func isLeadPeer_lead_case() throws {
-
- let connectedPeers: Set = [
- .init(displayName: "BBB"),
- .init(displayName: "CCC"),
- .init(displayName: "EEE")
- ]
- let peers = ConfirmedRegistrationPeers(peers: connectedPeers)
-
- let actual = peers.isLeadPeer(
- connectedPeers: connectedPeers,
- myPeerID: .init(displayName: "AAA")
- )
-
- #expect(actual == true)
- }
-
- @Test(
- "PeerIDの表示名の降順で一番最初ではない場合は、フォロワーデバイスになる",
- arguments: [
- MCPeerID(displayName: "DDD"),
- .init(displayName: "FFF"),
- .init(displayName: "CCC"),
- .init(displayName: "ZZZ")
- ]
- )
- func isLeadPeer_follower_case(myPeerID: MCPeerID) throws {
-
- let connectedPeers: Set = [
- .init(displayName: "BBB"),
- .init(displayName: "CCC"),
- .init(displayName: "EEE")
- ]
- let peers = ConfirmedRegistrationPeers(peers: connectedPeers)
-
- let actual = peers.isLeadPeer(connectedPeers: connectedPeers, myPeerID: myPeerID)
-
- #expect(actual == false)
- }
-
- @Test(
- "接続中の全てのデバイスが確認済みでない場合は、まだ登録メンバーが揃っていないのでリードデバイスかどうかを返さない"
- )
- func isLeadPeer_not_match_case() throws {
-
- let confirmedPeers: Set = [
- .init(displayName: "BBB"),
- .init(displayName: "CCC")
- ]
- let connectedPeers: Set = .init(confirmedPeers + [.init(displayName: "EEE")])
- let peers = ConfirmedRegistrationPeers(peers: confirmedPeers)
-
- let actual = peers.isLeadPeer(connectedPeers: connectedPeers, myPeerID: .init(displayName: "AAA"))
-
- #expect(actual == nil)
- }
-}