Skip to content

Latest commit

 

History

History
179 lines (145 loc) · 10.8 KB

File metadata and controls

179 lines (145 loc) · 10.8 KB

Best Practices: Design, Architecture & Development

These are practices (some new, some evergreen) that I consider especially important in this era.

User Interface & UX

• Embrace the Liquid Glass aesthetic: use translucency, blur, materials, adaptive colors, lighting & shadows appropriately so your app feels "native" on Tahoe 26. • Respect light & dark modes; ensure that translucent elements, glows, shadows adapt cleanly without readability or contrast issues. • Responsiveness: Mac apps have varying window sizes, possibly full screen, sidebars, multiple monitors. Design layouts that adapt; test on large / small displays. • Input modalities: Mouse + keyboard, trackpad gestures, maybe even stylus / touch in future (if hardware supports). Ensure keyboard navigation, focus ring, menu items, drag/drop support are solid. • Iconography & branding: use the new Icon Composer tool for app icons, check how icons adapt under different rendering modes, tints, specular highlights.

Performance & Graphics

• Use Metal 4 and the updated graphics/video-effect APIs for demanding rendering or visual work; avoid overdraw, unnecessary compositing. • Efficient resource usage: keep memory footprint reasonable, manage battery / thermal effects. On Apple Silicon, optimize for low power modes, etc. • Lazy load UI when possible; defer heavy work to background threads; use Swift Concurrency features (async/await, structured concurrency) to avoid blocking the UI. • Optimize startup time; minimize resource use at launch.

Architecture & Code Quality

• Modular design: separate UI, data, business logic. This helps in maintenance, testing, multi-platform reuse. • Use Swift + SwiftUI where feasible, but be ready to drop into AppKit or custom views when necessary (since not all UI/custom behavior is mature in SwiftUI yet). • Handle platform differences cleanly: if you plan to support iPadOS ↔ macOS, minimize #if os(...) scatter; design abstractions or use shared modules. • Maintain backward compatibility: macOS 26 won't be the only OS version your users run. Use @available / version checks, avoid deprecated APIs. • Always use the latest macOS 26 APIs and verify any API before using to ensure compatibility and avoid deprecation warnings.

Security & Privacy

• Privacy-by-design: request permissions only when needed; explain why in UI. Transparent data policy. • Secure storage: use Keychain, encrypt sensitive data, secure files at rest. • Notarization & code signing: ensure builds are properly signed; notarize if distributing outside App Store. • Sandboxing (if using App Store) and adhering to Apple's guidelines for entitlements, permissions. • Be mindful of third-party libraries/SDKs: their privacy and security implications.

Core Principles for Menu Bar Apps

• Lightweight & always available → Users expect menu bar apps to be quick to open, use minimal memory, and not clutter the system. • Instant interaction → Menu should open immediately with no lag; window actions must feel snappy. • Non-intrusive UI → Avoid modal dialogs or complex flows; keep interaction short and to the point. • Respect macOS idioms → Use Apple-style icons, keyboard shortcuts, menu bar spacing, and consistent naming (e.g., "Preferences…", "Quit").

UI/UX Best Practices for Window Management Apps

Menu Bar Presence

• Use a simple, recognizable icon that hints at layouts/windows (not too noisy in Liquid Glass translucency). • Offer optional text labels if clarity is needed. • Adapt to light/dark mode and Liquid Glass transparency (macOS 26 aesthetics).

Menu Design

• Keep menus short → group options into submenus if needed (e.g., "Layouts → Grid / 2-Column / Custom"). • Provide quick toggles: e.g., "Snap to Left Half" directly in the menu without opening extra UI. • Consider a secondary floating palette (optional) for power users, but never force it.

Layouts

• Predefined layouts (halves, thirds, grids) must be one click or one shortcut away. • Allow custom layouts — but save them behind Preferences, not cluttering the main menu. • Make it clear what will happen before it happens (preview overlays / highlight zones).

Keyboard Shortcuts

• Power users will live on shortcuts. Allow configurable hotkeys for each layout. • Respect macOS conventions — use ⌘⌥ (Command + Option) or ⌃⌥ (Control + Option) combos. • Provide conflict detection (warn if another app/system shortcut overlaps).

Technical Best Practices for Window Management Apps

Window Management APIs

• Use AXUIElement (Accessibility API) for manipulating window positions/sizes. • Request accessibility permission gracefully, with clear explanation. If permission is missing, show a helpful guide. • Cache permission state to avoid repeated nags.

Performance

• Minimize polling — use event listeners where possible. • Keep menu app memory <50MB idle. Users are sensitive to bloated background apps. • Test with many windows (20+) across multiple monitors to ensure speed.

Multi-Monitor Support

• Must handle: different resolutions, scaling (Retina vs non-Retina), and arrangements (vertical, horizontal). • Allow per-monitor layouts. Example: Grid on external monitor, full-screen split on laptop.

Persistence

• Remember last used layout, custom configurations, and hotkeys. • Optionally auto-restore layouts when specific apps launch.

