Swift-FocusEngine-Agent-Skill

agent
Guvenlik Denetimi
Uyari
Health Uyari
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Gecti
  • Code scan — Scanned 4 files during light audit, no dangerous patterns found
Permissions Gecti
  • Permissions — No dangerous permissions requested
Purpose
This tool is an AI agent skill designed to help AI coding assistants (like Cursor, Copilot, and Claude) write correct focus management code across Apple platforms, including iOS, tvOS, and macOS. It provides specialized instructions to prevent the common mistakes LLMs typically make when interacting with Apple's focus engine APIs.

Security Assessment
The overall risk is Low. The repository does not request any dangerous permissions or execute shell commands. A lightweight code audit scanned four files and found no dangerous patterns, suspicious network requests, or hardcoded secrets. Because this tool acts primarily as a knowledge base and set of instructions for AI assistants rather than an executable script, its attack surface is minimal.

Quality Assessment
The project is actively maintained, with its most recent push happening just today. It is properly licensed under the permissive MIT license, making it safe for integration into commercial and personal projects. The main drawback is low community visibility, currently sitting at only 5 GitHub stars. However, the project demonstrates clear professionalism through comprehensive documentation, compatibility with major AI developer tools, and references to legitimate sources like WWDC sessions and real-world production apps.

Verdict
Safe to use — a well-documented, actively maintained educational resource with no apparent security risks.
SUMMARY

AI agent skill for Claude Code, Copilot, Cursor, Codex & Gemini — correct focus management for tvOS, iOS, macOS, visionOS & watchOS

README.md

Swift FocusEngine Pro

Agent skill for focus management across all Apple platforms


Swift FocusEngine Pro is a free, open-source agent skill that helps AI coding assistants write correct focus management code for tvOS, iOS/iPadOS, watchOS, visionOS, and macOS. It covers SwiftUI, UIKit, AppKit, and RealityKit — targeting the mistakes LLMs actually make with Apple's focus engine.

Built from real-world experience shipping production tvOS apps, Apple developer documentation, WWDC sessions (2017-2025), and community best practices from Airbnb, Showmax, and others.

Works with Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, and any tool supporting the Agent Skills format.

Table of Contents

Who This Is For

  • tvOS developers — building apps where every interaction depends on the focus engine working correctly
  • iOS/iPadOS developers — adding keyboard, game controller, or external display support with focus groups
  • visionOS developers — navigating the differences between gaze, hover, and focus in spatial computing
  • macOS developers — building keyboard-navigable apps with key view loops, focus rings, and menu commands

Why Use an Agent Skill for Focus?

Focus management on Apple platforms is one of the hardest things to get right — and one of the hardest things to debug when it breaks.

The focus engine is geometric, not hierarchical. It doesn't follow your view tree. When a user swipes right and focus jumps two rows away instead of to the next item, there's no error, no crash, no log — it just looks broken. The item wasn't perfectly vertically aligned, so the engine picked a different candidate. You'll spend hours in UIFocusDebugger before you figure out why.

Apple's documentation covers the APIs but not the real-world edge cases: what happens when you reload data and focus resets to the top, why .disabled() silently removes views from the focus chain on tvOS, why .focusSection() is the difference between a usable scroll view and chaos, or why onHover doesn't fire from eye gaze on visionOS.

LLMs generate focus code that compiles and looks reasonable — but breaks in ways you only discover on a real device with a Siri Remote in your hand. This skill is built from my experience getting focus to actually work in a complex, production tvOS app. Every anti-pattern in here is something I hit, debugged, and fixed.

Installing

Claude Code

# Global (all projects)
npx skills add https://github.com/mhaviv/Swift-FocusEngine-Agent-Skill --skill swift-focusengine-pro -g -y

# Project-level only
npx skills add https://github.com/mhaviv/Swift-FocusEngine-Agent-Skill --skill swift-focusengine-pro -y

Codex

npx skills add https://github.com/mhaviv/Swift-FocusEngine-Agent-Skill --skill swift-focusengine-pro --agent codex

Cursor

