swift-expert について
swift-expertは、アーキテクチャ、並行処理、パフォーマンス、テストを扱うSwift開発向けスキルです。プロトコル優先の設計と型安全性を重視し、ビルドやテストのコマンドで実装を検証します。
主な機能
- 01アーキテクチャとプラットフォームの分析
- 02プロトコル優先のAPI設計
- 03async/awaitと並行処理の指針
- 04Instrumentsによる性能プロファイリング
- 05XCTestのテストガイダンス
活用シーン
- 01SwiftモジュールとプロトコルAPIの設計
- 02非同期処理とスレッドセーフな状態の実装
- 03性能や並行処理の問題調査
- 04XCTestの作成と実行
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ farmage/ opencode-skills --skill swift-expertインストール後、Claude Code で/swift-expertを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/async-concurrency.mdmemory-performance.mdprotocol-oriented.mdswiftui-patterns.mdtesting-patterns.md詳細
Swift Expert
コアワークフロー
- アーキテクチャ分析 - 対象プラットフォーム、依存関係、デザインパターンを特定します
- プロトコルの設計 - 関連型を使った、プロトコルを優先する API を作成します
- 実装 - async/await と値セマンティクスを用いて、型安全なコードを記述します
- 最適化 - Instruments でプロファイリングを行い、スレッドセーフであることを確認します
- テスト - XCTest と非同期パターンを用いて、包括的なテストを記述します
検証チェックポイント: ステップ 3 の後に
swift buildを実行して、コンパイルを確認します。ステップ 4 の後にswift build -warnings-as-errorsを実行して、アクター分離と Sendable に関する警告を確認します。ステップ 5 の後にswift testを実行し、すべての非同期テストが成功することを確認します。
リファレンスガイド
状況に応じて詳細なガイダンスを読み込みます。
| トピック | リファレンス | 読み込むタイミング |
|---|---|---|
| SwiftUI | references/swiftui-patterns.md | ビューの構築、状態管理、モディファイアの使用時 |
| 並行処理 | references/async-concurrency.md | async/await、アクター、構造化並行処理を扱う時 |
| プロトコル | references/protocol-oriented.md | プロトコル設計、ジェネリクス、型消去を扱う時 |
| メモリ | references/memory-performance.md | ARC、weak/unowned、パフォーマンス最適化を扱う時 |
| テスト | references/testing-patterns.md | XCTest、非同期テスト、モック戦略を扱う時 |
コードパターン
async/await — 正しい例と誤った例
// ✅ DO: async/await with structured error handling
func fetchUser(id: String) async throws -> User {
let url = URL(string: "https://api.example.com/users/\(id)")!
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode(User.self, from: data)
}
// ❌ DON'T: mixing completion handlers with async context
func fetchUser(id: String) async throws -> User {
return try await withCheckedThrowingContinuation { continuation in
// Avoid wrapping existing async APIs this way when a native async version exists
legacyFetch(id: id) { result in
continuation.resume(with: result)
}
}
}
SwiftUI の状態管理
// ✅ DO: use @Observable (Swift 5.9+) for view models
@Observable
final class CounterViewModel {
var count = 0
func increment() { count += 1 }
}
struct CounterView: View {
@State private var vm = CounterViewModel()
var body: some View {
VStack {
Text("\(vm.count)")
Button("Increment", action: vm.increment)
}
}
}
// ❌ DON'T: reach for ObservableObject/Published when @Observable suffices
class LegacyViewModel: ObservableObject {
@Published var count = 0 // Unnecessary boilerplate in Swift 5.9+
}
プロトコル指向アーキテクチャ
// ✅ DO: define capability protocols with associated types
protocol Repository<Entity> {
associatedtype Entity: Identifiable
func fetch(id: Entity.ID) async throws -> Entity
func save(_ entity: Entity) async throws
}
struct UserRepository: Repository {
typealias Entity = User
func fetch(id: UUID) async throws -> User { /* … */ }
func save(_ user: User) async throws { /* … */ }
}
// ❌ DON'T: use classes as base types when a protocol fits
class BaseRepository { // Avoid class inheritance for shared behavior
func fetch(id: UUID) async throws -> Any { fatalError("Override required") }
}
スレッドセーフのためのアクター
// ✅ DO: isolate mutable shared state in an actor
actor ImageCache {
private var cache: [URL: UIImage] = [:]
func image(for url: URL) -> UIImage? { cache[url] }
func store(_ image: UIImage, for url: URL) { cache[url] = image }
}
// ❌ DON'T: use a class with manual locking
class UnsafeImageCache {
private var cache: [URL: UIImage] = [:]
private let lock = NSLock() // Error-prone; prefer actor isolation
func image(for url: URL) -> UIImage? {
lock.lock(); defer { lock.unlock() }
return cache[url]
}
}
制約
必ず行うこと
- 型ヒントと型推論を適切に使います
- Swift API Design Guidelines に従います
- 非同期処理には
async/awaitを使います(上記のパターンを参照) - 並行処理において
Sendableに準拠していることを確認します - デフォルトでは値型(
struct/enum)を使います - マークアップコメント(
/// …)で API をドキュメント化します - 横断的な関心事にはプロパティラッパーを使います
- 最適化の前に Instruments でプロファイリングを行います
絶対に行わないこと
- 正当な理由なく強制アンラップ(
!)を使います - クロージャに強参照循環を作ります
- 同期コードと非同期コードを不適切に混在させます
- アクター分離の警告を無視します
- 暗黙的アンラップ型オプショナルを不必要に使います
- エラー処理を省略します
- Swift に代替手段がある場合に Objective-C のパターンを使います
- プラットフォーム固有の値をハードコードします
出力テンプレート
Swift の機能を実装する際は、以下を提示します。
- プロトコル定義と型エイリアス
- モデル型(値セマンティクスを持つ構造体/クラス)
- ビューの実装(SwiftUI)またはビューコントローラー
- 使用例を示すテスト
- アーキテクチャ上の判断についての簡潔な説明
コメント
Markdown 対応