一键导入
tca-feature-development
VoiceYourTextアプリでThe Composable Architecture(TCA)を使用した新機能開発をサポートします。Reducer、State、Action、Dependencyの実装パターンに従い、テスト可能で保守性の高いコードを作成します。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
VoiceYourTextアプリでThe Composable Architecture(TCA)を使用した新機能開発をサポートします。Reducer、State、Action、Dependencyの実装パターンに従い、テスト可能で保守性の高いコードを作成します。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
iOSシミュレーターをコンピューターユースで視覚的にテストします。スクリーンショットを撮影してUI要素を確認し、座標ベースでタップ・スワイプ操作を行いテスト結果を報告します。Use when ユーザーが「シミュレーターでテストして」「iOSシミュレーターを視覚的にテストして」「computer useでシミュレーターを操作して」「シミュレーターの画面確認して」と言ったとき。
Xcode MCP(mcpbridge)を Claude Code に追加します。Use when ユーザーが「Xcode MCP入れて」「シミュレーター操作できるようにして」「mcpbridge設定して」と言ったとき。
xcodebuildとfastlaneでiOSアプリをビルド・アーカイブし、App Store/TestFlightに申請します。Use when ユーザーが「TestFlightにアップして」「App Storeに申請して」「リリースして」と言ったとき。
Step-by-step release checklist for ClipKit iOS app submission to TestFlight and App Store. Use when preparing release, uploading to TestFlight, submitting to App Store, bumping version, or creating a release.
このプロジェクトで実際に踏んだ iOS 開発の落とし穴と対策。CoreData, AVFoundation, AVAudioSession など。CoreData の設定変更・新機能追加・マイグレーション対応時に必ず参照すること。
Step-by-step release checklist for Smart Player iOS app submission to App Store. Use when preparing release, updating version, submitting to App Store, or mentioning App Store submission.
| name | tca-feature-development |
| description | VoiceYourTextアプリでThe Composable Architecture(TCA)を使用した新機能開発をサポートします。Reducer、State、Action、Dependencyの実装パターンに従い、テスト可能で保守性の高いコードを作成します。 |
The Composable Architecture(TCA)パターンに従った機能開発をサポートするスキルです。
このスキルは以下の操作をサポートします:
目的: TCAパターンに従った新しい機能を実装する
手順:
iOS/VoiceYourText/Templates/ModernReducerTemplate.swift{FeatureName}Feature.swift - Reducer実装{FeatureName}View.swift - SwiftUI View{FeatureName}Tests.swift - Unit tests@Reducer
struct FeatureNameFeature {
@ObservableState
struct State: Equatable { }
enum Action: ViewAction, BindableAction {
case binding(BindingAction<State>)
case view(View)
enum View { }
}
var body: some ReducerOf<Self> {
BindingReducer()
Reduce { state, action in
switch action {
case .view(let viewAction):
switch viewAction {
// Handle view actions
}
case .binding:
return .none
}
}
}
}
目的: ViewとReducerの責任を明確に分離する
手順:
ViewActionとBindableActionに準拠させるView enumに定義@ViewAction(for: ReducerType.self)を使用send(.view(.actionName))でアクションを送信例:
// Reducer
enum Action: ViewAction, BindableAction {
case binding(BindingAction<State>)
case view(View)
enum View {
case onAppear
case playButtonTapped
case stopButtonTapped
}
}
// View
@ViewAction(for: FeatureReducer.self)
struct FeatureView: View {
@Bindable var store: StoreOf<FeatureReducer>
var body: some View {
Button("Play") {
send(.playButtonTapped)
}
.onAppear {
send(.onAppear)
}
}
}
目的: 外部サービスやAPIをテスト可能な形で注入する
手順:
@DependencyClientでクライアントを定義liveValueでライブ実装を提供testValueでテスト用モックを提供例:
@DependencyClient
struct SpeechSynthesizerClient {
var speak: (AVSpeechUtterance) async throws -> Void
var stopSpeaking: () async -> Bool
}
extension SpeechSynthesizerClient: DependencyKey {
static let liveValue = Self(
speak: { utterance in
// Real implementation
},
stopSpeaking: {
// Real implementation
}
)
static let testValue = Self()
}
extension DependencyValues {
var speechSynthesizer: SpeechSynthesizerClient {
get { self[SpeechSynthesizerClient.self] }
set { self[SpeechSynthesizerClient.self] = newValue }
}
}
目的: 副作用を伴う非同期処理を実装する
手順:
.runでEffectを返すsendを使用してアクションを送信例:
case .view(.loadData):
return .run { send in
do {
let data = try await apiClient.fetchData()
await send(.dataLoaded(data))
} catch {
await send(.dataLoadFailed(error))
}
}
目的: 親Reducerに子Reducerを統合する
手順:
@Presents var child: ChildFeature.State?case child(PresentationAction<ChildFeature.Action>)bodyで.ifLetを使用例:
@Reducer
struct ParentFeature {
@ObservableState
struct State {
@Presents var child: ChildFeature.State?
}
enum Action {
case child(PresentationAction<ChildFeature.Action>)
}
var body: some ReducerOf<Self> {
Reduce { state, action in
// Parent logic
}
.ifLet(\.$child, action: \.child) {
ChildFeature()
}
}
}
ユーザーの要求:
「音声プレイヤー機能をTCAで実装してほしい」
実行内容:
NowPlayingFeature.swiftを作成NowPlayingView.swiftでUIを作成結果: 再利用可能でテスト可能な音声プレイヤー機能が完成
ユーザーの要求:
「このViewControllerをTCAに変換してほしい」
実行内容:
結果: テスト可能で予測可能な状態管理
ユーザーの要求:
「API通信をDependency Injectionで実装したい」
実行内容:
@DependencyClientでAPIClientを定義liveValueで実装@Dependency(\.apiClient)を使用結果: テスト時にモックを注入可能な設計
iOS/VoiceYourText/Templates/ModernReducerTemplate.swift - TCAテンプレートiOS/VoiceYourText/Features/NowPlaying/NowPlayingFeature.swift - プレイヤー機能の実装例iOS/VoiceYourText/PDFReader/PDFReaderFeature.swift - PDF機能の実装例iOS/VoiceYourText/Features/UserDictionary/UserDictionaryManager.swift - Dependency実装例iOS/VoiceYourTextTests/PDFReaderFeatureTests.swift - Reducerテストの例原因: @ObservableStateが不足しているか、@Bindableが正しく使用されていない
解決策:
@ObservableStateを付与@Bindable var storeを使用原因: Reduce内でアクションのケースが処理されていない
解決策:
switch actionで全ケースをカバー.noneを返すべき場所で忘れずに返す原因: Effect内で同じアクションを送信し続けている
解決策:
.cancellable(id:)でキャンセル可能にする原因: testValueが未実装
解決策:
testValueを実装.unimplementedを使用して未実装メソッドを検出.run内のみ@ObservableStateはSwiftUI統合を改善@Presentsはナビゲーションとモーダルに使用BindingReducerは双方向バインディングを自動処理@Dependencyプロパティラッパーで注入TestStoreを使用して状態遷移を検証