Go to file
2026-02-11 12:38:17 -06:00
_design/screenshots Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-08 19:41:24 -06:00
BusinessCard Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-11 12:38:17 -06:00
BusinessCard.xcodeproj Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-11 08:25:22 -06:00
BusinessCardClip Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-10 22:01:50 -06:00
BusinessCardTests Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-11 10:49:00 -06:00
BusinessCardUITests Initial Commit 2026-01-08 15:54:49 -06:00
BusinessCardWatch Watch App Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-10 15:10:19 -06:00
.gitignore Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-11 10:49:00 -06:00
Agents.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-10 20:46:16 -06:00
ai_implementation.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-10 15:10:19 -06:00
APP_STORE_CONNECT.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-10 19:53:38 -06:00
APPCLIP-DEPLOYMENT.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-10 16:11:58 -06:00
CLOUDKIT_SCHEMA_GUARDRAILS.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-10 20:46:16 -06:00
DevAccount-Migration.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-10 15:10:19 -06:00
OPUS-Plan-AppClip.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-10 14:58:06 -06:00
README.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-10 20:46:16 -06:00
ROADMAP.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-01-10 14:24:06 -06:00
Website_AppClip_Plan.md Signed-off-by: Matt Bruce <mbrucedogs@gmail.com> 2026-02-10 19:53:38 -06:00

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.

CloudKit Schema Safety

Before changing any shipped SwiftData model schema, follow CLOUDKIT_SCHEMA_GUARDRAILS.md. This is the project checklist for safe additive changes and migration-friendly patterns.

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
  • Centralized preferences: AppPreferencesStore is the single source of truth for app-level settings (theme/debug flags)
  • Protocol-oriented: Interfaces for services and stores
  • Protocol-based providers: AppMetadataProviding and VCardPayloadProviding keep services/state decoupled
  • 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 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.

Settings Layout Contract

SettingsCard is the single owner of horizontal row inset in SettingsView.

  • Use SettingsCardRow for custom in-card rows (HStack, status/info rows, custom content).
  • Use SettingsDivider between in-card rows (instead of Divider/manual lines).
  • Use SettingsNavigationRow(..., backgroundColor: .clear) for standard in-card navigation rows.
  • Avoid child .padding(.horizontal, ...) inside SettingsCard unless intentional indentation is required.

Project Structure

BusinessCard/
├── Assets.xcassets/
│   └── SocialSymbols/   # Custom brand icons (LinkedIn, X, Instagram, etc.)
├── Configuration/       # App identifiers and configuration
│   ├── Base.xcconfig         # Source of truth for all identifiers
│   ├── Debug.xcconfig        # Debug configuration (imports Base)
│   ├── Release.xcconfig      # Release configuration (imports Base)
│   └── AppIdentifiers.swift  # Swift interface to configuration
├── 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.)
    ├── Widgets/         # Widgets feature view + feature-specific components
    └── [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

App Identifiers (xcconfig)

All company-specific identifiers are centralized in Configuration/Base.xcconfig:

COMPANY_IDENTIFIER = com.mbrucedogs
DEVELOPMENT_TEAM = 6R7KLBPBLZ

This flows through:

  • Build settings: Bundle IDs, Team ID (via xcconfig → project)
  • Entitlements: CloudKit container, App Group (via variable substitution)
  • Swift code: AppIdentifiers.* (via Info.plist → Bundle.main)

To migrate to a new developer account: Update Base.xcconfig only. See DevAccount-Migration.md.

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 for planned features and implementation status.


Built with SwiftUI, SwiftData, and ❤️