Development log
What We've Been Building
A running record of meaningful work on the new SwiftUI app — newest first. For context on why we're rebuilding, read the story.
April 24, 2026
Sharing
Share sheet upgraded from ShareLink to UIActivityViewController — photos and links now travel together in a single share action; iMessage keeps the hero photo as a real attachment and auto-expands the URL into a link preview card beneath it
Share-sheet tile renders branded immediately: LPLinkMetadata preloaded with the title and hero image so the raw URL never flashes during the async metadata fetch
Shimmer cost reduced via a 30fps TimelineView; static ImageSkeleton placeholder introduced for KFImage decode flashes
April 23, 2026
Performance
App launch unblocked: App.init() was synchronously walking the 1+ GB Caches tree (CloudKit trim, storage report, legacy purges, tmp cleanup) before SwiftUI could draw — all of it moved to a detached background task with a single-flight gate so overlapping foreground/background transitions no longer stack walks
Plant Light Visualizer
New Plant Light Visualizer added: ladder gallery view and a home hero card surface it in context; developer dashboard gains an entry point
Tips
Search scopes added so tips can be filtered within a specific category directly from the search bar
NEW pill badge surfaces recently added tips at a glance
Continue-reading rail on the Tips home surface lets users resume where they left off
Active-filter clear-all button added — one tap to reset all applied filters
Picker sort order introduced for controlling tip display sequence
Unified ContentUnavailableView used across all empty-state surfaces in the Tips tab
ShareLink integrated so any tip can be shared as a native iOS share sheet
Featured tips receive a Spotlight ranking boost so they surface in system search
Race-free hero image prefetch — tips no longer flash a placeholder when opening from search or the home rail
Accessibility
CareTip.accessibilityCardLabel applied to every tip card surface — VoiceOver users can navigate the full tips experience in a single swipe per card
Unit Preferences
User temperature (°C/°F) and size unit preferences now synced through ThemeManager — setting your preference once updates the weather strip, detail sheet, advisories, and plant measurements consistently
Community
Founder Unlock Popup shadow removed for a cleaner Apple/Freeform aesthetic
Sharing
BotanicShareLink and ShareService introduced — every Plant, Tip, Garden, and Community detail view now shares a Universal Link (botanicbase.app/…) with a cropped hero image preview via the native iOS share sheet
Siri & Spotlight
TipUserActivity and GardenUserActivity added alongside the existing PlantUserActivity — Siri suggestions, Handoff, and Spotlight indexing now cover all three content types
Parameterized App Intents (OpenPlant, OpenTip, OpenGarden, RandomPlant) with CloudKit-backed AppEntity queries — users can open any record by name from Siri or Shortcuts
Home
"You may also like" rail on Plant Detail surfaces taxonomically similar plants
Random plant toolbar button added to Home with haptic feedback
Recent searches chip strip in Search backed by RecentSearchesTracker — previous queries resurface as tappable chips below the search field
Deep Links
DeepLinkRouter now handles both botanicbase:// custom scheme and https://botanicbase.app Universal Links — Community deep links routed for the first time
Associated Domains entitlement cleaned up to applinks:botanicbase.app only
April 22, 2026
Weather
Added 9 new winter backgrounds: flurries, heavy snow, blizzard, blowing snow, sleet, wintry mix, freezing rain, sun flurries, and night variants
Rain redesigned as gradient teardrops with four intensity presets — light drizzle, moderate, heavy, and downpour — each reading visually distinct
Windy scene replaced with a non-seasonal falling-leaves overlay
Snow gains wind-driven horizontal drift; new sleet overlay for hard pellets
Rain re-tinted to ice-blue so drops catch the sky instead of rendering sterile white
Respects the user's °C/°F and length preferences across the strip, detail sheet, and advisory text
Now uses live device location with reverse geocoding and a city label; reload button refreshes the fix
Plant weather advisories rewritten with natural phrasing — condition-specific, shorter sentences
Local Shops
Refresh button and pull-to-refresh added
What's New
What's New sheet redesigned in an Apple/Freeform style: centered icon, bold title, SF Symbol feature rows, sticky Continue button — notes now ship bundled with the binary via WhatsNew.json instead of pulling from the cloud changelog, so release notes are available immediately on launch
Shown once per app version; silently marks the version as seen on fresh installs and empty-notes builds
Cloud changelog indicator: a green dot appears on the Home avatar and Profile → Changelog row when the cloud feed has new entries since the user last opened it — cleared on markSeen()
Community
Founder Unlock Popup: a one-time celebration overlay fires when founder status is first verified — CloudKit gates the lifetime and a local UserDefaults guard prevents double-fire while the save is in flight
Content policy surfaced in-app as a resizable sheet with a "read more" link
Author profile, BotanicBase author, and staff author pages now share the same tips-by-category layout and filter pills
Haptics
Haptics helper introduced with cached generator singletons — replaces 11 separate inline allocations across tip/plant save, quiz, onboarding, and Plant Matcher so the Taptic Engine stays warm between taps
Sensory feedback added to tip category pill selection, shops refresh, and weather strip refresh
Stability
Profile photo updates now reflect immediately in the UI without needing a relaunch
First-install fix: pre-creates the Application Support directory to prevent CoreData sandbox errors on a fresh install
Centralized logging throughout services and view models (replaces scattered debug prints)
Location search service migrated to the @Observable macro — codebase now uniformly off ObservableObject/@Published
April 21, 2026
Weather
Added cloudy night, snow night, fog night, sunrise, sunset, sun showers, hail, and windy/windy night backgrounds
Sunrise and sunset markers now appear inline in the Next 24 Hours hourly strip
Developer dashboard gains a live Weather Backgrounds gallery — every condition rendered at once, tap any to go fullscreen
Community
Feed reactions moved from a bottom sheet to an inline emoji strip — fixes a bug where nested sheets suppressed in-app notifications
Branded empty-state illustrations added for gardens, tips, and plants in light and dark variants
Reactions detail sheet redesigned: text-only hero, emoji filter chips, floating-emoji avatars, founder seals on each reactor
Performance & Caching
Image cache overhauled: stable cache keys, one-time disk purge for stale entries, atomic two-phase writes so partial saves no longer cause blank hero images
Missing plant assets re-fetched automatically; My Collection no longer falls back to gray placeholders after a cold launch
Unified neutral gray shimmer placeholder across Home, Tips, Gardens, All Plants, and My Collection
Search
Toolbar segments no longer flicker while catalogs are loading
Privacy
PrivacyInfo.xcprivacy fully populated with the app's actual data collection declarations
April 20, 2026
Onboarding
Fully redesigned with a shared progress bar, Back navigation, and a sticky bottom bar across every setup step
Username step: live profile preview card and shuffled suggestion chips
Experience level: accent shadow and animated checkmark on selection
Plant Interests: sticky selection summary, clear-all, and animated chip toggles
Community
Founder badge sheet redesigned with a gold palette, structured perk cards, and instant count from local cache (silently synced from CloudKit)
Founder seal badge introduced — shown in community feed author rows, spotlight posts, and profiles
Reactions detail sheet redesigned with emoji filter chips and floating-emoji avatars
Home
Recommended vs. Ready to Level Up plant rails now pull from separate CloudKit queries
Expert users see a curated Master Collection rail
Quiz hero card adopts the seasonal accent color and shows your current score
Plant Matcher results surface as a seasonal card on Home
Plant Matcher
Redesigned with a progress bar, step-card layout, experience sweet-spot range, collection exclusion, chip filters, and background diff-refresh
Leaderboard & Quiz
Leaderboard: adaptive polling, SwiftData-backed cache, redesigned podium with view-all, personal progress hub
Quiz: point calculation aligned with leaderboard, immediate local score merge after submission, results polish and countdown feedback
Architecture
Centralized PlantRepository, HeroImageCacheStorage, and UserDefaultsCodableStore — reduces boilerplate across the app
Hero image disk cache added for tips and gardens — fixes gradient placeholders on cold launch
CloudKit parallel query fan-out to work around the platform's lack of OR predicates; Spotlight indexing for plants and tips
April 17, 2026
Glossary
Migrated from hardcoded Swift to JSON files; new Pests & Diseases category adds 23 terms including aphids, spider mites, powdery mildew, botrytis, neem oil, and IPM
Redesigned with a Term of the Day hero card, category chips with counts, and tappable rows into a detail sheet
Plant detail pages now auto-link glossary terms inline — tap any highlighted word in the summary, care guide, or toxicity section to read its definition without leaving the view
Weather
Powered by native WeatherKit: 30-minute snapshot cache, plant-care advisories based on current conditions
Weather strip on Home shows condition icon, temperature, humidity, and UV — tap to open the full detail sheet
13 gradient palettes: clear day/night, golden hour, partly cloudy, overcast, rain, storm, snow, fog, hot, and cold
Home
Circular avatar toolbar button (Apple Music–style) opens the profile sheet
Redesigned welcome section and seasonal pill showing season name and days remaining
Admin
Catalog backed by a live webhook to the admin portal; CDN image URLs cached in memory so the picker shows existing images instantly
Infrastructure
CloudKit IN predicate chunked at 200 per query to stay under platform limits; rate-limit errors surface in the app banner with a countdown
Siri "continue" suggestions wired to plant detail views
February 17 – April 16, 2026
Foundation
SwiftUI project started — clean-slate rebuild begins
A lot of foundational work happened in this window that was never committed. We forgot to commit regularly early on, so this period is under-represented here.