agentleFS
moasqmoasq/ios-dev-agent/.cursor/rules/forbidden-patterns.mdc

ios-dev-agent / rules

Cursor rule4 starsChanged 6 months agoMITView on GitHub

iOS development rule

The file

Show its rules and text

We split this forbidden-patterns.mdc into the rules it gives an agent

16 rules. About 0 are common, 11 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈11

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    No Storyboards, no XIBs, no Interface Builder

    line 17
  2. Distinctive:

    Use SPM (Swift Package Manager) as the only package manager.

    line 22
  3. Distinctive:

    Add an SPM package when any of these apply:

    line 26
  4. Very specific:

    Use native Apple frameworks when they cover the need well enough.

    line 31
  5. Distinctive:

    Search the internet for the package.

    line 35
  6. Distinctive:

    Read the README to learn the correct import name and SwiftUI usage.

    line 40
  7. Very specific:

    After validation, use the add_package MCP tool to add it to the Xcode project.

    line 42
  8. Distinctive:

    Use SwiftData instead of CoreData

    line 60
  9. Distinctive:

    No CloudKit, no iCloud sync

    line 66
  10. Distinctive:

    No third-party cloud SDK unless the user explicitly asks and credentials/configuration already exist.

    line 68
  11. Distinctive:

    Never invent API keys, endpoints, or cloud configuration.

    line 70
  12. Very specific:

    NEVER: use hardcoded colors in views: .white, .black, Color.red, Color.blue, .orange, or .opacity() on raw colors

    line 74
  13. Very specific:

    NEVER: use hardcoded fonts in views: .font(.system(size:)), .font(.title2), .font(.headline), etc.

    line 75
  14. Very specific:

    NEVER: use hardcoded spacing: .padding(20), VStack(spacing: 10), etc.

    line 76
  15. Distinctive:

    If a needed token doesn't exist in AppTheme, add it to AppTheme first, then reference it

    line 82
  16. Distinctive:

    Import the module or file that defines the type

    line 105

≈ “Common” is an estimate: at least 1 in 5 of the 6,668 Cursor rule files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
forbidden-patterns.mdc
---
description: iOS development rule
globs: "**/*.swift"
alwaysApply: true
---

# Forbidden Patterns

## Networking — Project-Scoped
Generated app code should be offline-first by default. Do not add arbitrary REST clients, analytics SDKs, or cloud calls unless the project explicitly requires and configures them. RevenueCat, StoreKit, WeatherKit, HealthKit, and Apple platform services are allowed when the relevant skill/configuration is in use.

## UIKit — AVOID BY DEFAULT
**Why:** SwiftUI-first ensures cross-platform consistency.
- Prefer SwiftUI-first architecture
- `UIKit` imports are allowed only when a required feature has no viable SwiftUI equivalent
- `UIViewRepresentable` / `UIViewControllerRepresentable` are allowed only as minimal bridges for those required UIKit features
- No Storyboards, no XIBs, no Interface Builder

## Third-Party Packages — SPM Only, Validated Before Use
**Why:** Dependencies add build complexity and supply chain risk. Use Apple frameworks first; add an SPM package only when it provides a meaningfully better experience.

Use SPM (Swift Package Manager) as the only package manager. CocoaPods and Carthage are not allowed.

### When to add an SPM package

Add an SPM package when any of these apply:
- A feature needs capabilities that no Apple framework provides (e.g. playing After Effects / Lottie JSON animations, advanced image processing pipelines, barcode generation beyond Core Image).
- The approved-packages list below explicitly names a package for this project.
- The user's prompt explicitly requests a specific package by name.

Use native Apple frameworks when they cover the need well enough. For example, use Swift Charts instead of a charting library, use `AsyncImage` or PhotosUI instead of an image-loading library, and use `Canvas` / `TimelineView` for simple particle animations.

### How to validate a package before adding it

Search the internet for the package. Then confirm each item:
1. The GitHub repository exists and has more than 500 stars.
2. The repository was updated within the last 12 months.
3. The license is MIT or Apache 2.0.
4. A `Package.swift` file exists in the repository root (confirms SPM support).
5. Read the README to learn the correct import name and SwiftUI usage.

