6.7 KiB
AI Implementation Context
This file summarizes project-specific context, architecture, and conventions to speed up future AI work.
Project Summary
BusinessCard is a SwiftUI app for building and sharing digital business cards with QR codes. It includes iOS screens for cards, sharing, customization, contact tracking, and widget previews, plus a watchOS companion to show a default card QR code.
Key Constraints
- iOS 26+, watchOS 12+, Swift 6.2.
- SwiftUI with
@Observableclasses and@MainActor. - Protocol‑oriented architecture is prioritized.
- Clean Architecture with separation of concerns.
- One public type per file, keep files under 300 lines.
- No UIKit unless explicitly requested.
- String Catalogs only (
.xcstrings). - No magic numbers in views; use Bedrock's
Designconstants. - Uses Bedrock package for shared design system and utilities.
Core Data Flow
AppStateowns:CardStore(cards and selection)ContactsStore(contact list + search)ShareLinkService(share URLs)
- SwiftData with CloudKit for persistence and sync.
- App Groups for iOS-Watch data sharing.
- Views read state via environment and render UI only.
Dependencies
Bedrock Package
Located at /Frameworks/Bedrock (local package). Provides:
Design.Spacing,Design.CornerRadius,Design.Opacity, etc.QRCodeGeneratorandQRCodeImageViewfor QR codes- Reusable settings components
App-specific extensions are in Design/DesignConstants.swift:
Design.CardSize- card dimensions, avatar, QR sizesDesign.Shadow.offsetNone- zero offset extensionColor.AppBackground,Color.CardPalette,Color.AppAccent,Color.AppText
Important Files
Models
-
Models/BusinessCard.swift— SwiftData model with:- Basic fields: name, role, company, email, phone, website, location
- Rich fields: pronouns, bio, social links (LinkedIn, Twitter, Instagram, etc.)
- Custom links: 2 slots for custom URLs
- Photo:
photoDatastored with@Attribute(.externalStorage) - Computed:
theme,layoutStyle,vCardPayload,hasSocialLinks
-
Models/Contact.swift— SwiftData model with:- Basic fields: name, role, company
- Annotations: notes, tags (comma-separated), followUpDate, whereYouMet
- Received cards: isReceivedCard, email, phone
- Photo:
photoData - Computed:
tagList,hasFollowUp,isFollowUpOverdue - Static:
fromVCard(_:)parser
-
Models/CardTheme.swift— card theme palette -
Models/CardLayoutStyle.swift— stacked/split/photo -
Models/AppTab.swift— tab bar enum
Protocols (POP)
Protocols/BusinessCardProviding.swift— card selection interfaceProtocols/ContactTracking.swift— contact management interfaceProtocols/ShareLinkProviding.swift— share URL generation interface
State
State/AppState.swift— central state containerState/CardStore.swift— card CRUD, selection, watch syncState/ContactsStore.swift— contacts, search, received cards
Services
Services/ShareLinkService.swift— share URL helpersServices/WatchSyncService.swift— App Group sync to watch
Views
Main screens:
Views/RootTabView.swift— tabbed shellViews/CardsHomeView.swift— hero + card carouselViews/ShareCardView.swift— QR + share actions + track shareViews/CustomizeCardView.swift— theme/layout controlsViews/ContactsView.swift— contact list with sectionsViews/WidgetsView.swift— widget preview mockups
Feature views:
Views/BusinessCardView.swift— card display with layoutsViews/CardEditorView.swift— create/edit cards with PhotosPickerViews/ContactDetailView.swift— full contact view with annotationsViews/QRScannerView.swift— camera-based QR scannerViews/QRCodeView.swift— QR code image generator
Reusable components (in Views/Components/):
AvatarBadgeView.swift— circular avatar with photo or iconIconRowView.swift— icon + text row for detailsLabelBadgeView.swift— small badge labelsActionRowView.swift— generic action row with chevron
Sheets (in Views/Sheets/):
RecordContactSheet.swift— track share recipient
Small utilities:
Views/EmptyStateView.swift— empty state placeholderViews/PrimaryActionButton.swift— styled action buttonViews/HeroBannerView.swift— home page bannerViews/CardCarouselView.swift— card scroll carouselViews/WidgetsCalloutView.swift— widget promotion callout
Design + Localization
Design/DesignConstants.swift— extends BedrockResources/Localizable.xcstrings— string catalogLocalization/String+Localization.swift— string helpers
watchOS
BusinessCardWatch/BusinessCardWatchApp.swiftBusinessCardWatch/Views/WatchContentView.swiftBusinessCardWatch/State/WatchCardStore.swiftBusinessCardWatch/Models/WatchCard.swiftBusinessCardWatch/Resources/Localizable.xcstrings
File Guidelines
Size Limits
- Main views: aim for under 300 lines
- Extract reusable sub-views to
Components/ - Extract sheets/modals to
Sheets/ - Private structs in same file OK if under 50 lines
Current File Sizes
| File | Lines | Status |
|---|---|---|
| CardEditorView | ~420 | Complex form, acceptable |
| QRScannerView | ~310 | Camera + parsing, acceptable |
| BusinessCardView | ~245 | Multiple layouts, acceptable |
| ShareCardView | ~235 | Good |
| ContactDetailView | ~235 | Good |
| ContactsView | ~220 | Good |
| CustomizeCardView | ~170 | Good |
| All others | <110 | Good |
Localization
- All user-facing strings are in
.xcstrings. - Supported locales: en, es‑MX, fr‑CA.
- Use
String.localized("Key")for non-Text strings.
Testing
BusinessCardTests/BusinessCardTests.swiftcovers:- vCard payload formatting
- Card CRUD operations
- Contact search and filtering
- Social links detection
- Contact notes/tags
- Follow-up status
- vCard parsing for received cards
Known Stubs / TODOs
- Apple Wallet and NFC flows are alert-only placeholders.
- Share URLs are sample placeholders.
- Widget previews are not WidgetKit extensions.
- See
ROADMAP.mdfor full feature status.
If You Extend The App
- Add new strings to the String Catalogs.
- Use
Design.*from Bedrock for spacing, opacity, etc. - Add app-specific constants to
DesignConstants.swift. - Keep view logic UI-only; push business logic to state classes.
- Prefer protocols for new capabilities.
- Add unit tests for new model logic.
- Update
ROADMAP.mdwhen adding features. - Keep files under 300 lines — extract components when needed.
- No duplicate code — check for existing components first.
- One public type per file — private helpers OK if small.