RepoPilotOpen in app →

kudoleh/iOS-Clean-Architecture-MVVM

Template iOS app using Clean Architecture and MVVM. Includes DIContainer, FlowCoordinator, DTO, Response Caching and one of the views in SwiftUI

Mixed

Missing license — unclear to depend on

worst of 4 axes
Use as dependencyConcerns

no license — legally unclear; no tests detected

Fork & modifyConcerns

no license — can't legally use code; no tests detected

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isConcerns

no license — can't legally use code

  • Last commit 3w ago
  • 13 active contributors
  • CI configured
Show 3 more →
  • Concentrated ownership — top contributor handles 79% of recent commits
  • No license — legally unclear to depend on
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: publish a permissive license (MIT, Apache-2.0, etc.)
  • Fork & modify ConcernsMixed if: add a LICENSE file
  • Deploy as-is ConcernsMixed if: add a LICENSE file

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Great to learn from" badge

Paste into your README — live-updates from the latest cached analysis.

RepoPilot: Great to learn from
[![RepoPilot: Great to learn from](https://repopilot.app/api/badge/kudoleh/ios-clean-architecture-mvvm?axis=learn)](https://repopilot.app/r/kudoleh/ios-clean-architecture-mvvm)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/kudoleh/ios-clean-architecture-mvvm on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: kudoleh/iOS-Clean-Architecture-MVVM

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/kudoleh/iOS-Clean-Architecture-MVVM shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Missing license — unclear to depend on

  • Last commit 3w ago
  • 13 active contributors
  • CI configured
  • ⚠ Concentrated ownership — top contributor handles 79% of recent commits
  • ⚠ No license — legally unclear to depend on
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live kudoleh/iOS-Clean-Architecture-MVVM repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/kudoleh/iOS-Clean-Architecture-MVVM.

What it runs against: a local clone of kudoleh/iOS-Clean-Architecture-MVVM — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in kudoleh/iOS-Clean-Architecture-MVVM | Confirms the artifact applies here, not a fork | | 2 | Default branch master exists | Catches branch renames | | 3 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 4 | Last commit ≤ 48 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>kudoleh/iOS-Clean-Architecture-MVVM</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of kudoleh/iOS-Clean-Architecture-MVVM. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/kudoleh/iOS-Clean-Architecture-MVVM.git
#   cd iOS-Clean-Architecture-MVVM
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of kudoleh/iOS-Clean-Architecture-MVVM and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "kudoleh/iOS-Clean-Architecture-MVVM(\\.git)?\\b" \\
  && ok "origin remote is kudoleh/iOS-Clean-Architecture-MVVM" \\
  || miss "origin remote is not kudoleh/iOS-Clean-Architecture-MVVM (artifact may be from a fork)"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "ExampleMVVM/Application/DIContainer/AppDIContainer.swift" \\
  && ok "ExampleMVVM/Application/DIContainer/AppDIContainer.swift" \\
  || miss "missing critical file: ExampleMVVM/Application/DIContainer/AppDIContainer.swift"
test -f "ExampleMVVM/Application/AppFlowCoordinator.swift" \\
  && ok "ExampleMVVM/Application/AppFlowCoordinator.swift" \\
  || miss "missing critical file: ExampleMVVM/Application/AppFlowCoordinator.swift"
test -f "ExampleMVVM/Domain/Interfaces/Repositories/MoviesRepository.swift" \\
  && ok "ExampleMVVM/Domain/Interfaces/Repositories/MoviesRepository.swift" \\
  || miss "missing critical file: ExampleMVVM/Domain/Interfaces/Repositories/MoviesRepository.swift"
test -f "ExampleMVVM/Data/Repositories/DefaultMoviesRepository.swift" \\
  && ok "ExampleMVVM/Data/Repositories/DefaultMoviesRepository.swift" \\
  || miss "missing critical file: ExampleMVVM/Data/Repositories/DefaultMoviesRepository.swift"
test -f "ExampleMVVM/Infrastructure/Network/DataTransferService.swift" \\
  && ok "ExampleMVVM/Infrastructure/Network/DataTransferService.swift" \\
  || miss "missing critical file: ExampleMVVM/Infrastructure/Network/DataTransferService.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 48 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~18d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/kudoleh/iOS-Clean-Architecture-MVVM"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

An Xcode project template demonstrating Clean Architecture + MVVM applied to a movie search iOS app. It implements strict layer separation (Domain/Data/Presentation), reactive data binding via a custom Observable, dependency injection through DIContainer, and concrete examples of CoreData caching, API pagination, and SwiftUI/UIKit view reuse—serving as a blueprint for structuring production iOS apps with testable, maintainable layers. Clean layered monolith: ExampleMVVM/ root contains Application/ (AppDelegate, AppFlowCoordinator, DIContainer/), Domain/ (use cases, entities, repository interfaces), Data/ (Network with APIEndpoints and DataMapping/, PersistentStorages with CoreData and UserDefaults implementations), Presentation/ (MVVM ViewModels with Observable binding, separate SwiftUI and UIKit View implementations). Data → Presentation/Domain dependency enforced via folder structure; no cross-layer imports.

👥Who it's for

iOS engineers building new apps or refactoring existing ones who want a reference implementation of Clean Architecture patterns; architects evaluating layered design approaches for Swift projects; teams establishing coding standards around dependency injection and MVVM. Specifically: developers who need to understand how to wire ViewModels to both UIKit and SwiftUI without code duplication.

🌱Maturity & risk

Moderately mature, active template: includes CI setup (Travis CI + Fastlane in .travis.yml), unit tests across Domain/Presentation/Infrastructure layers, and multiple persistent storage implementations (CoreData, UserDefaults). Last visible structure shows dual data models in CoreDataStorage.xcdatamodeld and well-organized test suites. No indicators of abandonment, but it's a reference template rather than a production framework, so updates follow education cycles rather than feature velocity.

Low risk as a template/reference, but beware: single maintainer (kudoleh), no CocoaPods/SPM dependency declarations visible in file list (DIContainer wiring is manual), and template nature means it's optimized for learning clarity over production performance optimizations. If forking for production, you'll inherit the manual DI setup and must add your own package management strategy. Travis CI config exists but CI status visibility is limited from file list alone.

Active areas of work

Repo appears stable rather than actively developed (template nature). Latest visible work includes dual CoreData model versions (CoreDataStorage.xcdatamodeld has '2.xcdatamodel' and base version), suggesting recent persistence layer iteration. SwiftUI view support indicates modernization for recent iOS SDKs. No open PR data visible, but structure suggests maintenance is reactive (supporting new Xcode/iOS versions) rather than feature-driven.

🚀Get running

git clone https://github.com/kudoleh/iOS-Clean-Architecture-MVVM.git
cd iOS-Clean-Architecture-MVVM
open ExampleMVVM.xcodeproj

Then select ExampleMVVM scheme, pick a simulator target (Xcode 11+), and press ▶ Run. No external package manager setup required; all dependencies are framework-level (UIKit, SwiftUI, CoreData) already linked in Xcode project.

Daily commands: Open ExampleMVVM.xcodeproj in Xcode 11+, select ExampleMVVM target, choose a simulator (iPhone 11+), press ▶ Run. App launches to MoviesQueryListView (SwiftUI or UIKit, configurable). No local env setup needed; network calls hit live API via APIEndpoints.swift endpoints.

🗺️Map of the codebase

  • ExampleMVVM/Application/DIContainer/AppDIContainer.swift — Root dependency injection container that orchestrates all layer instantiation; every new feature requires registration here
  • ExampleMVVM/Application/AppFlowCoordinator.swift — App-level flow coordinator that manages navigation between scenes; controls app lifecycle and screen transitions
  • ExampleMVVM/Domain/Interfaces/Repositories/MoviesRepository.swift — Core domain interface that defines the contract between presentation/data layers; all movie data access must conform to this
  • ExampleMVVM/Data/Repositories/DefaultMoviesRepository.swift — Repository implementation combining network and persistence; demonstrates data layer pattern for caching and API coordination
  • ExampleMVVM/Infrastructure/Network/DataTransferService.swift — Abstraction layer for all network operations; handles serialization, error mapping, and protocol-level concerns
  • ExampleMVVM/Presentation/MoviesScene/Flows/MoviesSearchFlowCoordinator.swift — Scene-specific flow coordinator managing movie search navigation; demonstrates MVVM+Coordinator pattern for modular features
  • ExampleMVVM/Application/DIContainer/MoviesSceneDIContainer.swift — Scene-scoped DI container showing how to isolate dependencies per feature; template for adding new scenes

🛠️How to make changes

Add a New API Endpoint and Use Case

  1. Create domain entity in Domain/Entities/ (ExampleMVVM/Domain/Entities/Movie.swift)
  2. Define repository interface in Domain/Interfaces/Repositories/ (ExampleMVVM/Domain/Interfaces/Repositories/MoviesRepository.swift)
  3. Create use case in Domain/UseCases/ with injectable repository dependency (ExampleMVVM/Domain/UseCases/SearchMoviesUseCase.swift)
  4. Add endpoint definition to Data/Network/APIEndpoints.swift (ExampleMVVM/Data/Network/APIEndpoints.swift)
  5. Create DTO and mapping in Data/Network/DataMapping/ (ExampleMVVM/Data/Network/DataMapping/MoviesResponseDTO+Mapping.swift)
  6. Implement repository in Data/Repositories/ using DataTransferService (ExampleMVVM/Data/Repositories/DefaultMoviesRepository.swift)
  7. Register in MoviesSceneDIContainer or AppDIContainer depending on scope (ExampleMVVM/Application/DIContainer/MoviesSceneDIContainer.swift)

Create a New Screen with MVVM

  1. Create ViewModel in Presentation/MoviesScene/[ScreenName]/ViewModel/ (ExampleMVVM/Presentation/MoviesScene/MoviesList/ViewModel/MoviesListViewModel.swift)
  2. Create UIViewController in Presentation/MoviesScene/[ScreenName]/View/ and bind ViewModel outputs (ExampleMVVM/Presentation/MoviesScene/MoviesList/View/MoviesListViewController.swift)
  3. Create storyboard in Presentation/MoviesScene/[ScreenName]/View/ (ExampleMVVM/Presentation/MoviesScene/MoviesList/View/MoviesListViewController.storyboard)
  4. Register screen in MoviesSearchFlowCoordinator for navigation (ExampleMVVM/Presentation/MoviesScene/Flows/MoviesSearchFlowCoordinator.swift)
  5. Add ViewModel and ViewController instantiation to MoviesSceneDIContainer (ExampleMVVM/Application/DIContainer/MoviesSceneDIContainer.swift)

Add Persistence Storage for a New Entity

  1. Update CoreDataStorage.xcdatamodeld model with new entity (ExampleMVVM/Data/PersistentStorages/CoreDataStorage/CoreDataStorage.xcdatamodeld/CoreDataStorage.xcdatamodel/contents)
  2. Create entity mapping file in Data/PersistentStorages/[EntityName]Storage/CoreDataStorage/EntityMapping/ (ExampleMVVM/Data/PersistentStorages/MoviesQueriesStorage/CoreDataStorage/EntityMapping/MovieQueryEntity+Mapping.swift)
  3. Implement storage protocol in Data/PersistentStorages/[EntityName]Storage/ (ExampleMVVM/Data/PersistentStorages/MoviesQueriesStorage/MoviesQueriesStorage.swift)
  4. Implement CoreData storage in Data/PersistentStorages/[EntityName]Storage/CoreDataStorage/ (ExampleMVVM/Data/PersistentStorages/MoviesQueriesStorage/CoreDataStorage/CoreDataMoviesQueriesStorage.swift)
  5. Register storage in AppDIContainer as singleton (ExampleMVVM/Application/DIContainer/AppDIContainer.swift)

Implement Caching Strategy for API Response

  1. Create response storage interface in Data/PersistentStorages/ (ExampleMVVM/Data/PersistentStorages/MoviesResponseStorage/MoviesResponseStorage.swift)
  2. Implement CoreData response storage with entity mapping (ExampleMVVM/Data/PersistentStorages/MoviesResponseStorage/CoreDataMoviesResponseStorage.swift)
  3. Update DefaultRepository to check cache before network call (ExampleMVVM/Data/Repositories/DefaultMoviesRepository.swift)
  4. Inject storage into repository through DIContainer (ExampleMVVM/Application/DIContainer/AppDIContainer.swift)

🪤Traps & gotchas

No hidden package manager setup: all dependencies are system frameworks (UIKit, SwiftUI, CoreData, Foundation URLSession); no Podfile or Package.swift, so first-time contributors may assume missing dependency management is an error. Dual CoreData models: CoreDataStorage.xcdatamodeld has both '.xcdatamodel' and '2.xcdatamodel'—.xccurrentversion points to the active one; forgetting to update .xccurrentversion when adding entities causes silent data migration failures. Manual DI wiring: no code generation for DIContainer; adding a new repository requires editing AppDIContainer.swift and MoviesSceneDIContainer.swift simultaneously or the new service won't be injectable. Observable threading: Custom Observable in ExampleMVVM/Presentation/Common/Observable.swift does not enforce main-thread dispatch by default; ViewModels must manually call DispatchQueue.main.async when updating observable state, or UIKit/SwiftUI updates may crash.

🏗️Architecture

💡Concepts to learn

  • Repository Pattern — This repo's core architectural pattern: DefaultMoviesRepository abstracts data sources (API, CoreData) behind a single interface, making the app testable and allowing swappable persistence without touching business logic.
  • Data Transfer Object (DTO) — Decouples network Codable structs (MoviesResponseDTO) from domain entities; critical for maintaining layer independence and handling API evolution without breaking domain logic.
  • Dependency Injection — AppDIContainer manually wires dependencies; understanding DI is essential to modify the codebase because adding new repositories or services requires registration in the container.
  • Flow Coordinator / Router Pattern — MoviesSearchFlowCoordinator centralizes navigation decisions; separating routing from ViewControllers prevents tight coupling and makes navigation testable in MVVM architectures.
  • Observable Pattern / Reactive Data Binding — Custom Observable in this repo enables ViewModel→View binding without RxSwift; understanding property observers and generics in Swift is required to extend or debug the binding mechanism.
  • Cache-Aside Pattern — DefaultMoviesRepository checks CoreData cache before network fetch; this is a fundamental database optimization pattern shown concretely in this codebase's Data layer.
  • Use Case / Interactor — Domain layer Use Cases (SearchMoviesUseCase) encapsulate application business rules; this pattern keeps domain logic testable and framework-independent, core to Clean Architecture.
  • raywenderlich/swift-algorithm-club — While algorithm-focused, it shares the same philosophy of educational, well-structured code as this Clean Architecture template; useful for understanding design patterns in larger context.
  • ashleymills/Reachability.swift — Standalone network reachability library; commonly integrated into projects using this architecture for offline-mode support in the Data layer.
  • pointfreeco/swift-composable-architecture — Modern alternative to MVVM + manual Observable using TCA (The Composable Architecture); if learning about state management patterns beyond MVVM, this is the next step.
  • ReactiveX/RxSwift — Production replacement for the custom Observable pattern in this repo; teams scaling beyond template should evaluate RxSwift for more robust reactive bindings.
  • SwiftyJSON/SwiftyJSON — Simplifies JSON parsing compared to Codable DTO mapping shown here; alternative approach to the DataMapping layer pattern used in this codebase.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for DefaultMoviesRepository and DefaultMoviesQueriesRepository

The Data/Repositories layer has no visible test files. These repositories are critical for data flow and caching logic. Testing them would validate the repository pattern implementation, DTO mapping correctness, and cache hit/miss scenarios. This is especially important given the caching strategy mentioned in the repo description.

  • [ ] Create ExampleMVVMTests/Data/Repositories/DefaultMoviesRepositoryTests.swift
  • [ ] Create ExampleMVVMTests/Data/Repositories/DefaultMoviesQueriesRepositoryTests.swift
  • [ ] Mock MoviesResponseStorage and MoviesQueriesStorage dependencies
  • [ ] Test cache behavior: verify cached responses are returned and network calls are avoided
  • [ ] Test DTO mapping via MoviesResponseDTO+Mapping.swift by verifying domain entity conversion
  • [ ] Test error handling for network failures with fallback to cache

Add integration tests for DIContainer and dependency injection setup

The repo prominently features DIContainer (AppDIContainer.swift and MoviesSceneDIContainer.swift) but no tests validate the container configuration. A misconfigured container is a silent failure that breaks the app at runtime. Tests should verify that all dependencies resolve correctly and that the object graph is wired properly.

  • [ ] Create ExampleMVVMTests/Application/DIContainer/AppDIContainerTests.swift
  • [ ] Create ExampleMVVMTests/Application/DIContainer/MoviesSceneDIContainerTests.swift
  • [ ] Test that MoviesRepository, MoviesQueriesRepository, and PosterImagesRepository resolve without nil
  • [ ] Test that ViewModels can be instantiated through the container with all transitive dependencies
  • [ ] Verify singletons vs. factory patterns are honored (e.g., caches should be singletons)
  • [ ] Test AppFlowCoordinator initialization and SceneDIContainer lifecycle

Add unit tests for CoreDataStorage and entity mapping for persistence layer

The Data/PersistentStorages layer contains CoreData implementations (CoreDataStorage.swift, CoreDataMoviesResponseStorage.swift) and entity mappings (MoviesResponseEntity+Mapping.swift, MovieQueryEntity+Mapping.swift) but lacks test coverage. These tests are critical because CoreData bugs often surface only during actual storage/retrieval scenarios and entity mapping errors corrupt domain entities.

  • [ ] Create ExampleMVVMTests/Data/PersistentStorages/CoreDataStorageTests.swift with in-memory test store
  • [ ] Create ExampleMVVMTests/Data/PersistentStorages/MoviesResponseEntity+MappingTests.swift
  • [ ] Create ExampleMVVMTests/Data/PersistentStorages/MovieQueryEntity+MappingTests.swift
  • [ ] Test save and fetch operations: verify data persists and is retrieved correctly
  • [ ] Test entity-to-domain mapping: validate MoviesResponseEntity maps to Movie domain entity without data loss
  • [ ] Test edge cases: null values, large datasets, concurrent read/write scenarios
  • [ ] Use NSPersistentContainer with type=NSInMemoryStoreType for fast, isolated tests

🌿Good first issues

  • Add unit tests for ExampleMVVM/Data/Network/DataMapping/MoviesRequestDTO+Mapping.swift and MoviesResponseDTO+Mapping.swift; currently test coverage is incomplete for DTO serialization/deserialization edge cases (null fields, malformed dates).
  • Extend ExampleMVVM/Presentation/Common/Observable.swift to support Combine integration (ObservableObjectAdapter or EnvironmentObject bridge) for seamless SwiftUI adoption across all ViewModels, not just MoviesQueryListViewModel.
  • Create reusable DataSource/Delegate implementations in ExampleMVVM/Presentation/MoviesScene/ for UITableViewController pagination; current example embeds pagination logic in ViewController, violating single-responsibility principle.
  • Document DIContainer dependency resolution flow with inline comments in AppDIContainer.swift explaining why each factory method exists and which layers depend on it; new contributors currently must trace instantiation manually.
  • Add MockMovieRepository and MockNetworkService implementations for test targets to enable ViewModel unit tests without network mocking boilerplate (currently tests likely mock at network layer, not repository layer).

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 7e1d515 — Remove empty lines (oooleh)
  • eaf3b26 — Fix warning (Oleh Kudinov)
  • b22fb1f — Fix tests (Oleh Kudinov)
  • 7880b4e — Merge pull request #30 from Jeon0976/master (kudoleh)
  • 05c3e48 — Update Endpoint.swift (Jeon0976)
  • 70b6070 — Update Endpoint.swift (Jeon0976)
  • e7e7125 — Refector for transition from BodyEncoding enum to BodyEncoder protocol (Jeon0976)
  • 324e004 — Merge pull request #29 from ictechgy/master (kudoleh)
  • 2cfa54e — fix typo (ictechgy)
  • 821cb40 — Merge pull request #28 from Kim-Junhwan/refactor/Remove_Unused_Properties (kudoleh)

🔒Security observations

  • High · Missing API Key Management — ExampleMVVM/Application/AppConfigurations.swift. The AppConfigurations.swift file likely contains hardcoded API endpoints and keys without proper secret management. No evidence of environment-based configuration or secure credential storage (Keychain, secured config files) was found in the file structure. Fix: Implement secure credential management using iOS Keychain or environment-based configuration. Never hardcode API keys in source code. Use configuration files that are excluded from version control (.gitignore should exclude sensitive config).
  • High · Insufficient Input Validation in Data Mapping — ExampleMVVM/Data/Network/DataMapping/. The Data/Network/DataMapping layer performs DTO mapping without visible validation. MoviesResponseDTO+Mapping.swift and MoviesRequestDTO+Mapping.swift may be susceptible to malformed data injection or type confusion attacks if not properly validating API responses. Fix: Implement comprehensive input validation for all network responses. Validate data types, ranges, and formats before mapping to domain entities. Use Codable's error handling to catch malformed JSON responses.
  • Medium · Potential SQL Injection in Core Data Storage — ExampleMVVM/Data/PersistentStorages/CoreDataStorage/CoreDataStorage.swift. Core Data storage implementations (CoreDataStorage.swift, CoreDataMoviesQueriesStorage.swift) may be vulnerable to injection attacks if queries are constructed dynamically. While Core Data uses parameterized queries by default, custom NSPredicate constructions with string interpolation could introduce vulnerabilities. Fix: Always use NSPredicate with proper parameter binding rather than string interpolation. Ensure all user input is properly escaped and parameterized in NSFetchRequest predicates.
  • Medium · Missing HTTPS Certificate Pinning — ExampleMVVM/Infrastructure/Network/NetworkService.swift, DataTransferService.swift. The NetworkService.swift and DataTransferService.swift lack evidence of certificate pinning for API communications. This makes the app vulnerable to man-in-the-middle (MITM) attacks, especially when connecting to untrusted networks. Fix: Implement SSL/TLS certificate pinning using URLSessionDelegate or third-party libraries like TrustKit. Validate server certificates against a pinned set of certificates in the app bundle.
  • Medium · Unencrypted Local Data Storage — ExampleMVVM/Data/PersistentStorages/MoviesQueriesStorage/UserDefaultsStorage/UserDefaultsMoviesQueriesStorage.swift. User search queries are stored in both UserDefaults and Core Data (MoviesQueriesStorage layer) without encryption. UserDefaults data is stored in plaintext and can be accessed by other apps on a jailbroken device or through backup exploitation. Fix: Use Keychain for sensitive data storage instead of UserDefaults. For Core Data, implement file-level encryption or use Core Data with NSPersistentStore encryption options.
  • Medium · No App Transport Security (ATS) Configuration Visible — ExampleMVVM/Info.plist (not provided). Info.plist configuration for App Transport Security is not visible in the provided file structure. The app may allow insecure connections or have overly permissive ATS settings. Fix: Configure Info.plist to enforce HTTPS-only connections. Set NSAllowsArbitraryLoads to false and only whitelist necessary insecure domains if absolutely required (not recommended).
  • Low · Missing Xcode User Data in .gitignore — .gitignore, ExampleMVVM.xcodeproj/xcuserdata/. The .gitignore file may not properly exclude sensitive Xcode user data. Directories like xcuserdata/ and Breakpoints files are visible in the structure, indicating they may be tracked in version control. Fix: Ensure .gitignore includes standard Xcode files: *.xcuserdata, *.xcworkspace/xcuserdata, Breakpoints_v2.xcbkptlist, xcschememanagement.plist.
  • Low · No Visible Security Headers in Network Layer — undefined. The NetworkConfig.swift and DataTransferService.swift files do not show implementation of security headers like Content-Security-Policy, X-Frame Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.