After validation, use the `add_package` MCP tool to add it to the Xcode project. If the tool is unavailable, edit `project.yml` directly (see the SPM Packages section in the build plan for the exact YAML format).

### SPM naming — three names to keep straight

SPM has three different names for the same dependency. Getting them confused is the most common integration error.

| Name | What it is | Example for Lottie |
|---|---|---|
| **Repository name** | Last path component of the Git URL. Used as the XcodeGen `packages:` key and in `- package:` under dependencies. | `lottie-ios` |
| **Package display name** | The `name:` in `Package.swift`. Only for display — SPM resolves by URL, not by this name. | `Lottie` |
| **Product name** | Declared in `products: [.library(name: "…")]` inside `Package.swift`. This is what you write in `import` statements and in the `product:` field in XcodeGen. | `Lottie` |

To find the correct product name, open the repository's `Package.swift` on GitHub and look at the `products:` array.



## CoreData — BANNED
**Why:** SwiftData is Apple's modern replacement.
- Use **SwiftData** instead of CoreData
- No `NSManagedObject`, no `NSPersistentContainer`
- No `.xcdatamodeld` files

## Authentication & Cloud — Setup Required
External services require explicit configuration with API keys and credentials.
- No CloudKit, no iCloud sync
- No push notifications
- No third-party cloud SDK unless the user explicitly asks and credentials/configuration already exist.
- RevenueCat is supported through the `revenuecat` skills and must be configured before SDK calls are added.
- Never invent API keys, endpoints, or cloud configuration.

## Hardcoded Styling — BANNED
**Why:** Centralized tokens ensure consistency, enable theme changes.
- **NEVER** use hardcoded colors in views: `.white`, `.black`, `Color.red`, `Color.blue`, `.orange`, or `.opacity()` on raw colors
- **NEVER** use hardcoded fonts in views: `.font(.system(size:))`, `.font(.title2)`, `.font(.headline)`, etc.
- **NEVER** use hardcoded spacing: `.padding(20)`, `VStack(spacing: 10)`, etc.
- **ALL** colors must come from `AppTheme.Colors.*` tokens
- **ALL** fonts must come from `AppTheme.Fonts.*` tokens
- **ALL** spacing must come from `AppTheme.Spacing.*` tokens
- Text color tokens MUST use UIKit adaptive colors (`Color(.label)`, `Color(.secondaryLabel)`, `Color(.tertiaryLabel)`) — these auto-adapt to appearance mode
- Brand/theme color tokens (primary, secondary, accent, background, surface) use `Color(hex:)` with palette values
- If a needed token doesn't exist in AppTheme, **add it to AppTheme first**, then reference it

```swift
// BANNED — hardcoded styling
.foregroundStyle(.white)
.foregroundStyle(.black)
.foregroundStyle(Color.primary)
.font(.title2)
.font(.system(size: 48))
.padding(20)

// CORRECT — AppTheme tokens (text uses UIKit adaptive, brand uses hex)
.foregroundStyle(AppTheme.Colors.textPrimary)   // Color(.label) — adapts to appearance
.foregroundStyle(AppTheme.Colors.accent)         // Color(hex:) — brand identity
.font(AppTheme.Fonts.title2)
.font(AppTheme.Fonts.largeTitle)
.padding(AppTheme.Spacing.lg)
```

## Type Re-declarations — BANNED
**Why:** Duplicates cause ambiguous type errors.
- **NEVER** re-declare types that exist in other project files
- **NEVER** re-declare types from SwiftUI/Foundation (`Color`, `CGPoint`, `Font`, etc.)
- Import the module or file that defines the type
- Each type must be defined in **exactly one file**

```swift
// BANNED — re-declaring Color enum that SwiftUI already provides
enum Color {
    case red, blue, green
}

// BANNED — re-declaring a model that exists in Models/Note.swift
struct Note {
    var title: String
}

// CORRECT — import and use the existing type
import SwiftUI  // provides Color
// Note is already defined in Models/Note.swift, just reference it
```

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.