npx skills add https://github.com/mhaviv/Swift-FocusEngine-Agent-Skill --skill swift-focusengine-pro --agent cursor

GitHub Copilot

npx skills add https://github.com/mhaviv/Swift-FocusEngine-Agent-Skill --skill swift-focusengine-pro --agent github-copilot

Gemini CLI

npx skills add https://github.com/mhaviv/Swift-FocusEngine-Agent-Skill --skill swift-focusengine-pro --agent gemini

Other Agents

Any agent that supports the Agent Skills format can use this skill. See agentskills.io for instructions on adding skills to your agent.

Don't have Node installed?
brew install node

Or download from nodejs.org.

Using

Claude Code

/swift-focusengine-pro Review this view for tvOS focus issues

Codex

$swift-focusengine-pro Check my SwiftUI code for focus anti-patterns

Cursor

/swift-focusengine-pro Review this view for tvOS focus issues

GitHub Copilot

/swift-focusengine-pro Review this view for tvOS focus issues

Gemini CLI

Use the swift-focusengine-pro skill to review my focus handling code

Any Agent

Use the Swift FocusEngine Pro skill to audit my project for focus management problems

Example Prompts

  • "Why isn't the first item focused when my view appears?"
  • "Focus is jumping to a completely different row when I swipe right — the items aren't perfectly aligned vertically"
  • "How do I keep focus position after my data reloads?"
  • "I added .disabled() to a button but now focus skips over the entire section"
  • "What's the difference between gaze and focus on visionOS?"
  • "My Digital Crown rotation stopped working after I reordered my view modifiers"
  • "How do I make menu bar commands respond to whichever document window is focused?"

What It Covers

4,500+ lines of focus expertise across 14 reference files (v1.5)

Reference Platform Coverage
anti-patterns.md All 29 critical mistakes: 17 original tvOS + 5 production tvOS + 7 macOS-specific
swiftui-focus.md tvOS @FocusState, focusSection, prefersDefaultFocus, AutoFocusManager pattern
uikit-focus.md tvOS UIFocusEnvironment, UIFocusGuide, shouldUpdateFocus, didUpdateFocus
ios-focus.md iOS/iPadOS SwiftUI + UIKit: focus groups, focusGroupIdentifier, UIFocusHaloEffect, keyboard nav, focusedValue, game controller, Stage Manager
watchos-focus.md watchOS SwiftUI: Digital Crown routing, sequential focus, Crown conflicts, .digitalCrownAccessory
visionos-focus.md visionOS SwiftUI + UIKit + RealityKit: gaze vs hover vs focus, HoverEffect, HoverEffectComponent
focus-styling.md All ButtonStyle + isFocused, FocusBorder, CABasicAnimation, CardButtonStyle, macOS focus ring styling
focus-restoration.md All Data reload handling, safe reload pattern, row offset tracking
layout-patterns.md tvOS Table-of-collections, sidebar+content, tab bar, hero+catalog
macos-focus.md macOS AppKit + SwiftUI: key view loop, focus ring, NSView focus APIs, focusedValue for menus, Mac Catalyst, Full Keyboard Access
realitykit-focus.md visionOS RealityKit entity hover, collision shapes, gestures, shader effects, mixed hierarchies
async-focus.md All @MainActor coordination, focus after data load, NavigationStack pop, Task cancellation
accessibility-focus.md All @AccessibilityFocusState, VoiceOver + focus, Full Keyboard Access, Switch Control, Reduce Motion
debugging.md All UIFocusDebugger, _whyIsThisViewNotFocusable, launch arguments, macOS first responder debugging

Anti-Patterns It Catches