Integration & System Features

App Intents (macOS 26)

• Expose layouts as system actions → Spotlight search: type "Snap Safari left" → executes via App Intents. • Siri / Shortcuts support → let users build workflows like "When I plug in monitor → Apply grid layout."

Accessibility & Transparency

• Full VoiceOver compatibility (announce menus properly). • Contrast-safe icons for Liquid Glass style.

Security & Trust

• Clear, minimal permission requests: only Accessibility API. • Sandboxed app if targeting App Store (but may require helper for deeper system integration). • Sign & notarize app for outside distribution.

Power Features to Differentiate

AI-Assisted Layouts (Forward-Thinking)

• Detect work patterns → suggest layouts (e.g., "You usually place VSCode + Safari side by side, apply now?"). • Predictive window snapping: offer best guess based on window type.

Layout Sets / Profiles

• "Coding mode", "Design mode", "Meetings mode" with pre-arranged app positions. • Hot-switch profiles via menu or shortcut.

Quick Layout Preview Overlay

• Subtle screen overlay showing zones when triggering a shortcut. Helps with discoverability and precision.

SwiftUI Menu Implementation Gotchas

Menu Label Limitations

CRITICAL: SwiftUI Menu labels do NOT support complex layouts like HStack, VStack, or custom views • DO NOT USE: HStack, Spacer(), or custom View components in Menu labels - they will not render • USE INSTEAD: AttributedString for styled text, or simple string concatenation with tab characters (\t) • WORKING SOLUTION: Use AttributedString with different font sizes and colors for proper macOS-style menu shortcuts

Menu Shortcut Display Best Practices

• Use AttributedString to create rich text with different styling (font size, color) • Apply .font(.caption) and .foregroundColor(.secondary) to shortcut text for proper macOS styling • Use spacing (" ") between layout name and shortcut for visual separation • Only display shortcuts when they exist (conditional rendering)

Common Menu Implementation Mistakes

• ❌ Trying to use HStack/Spacer in Menu labels - doesn't work • ❌ Using Label with custom content in Menu labels - doesn't render properly
• ❌ Complex View hierarchies in Menu labels - ignored by SwiftUI • ❌ AttributedString in Menu labels - not properly supported • ❌ NSWindow.menuBar property - doesn't exist (NSWindow has no menuBar property) • ✅ Simple string concatenation with tab characters - works for basic alignment • ✅ Using NSMenuItem directly with NSAttributedString - proper solution but requires dropping SwiftUI Menu

AppKit Menu Implementation Best Practices

NSMenuItem with NSAttributedString: Use NSMenuItem.attributedTitle for proper styling • Font Styling: Use NSFont.menuFont(ofSize: NSFont.smallSystemFontSize) for smaller shortcut text • Color Styling: Use NSColor.secondaryLabelColor for muted shortcut appearance • Tab Alignment: Use "\t" character for proper macOS menu alignment • Menu Structure: Create NSMenu with submenus for complex layouts • Status Bar Integration: Use NSStatusItem for menu bar presence • App Delegate Pattern: Use NSApplicationDelegate for proper app lifecycle management

Release Management Best Practices

GitHub Release Process

ALWAYS build and upload DMG files when creating releases • Complete release checklist:

  1. Update version number in Info.plist (CFBundleShortVersionString and CFBundleVersion)
  2. Commit changes with proper version tag
  3. Create git tag with detailed release notes
  4. Push code and tag to repository
  5. BUILD DMG file using build scripts (build.sh or build_dmg.sh)
  6. Upload DMG to GitHub release using gh release upload or manually
  7. Verify release is complete with downloadable assets

DMG Building Process

Use existing build scripts: Check for build.sh, build_dmg.sh, or create_dmg.sh • Build location: DMG files are typically stored in build/releases/ directory • Naming convention: Use format like "Snap-v1.0.3.dmg" for consistency • Upload command: gh release upload v1.0.3 build/releases/Snap-v1.0.3.dmg

Release Notes Best Practices

Include detailed changelog with technical improvements • Mention code statistics (lines added/removed, files changed) • Highlight new features and bug fixes • Use proper markdown formatting for GitHub display • Include technical details for developers

Common Release Mistakes to Avoid

• ❌ Creating release without DMG file - users can't download the app • ❌ Forgetting to update version numbers in Info.plist • ❌ Not building DMG after code changes • ❌ Pushing to wrong repository (check remote URLs) • ❌ Creating release with incomplete changelog • ❌ Uploading multiple DMG files with different names (e.g., "app-v1.0.dmg" and "app-v1.0-updated.dmg") • ❌ Leaving old/duplicate DMG files in release - confuses users and clutters release page • ✅ Always verify DMG file exists before marking release complete • ✅ Test DMG installation before releasing • ✅ Use consistent DMG naming: "AppName-v1.0.0.dmg" format only • ✅ Replace, don't add: If rebuilding DMG, delete old one first, then upload new one • ✅ Keep only the latest DMG in each release • ✅ Include both signed and unsigned DMG if applicable