BusinessCard/README.md

237 lines
9.9 KiB
Markdown

# BusinessCard
A SwiftUI iOS + watchOS app that creates and shares digital business cards with QR codes, quick share actions, customization, and contact tracking. Data syncs across devices via iCloud.
## Platforms
- iOS 26+
- watchOS 12+
- Swift 6.2
## Features
### My Cards
- **Full-screen card display**: Swipe between your business cards in a full-screen view
- Tap the **edit icon** (pencil) in the top right to edit the current card
- Tap the **plus icon** to create a new card
- Set a default card for sharing
- **Modern card design**: Banner with optional cover photo, company logo, overlapping profile photo, clean contact rows
- **Header layout picker**: Choose how profile, cover, and logo images are arranged in the card header
- **Profile Banner**: Profile photo fills the entire banner (great for personal branding)
- **Cover + Avatar**: Cover image as banner with profile photo overlapping at bottom
- **Centered Logo**: Cover image with company logo centered and profile avatar smaller
- **Logo Badge**: Cover with small logo badge in corner, profile avatar overlapping
- **Side by Side**: Avatar and logo displayed together in the content area
- **Smart layout suggestions**: The app suggests the best layout based on which images you've added
- **Live layout preview**: See exactly how each layout looks before selecting in both the picker and editor
- **Profile photos**: Add a headshot from library or camera with crop/zoom editor
- **Cover photos**: Add a custom banner background from library or camera
- **Company logos**: Upload a logo from library or camera
- **3-step photo workflow**: Choose source (library/camera) → crop/position → save
- **Rich profiles**: First/middle/last name, prefix, maiden name, preferred name, pronouns, headline, bio, accreditations
- **Clickable contact fields**: Tap any field to call, email, open link, or launch app
### Share
- **Floating share button**: Centered above the tab bar for quick access
- **Dark-themed share sheet**: Sleek QR code display with prominent sharing options
- Share options: copy link, SMS, email, WhatsApp, LinkedIn, and more
- **Offline sharing toggle**: Share your card without internet connection
- **Track shares**: Record who received your card and when
- Button is hidden when no cards exist
- Placeholder actions for Apple Wallet and NFC (alerts included)
### Card Editor
Access via the edit (pencil) icon in the My Cards tab:
- **Horizontal color picker**: Scrollable theme swatches for quick selection
- Theme picker with multiple color palettes (Coral, Midnight, Ocean, Lime, Violet)
- **Expandable name section**: Prefix, first, middle, last, maiden name, suffix, preferred name, pronouns
- **Edit all card details**: Name, role, department, company, headline, bio
- **Accreditations**: Tag-based input with inline editing
#### Dynamic Contact Fields
Add unlimited contact fields of any type, reorder by drag-and-drop:
- **Contact**: Email, phone, website, address
- **Social Media**: LinkedIn, X/Twitter, Instagram, Facebook, TikTok, Threads, Bluesky, Mastodon, Reddit, Twitch, YouTube, Snapchat, Pinterest
- **Developer**: GitHub, GitLab, Stack Overflow, CodePen
- **Messaging**: Telegram, WhatsApp, Discord, Slack, Matrix, Signal
- **Support & Funding**: Patreon, Ko-fi, Buy Me a Coffee, GitHub Sponsors
- **Payment**: Venmo, Cash App, PayPal, Zelle
- **Scheduling**: Calendly
- **Other**: Custom links with any URL
Each field has:
- **Custom icons**: Brand-colored icons from asset catalog (not generic SF Symbols)
- **Title/Label**: Add context like "Work", "Personal", or custom call-to-action
- **Deep linking**: Opens native apps when available (X, Instagram, etc.)
- **Drag-to-reorder**: Long press and drag to change order
- **Suggestion chips**: Quick-fill suggestions for field titles
- **Live preview**: "Preview card" button to see changes before saving
- **Delete cards** you no longer need
### Contacts
- **Add contacts manually**: Tap + to create contacts with name, role, company, email, phone
- **Profile photos**: Add or edit a photo for each contact
- Track who you've shared your card with
- **Scan QR codes** to save someone else's business card
- **Notes & annotations**: Add notes about each contact
- **Tags**: Organize contacts with comma-separated tags
- **Follow-up reminders**: Set reminder dates with overdue indicators
- **Where you met**: Record event or location where you connected
- Search contacts using localized matching (searches name, company, role, tags, notes)
- Shows last shared time and the card label used
- Swipe to delete contacts
### Widgets (Preview Only)
- Phone widget preview mock
- Watch widget preview mock
### watchOS App
- Shows the **default card QR code** full-screen (no card picker)
- Default card is determined by the iPhone app
- **Syncs with iPhone** via WatchConnectivity framework
- QR codes are pre-generated on iPhone (CoreImage not available on watchOS)
## Data Sync
### iCloud Sync (iOS)
Cards and contacts are stored using SwiftData with CloudKit sync enabled. Your data automatically syncs across all your iPhones and iPads signed into the same iCloud account.
### iPhone to Watch Sync
The iPhone app syncs card data to the paired Apple Watch via WatchConnectivity framework using `updateApplicationContext`. When you create, edit, or delete cards on your iPhone, the changes are pushed to your watch automatically.
**Note**: The watch receives data from the iPhone. To update cards on the watch, make changes on the iPhone first. QR codes are pre-generated on iPhone since CoreImage is not available on watchOS.
**IMPORTANT**: Do NOT use App Groups for iPhone-Watch communication. App Groups only work between an app and its extensions on the SAME device. iPhone and Apple Watch are separate devices with separate file systems.
## Architecture
- **Clean Architecture**: Clear separation between Views, State, Services, and Models
- **Views are dumb**: Presentation only, no business logic
- **State is smart**: `@Observable` classes with all business logic
- **Protocol-oriented**: Interfaces for services and stores
- **SwiftData + CloudKit**: Persistent storage with iCloud sync
- **WatchConnectivity**: iPhone to Apple Watch sync (NOT App Groups)
- **One type per file**: Lean, maintainable files under 300 lines
- **Reusable components**: Shared UI in `Views/Components/`
- **Bedrock package**: Shared design system and utilities
- **String Catalogs**: Localization for en, es-MX, fr-CA
- **Single source of truth for names**: `BusinessCard.fullName` is computed from individual name fields (no stored displayName)
## Dependencies
### Bedrock (Local Package)
The app uses the [Bedrock](ssh://git@192.168.1.128:220/mbrucedogs/Bedrock.git) package for:
- **Design constants**: `Design.Spacing`, `Design.CornerRadius`, `Design.Opacity`, etc.
- **QR code generation**: `QRCodeGenerator`, `QRCodeImageView`
- **Reusable UI components**: Settings views, badges, effects
App-specific extensions are in `Design/DesignConstants.swift`.
## Project Structure
```
BusinessCard/
├── Assets.xcassets/
│ └── SocialSymbols/ # Custom brand icons (LinkedIn, X, Instagram, etc.)
├── Design/ # Design constants (extends Bedrock)
├── Localization/ # String helpers
├── Models/
│ ├── BusinessCard.swift # Main card model
│ ├── CardHeaderLayout.swift # Header layout options (profile banner, cover+avatar, etc.)
│ ├── Contact.swift # Received contacts
│ ├── ContactField.swift # Dynamic contact fields (SwiftData)
│ └── ContactFieldType.swift # Field type definitions with icons & URLs
├── Protocols/ # Protocol definitions
├── Resources/ # String Catalogs (.xcstrings)
├── Services/ # ShareLinkService, VCardFileService, WatchConnectivityService
├── State/ # Observable stores (CardStore, ContactsStore)
└── Views/
├── Components/ # Reusable UI (ContactFieldPickerView, HeaderLayoutPickerView, etc.)
├── Sheets/ # Modal sheets (ContactFieldEditorSheet, RecordContactSheet, etc.)
└── [Feature].swift # Feature screens
BusinessCardWatch Watch App/ # watchOS app target (WatchConnectivity sync)
BusinessCardTests/ # Unit tests
```
## Configuration
### Required Capabilities
**iOS Target:**
- iCloud (CloudKit enabled)
- App Groups (`group.com.mbrucedogs.BusinessCard`) - for future widget access
- Background Modes (Remote notifications)
- Camera (for QR code scanning)
**watchOS Target:**
- WatchConnectivity (for receiving cards from iPhone)
- Bundle ID must be prefixed with iOS bundle ID (e.g., `com.mbrucedogs.BusinessCard.watchkitapp`)
### Watch App Embedding (CRITICAL)
The watch app must be embedded in the iOS app for deployment. In the iOS target's **Build Phases**:
1. **"Embed Watch Content"** phase must exist
2. **"Code Sign On Copy"** must be CHECKED ✓
Without this, the iOS app installs but the watch app does NOT install on the paired Apple Watch. See `Agents.md` for full troubleshooting guide.
### CloudKit Container
`iCloud.com.mbrucedogs.BusinessCard`
## Notes
- Share URLs are sample placeholders
- Wallet/NFC flows are stubs with alerts only
- Widget UI is a visual preview (not a WidgetKit extension)
## Running
1. Open `BusinessCard.xcodeproj` in Xcode
2. Ensure Bedrock package is resolved (File → Packages → Resolve Package Versions)
3. Build and run on iOS Simulator or device
## Tests
Unit tests cover:
- vCard payload formatting
- Default card selection
- Contact search filtering
- Create, update, delete cards
- Contact tracking (new and existing contacts)
- Theme and layout assignment
- Social links detection
- Contact notes and tags
- Follow-up status and overdue detection
- vCard parsing for received cards
- Adding received cards via QR scan
Run tests with `Cmd+U` in Xcode.
## Roadmap
See [ROADMAP.md](ROADMAP.md) for planned features and implementation status.
---
*Built with SwiftUI, SwiftData, and ❤️*