Blocking (must fix before ship)

  1. .disabled() removes views from the focus chain on tvOS — gate the action inside the closure instead (.allowsHitTesting(false) is unreliable)
  2. Missing .focusSection() on horizontal ScrollViews — causes cross-row focus jumping in vertical layouts
  3. Adding .focusable() to Buttons or NavigationLinks — creates double-focus artifacts
  4. Mixing SwiftUI and UIKit focus in the same hierarchy — focus environment conflicts
  5. Calling reloadData() during animations — focus resets to the top of the screen
  6. Using frame.width in focus transform calculations — dimensions change when focused
  7. setNeedsFocusUpdate() called from wrong environment — silently fails with no error
  8. Setting isUserInteractionEnabled = false on headers/labels — removes them and their children from focus chain
  9. remembersLastFocusedIndexPath + offscreen reloadData() — remembered index may no longer exist
  10. Using UIView.animate for CALayer properties — animations won't work, use CABasicAnimation

Warning (should fix)

  1. Non-optional @FocusState with focused(_:equals:) — can't represent "nothing focused" state
  2. Missing prepareForReuse() cleanup for focus state — stale focus styling on reused cells
  3. prefersDefaultFocus inside ScrollView — may not work as expected, use defaultFocus instead
  4. LazyVStack/LazyVGrid performance on Apple TV HD — A8 chip can't handle lazy layout recalculation during fast scrolling

tvOS production patterns

  1. LazyVStack deallocates offscreen rows — rapid upward swipe causes focus to jump to tab bar, skipping content
  2. Missing .focusSection() on vertical ScrollView — focus escapes upward to tab bar/nav bar
  3. Allocating objects in didUpdateFocus/shouldUpdateFocus — per-frame garbage causes micro-stutters

macOS-specific

  1. Not overriding acceptsFirstResponder on custom NSView — view is invisible to Tab navigation
  2. Incomplete key view loop — Tab stops working after reaching the last view
  3. Calling becomeFirstResponder() directly — bypasses resign/become handshake, use window.makeFirstResponder
  4. NSPanel stealing focus — inspector panels take focus from document window, use becomesKeyOnlyIfNeeded
  5. Not restoring focus after sheet/alert — focus lost to window instead of returning to original view
  6. .focusable() on NSViewRepresentable — creates double focus layer conflicting with AppKit
  7. Menu items not checking for nil focusedValue — crashes when no window is key

FAQ

How do I set initial focus on a specific view in tvOS?

In SwiftUI, use defaultFocus(_:_:) or prefersDefaultFocus. In UIKit, override preferredFocusEnvironments on the parent view controller. See swiftui-focus.md and uikit-focus.md.

Focus resets after reloadData — how do I keep focus position?

Use remembersLastFocusedIndexPath or the safe reload pattern that locks focus before reloading. See focus-restoration.md.

Focus jumps to the wrong row when I swipe right

