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.