You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift与MVVM架构新项目文件目录结构(ViewModels)最佳实践咨询

Hey there! I totally get where you're coming from—those generic type-based directories (Models/Views/ViewModels) work fine for tiny projects, but once your app scales to dozens of screens and features, they turn into a nightmare to navigate. Let me share what I've used in production Swift apps that stay maintainable even as teams and codebases grow.

Swift MVVM Project Structure: Scalable, Real-World Approach

Core Principle: Organize by Feature, Not by Type

Instead of lumping all ViewModels into one overcrowded folder, group related files (ViewModel, View, Model, even supporting logic) into feature-specific directories. This way, everything related to "Checkout" or "Profile" lives in one place—no more jumping between 5 different folders to make a small change to a single feature.

Example Production-Grade Directory Structure

Here’s a breakdown of a structure I’ve relied on for mid-to-large apps:

YourAppName/
├─ Core/                  # Shared, app-wide foundational logic
│  ├─ Models/             # Cross-feature data models (e.g., User, BaseAPIResponse)
│  ├─ ViewModels/         # Base view models (e.g., BaseViewModel with common Combine bindings/loading states)
│  ├─ Services/           # Singleton/shared services (APIClient, AuthService, AnalyticsTracker)
│  ├─ Helpers/            # Utilities (DateFormatter, ValidationRules, ImageCache)
│  ├─ Extensions/         # SwiftUI/UIKit extensions (e.g., View+AppStyling, UIColor+BrandPalette)
│  └─ Resources/          # Shared assets (colors, fonts, localized strings, common icons)
├─ Features/              # All feature-specific code (the heart of your app)
│  ├─ Profile/
│  │  ├─ ProfileViewModel.swift
│  │  ├─ ProfileView.swift (or ProfileViewController.swift for UIKit)
│  │  ├─ ProfileModels.swift (feature-specific models, e.g., ProfileEditFormData)
│  │  ├─ ProfileStore.swift (local state manager for the feature, if needed)
│  │  └─ Components/      # Feature-specific subviews (e.g., ProfileHeaderView.swift)
│  ├─ Checkout/
│  │  ├─ CheckoutViewModel.swift
│  │  ├─ CheckoutView.swift
│  │  ├─ CheckoutModels.swift
│  │  ├─ CheckoutStore.swift
│  │  └─ Components/
│  └─ Home/
│     ├─ HomeViewModel.swift
│     ├─ HomeView.swift
│     ├─ HomeModels.swift
│     └─ Components/
├─ Tests/                 # Mirror the main structure for unit/integration tests
│  ├─ CoreTests/
│  └─ FeaturesTests/
└─ UITests/

Why This Solves ViewModel Management Pain Points

  • No more endless scrolling: Each feature’s ViewModel lives right next to its corresponding View and Model, making it trivial to trace logic flow.
  • Encapsulation: A ViewModel tied exclusively to the Profile feature won’t pollute the global namespace or get mixed up with unrelated ViewModels.
  • Team-friendly: Multiple developers can work on different features simultaneously without conflicting in a single ViewModels directory.

Pro Tips for ViewModel Maintenance

  • Leverage base ViewModels: Create a BaseViewModel in Core/ViewModels that handles repetitive tasks like loading state tracking, error handling, and Combine binding setup. All feature-specific ViewModels inherit from this to cut down on code duplication.
  • Avoid "God ViewModels": If a ViewModel grows beyond 300 lines, split it into smaller focused components. For example, a HomeViewModel might delegate feed logic to a HomeFeedManager or search logic to a HomeSearchHandler.
  • Pair ViewModels with feature-specific Stores: For complex state (like multi-step checkout), use a dedicated Store within the feature folder. The ViewModel interacts with the Store to fetch/update state, keeping the ViewModel focused on presenting data to the View, not managing raw state.

When to Fall Back to Type-Based Directories

Type-based folders still have value for shared, app-wide code. For example, Core/Models holds models used across multiple features (like User), while feature-specific models stay in their respective feature folders.

Final Thought

The key is flexibility—adjust the structure to fit your team’s workflow and app’s complexity. If you have tons of shared UI components, add a SharedComponents folder under Core. The goal is to make it easy for any developer (new or veteran) to find code quickly and understand how parts of the app connect.

内容的提问来源于stack exchange,提问作者Erez Hod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:35:06