The focus engine is geometric, not hierarchical. Add .focusSection() to horizontal ScrollViews to keep focus within rows. See anti-patterns.md (pattern #2).

How do I programmatically move focus?

You cannot directly set focus. Override preferredFocusEnvironments to return the target, then call setNeedsFocusUpdate() + updateFocusIfNeeded() on the correct focus environment. See uikit-focus.md.

UIFocusGuide not working

Common causes: guide not added to the view hierarchy, preferredFocusEnvironments not set on the guide, or incorrect sizing/positioning. Focus guides bridge empty space between focusable views. See uikit-focus.md.

What does focusSection() actually do?

It creates a focus group that the engine treats as a contiguous region, preventing focus from skipping over the section to items in other rows. Essential for horizontal ScrollViews in vertical layouts. See swiftui-focus.md.

How do I debug focus issues on tvOS?

Use UIFocusDebugger.checkFocusability(for:) in the debugger, _whyIsThisViewNotFocusable on any UIView, and the UIFocusLoggingEnabled launch argument. See debugging.md.

Why does .disabled() break focus on Apple TV?

On tvOS, .disabled() removes the view entirely from the focus chain. .allowsHitTesting(false) is commonly recommended but is unreliable — it may map to isUserInteractionEnabled = false under the hood. The most reliable approach is to gate the action inside the button closure instead of disabling the view. For lists/sidebars, use the dual @FocusState + .disabled() gating pattern (anti-pattern #25). See anti-patterns.md (patterns #1 and #25).

@FocusState not dismissing keyboard on iOS

Setting @FocusState to nil should dismiss the keyboard, but it can fail inside sheets or NavigationStack. See ios-focus.md for workarounds.

How do I move focus between TextFields with the keyboard next button?

Use @FocusState with an enum representing each field, then set the next case in onSubmit. See ios-focus.md.

How does keyboard focus navigation work on iPad?

iOS 15+ added UIFocusSystem support for hardware keyboards. Opt in with UIFocusHaloEffect, focusGroupIdentifier, and focusEffect. See ios-focus.md.

How does focus work across multiple windows on iPad with Stage Manager?

Each window scene has its own focus state. Use focusedSceneValue to propagate focus information across scenes. See ios-focus.md (Stage Manager section).

How do I use focusedSceneValue for multi-window iPad apps?

Define a FocusedValueKey, set values with .focusedSceneValue(), and read them with @FocusedValue in your menu bar or toolbar commands. See ios-focus.md.

Digital Crown rotation stops working after reordering view modifiers

The .digitalCrownRotation() modifier is order-sensitive. It must be applied in the correct position relative to other modifiers. See watchos-focus.md.

How do I handle nested scrolling conflicts with Digital Crown?

When a ScrollView contains a Digital Crown control, the Crown drives both scrolling and the control. Use explicit @FocusState to determine which element owns the Crown. See watchos-focus.md.

What's the difference between hover and focus on visionOS?

visionOS uses eye tracking for hover (.hoverEffect()) and indirect input for focus. They are separate systems. Gaze creates hover highlights, but tap gestures are needed for activation. See visionos-focus.md.

How do I customize hover effects in visionOS?

Use HoverEffectComponent on RealityKit entities with styles: default, spotlight, shader, or highlight. For SwiftUI views, use .hoverEffect(.highlight) or .hoverEffect(.lift). See realitykit-focus.md.

How does focus work in Mac Catalyst apps?

Mac Catalyst inherits iPad's UIFocusSystemUIFocusHaloEffect renders as a macOS focus ring, and focusGroupIdentifier maps to Tab navigation groups. If your iPad app doesn't support keyboard focus, neither will the Catalyst version. See macos-focus.md (Mac Catalyst section).

How do I handle keyboard focus in a macOS SwiftUI app?

Use @FocusState (same as iOS) and .focusable() for custom views. macOS focus is always active — no hardware keyboard requirement. For menu bar integration, use focusedValue / focusedSceneValue. See macos-focus.md.

Focus works in simulator but not on device (or vice versa)

The focus engine behaves differently between Xcode Simulator and physical hardware, especially for tvOS remote gestures and visionOS eye tracking. Always test focus on real devices. See debugging.md.

Sources

Built from:

  • Apple Developer Documentation (UIFocusEnvironment, UIFocusGuide, FocusState, focusSection, HoverEffect)
  • WWDC17: Focus Interaction in tvOS 11
  • WWDC21: Direct and reflect focus in SwiftUI + Focus on iPad keyboard navigation
  • WWDC23: The SwiftUI cookbook for focus
  • WWDC24: Create custom hover effects in visionOS
  • WWDC25: Design hover interactions for visionOS
  • Production tvOS apps with complex focus requirements
  • Community guides (Airbnb, Showmax, Fatbobman, Big Nerd Ranch)

Complementary Skills

Swift FocusEngine Pro pairs well with these skills:

See the Swift Agent Skills directory for more.

Changelog

See CHANGELOG.md for release history.

Contributing

Contributions are welcome! Focus on:

  • Edge cases — non-obvious focus behaviors that catch developers off guard
  • New platform APIs — iOS 19, tvOS 19, visionOS 3, watchOS 12, macOS 16 additions
  • Real-world patterns — battle-tested solutions from production apps
  • Anti-patterns — mistakes LLMs commonly generate

Keep reference files focused and under 300 lines each. Don't repeat things LLMs already know — focus on what they get wrong. All contributions must be MIT licensed.

Please read the Code of Conduct before contributing.

License

Swift FocusEngine Pro was created by Michael Haviv and is licensed under the MIT License.

Yorumlar (0)

Sonuc bulunamadi