SwiftUIでクリーンアーキテクチャを導入する方法とそのメリット

  • 2025年4月25日
  • 2025年4月25日
  • Swift
  • 2View
  • 0件

SwiftUIでクリーンアーキテクチャを導入する方法とそのメリット

SwiftUIでアプリを作っていると、「コードが散らかってきた…」「Viewにロジックが詰まりすぎて読みにくい…」と感じる瞬間はありませんか?

そこでおすすめなのが「クリーンアーキテクチャ」。
この記事では、SwiftUIでクリーンアーキテクチャをどう導入するかどんなメリットがあるかを初心者にもわかりやすく解説します。


1. クリーンアーキテクチャとは?

「責務を分離して、保守性・テスト性を高める設計思想」のことです。

主な層:

  • View層:UI表示のみ
  • Presenter / ViewModel層:UI向けの状態や処理
  • UseCase層:ビジネスロジックを司る
  • Repository層:データ取得の抽象化(API・DBなど)
  • Entity層:アプリの基本的なデータ構造

この構造により、ロジックとUIが分離され、スケーラブルなコードになります。


2. SwiftUIでの構造イメージ


MyApp/
├── View/              ← SwiftUIの画面
├── ViewModel/         ← ObservableObjectで状態管理
├── UseCase/           ← アプリ固有の処理
├── Repository/        ← APIやDBとのやり取り
├── Entity/            ← データモデル
└── DI/                ← 依存注入用

実際のプロジェクト構成もこのように分けておくと、自然と役割が明確になります。


3. サンプルコードで解説

「ユーザー名を取得して表示する」というシンプルな例で、各層を紹介します。

① Entity

struct User {
    let id: Int
    let name: String
}

② Repository

protocol UserRepository {
    func fetchUser() async throws -> User
}

final class MockUserRepository: UserRepository {
    func fetchUser() async throws -> User {
        return User(id: 1, name: "太郎")
    }
}

③ UseCase

protocol FetchUserUseCase {
    func execute() async throws -> User
}

final class FetchUserUseCaseImpl: FetchUserUseCase {
    private let repository: UserRepository
    init(repository: UserRepository) {
        self.repository = repository
    }

    func execute() async throws -> User {
        try await repository.fetchUser()
    }
}

④ ViewModel

@MainActor
final class UserViewModel: ObservableObject {
    @Published var userName: String = ""

    private let fetchUserUseCase: FetchUserUseCase

    // DI処理:ここでRepository → UseCaseを初期化
    init() {
        let repository: UserRepository = MockUserRepository()
        self.fetchUserUseCase = FetchUserUseCaseImpl(repository: repository)
    }

    func loadUser() async {
        do {
            let user = try await fetchUserUseCase.execute()
            self.userName = user.name
        } catch {
            self.userName = "エラー"
        }
    }
}

⑤ View

struct UserView: View {
    @StateObject private var viewModel = UserViewModel()

    var body: some View {
        VStack {
            Text(viewModel.userName)
                .font(.title)
            Button("読み込み") {
                Task {
                    await viewModel.loadUser()
                }
            }
        }
        .padding()
    }
}

4. クリーンアーキテクチャ導入のメリット

  • コードが読みやすくなる
  • Viewのテストがしやすくなる
  • スケーラブルで保守しやすい
  • 将来的な機能追加やAPI変更にも柔軟に対応

小さなアプリでもこの構成を意識しておくと、後から必ず助かります。


5. まとめ

SwiftUIでクリーンアーキテクチャを導入すると、責任の所在が明確になり、コードの見通しが劇的に改善します。

最初は少し構造が大げさに感じるかもしれませんが、慣れてくるとコードの分離と再利用が快適になります。ぜひあなたのアプリにも取り入れてみてください!