# Safe Area Compliance

> Detects unsafe safe-area overrides and hardcoded inset values that hide content behind the Dynamic Island, notch, or home indicator, violating Apple's Human Interface Guidelines for adaptive layout.

- **Type:** Skill
- **Install:** `agentstack add skill-cruisediary-apple-app-review-skills-safe-area-compliance`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [cruisediary](https://agentstack.voostack.com/s/cruisediary)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [cruisediary](https://github.com/cruisediary)
- **Source:** https://github.com/cruisediary/apple-app-review-skills/tree/main/skills/layout/safe-area-compliance

## Install

```sh
agentstack add skill-cruisediary-apple-app-review-skills-safe-area-compliance
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Skill: Safe Area Compliance

## Purpose
Detects unsafe safe-area overrides and hardcoded inset values that hide content behind the Dynamic Island, notch, or home indicator, violating Apple's Human Interface Guidelines for adaptive layout.

## Apple Guideline
- **Primary:** HIG — Adaptivity and Layout (Apple Human Interface Guidelines)
- **Related:** 2.1
- **Reference:** `references/hig/adaptive-layout.md`

## Real-World Rejection Cases
- **Case:** Content hidden behind Dynamic Island on iPhone 14 Pro and later
  **Source:** Apple Developer Forums
  **Root cause:** View used `.edgesIgnoringSafeArea(.all)` without compensating insets, pushing interactive controls into the Dynamic Island cutout area.

- **Case:** Bottom navigation buttons unreachable behind home indicator
  **Source:** App Store Connect rejection feedback
  **Root cause:** Tab bar and custom buttons were positioned at `y = screenHeight - 49` — correct for notchless iPhones but obscured by the home indicator on Face ID devices.

- **Case:** Developer hardcoded `top: 44` inset — broke on devices with different safe areas
  **Source:** Apple Developer Forums
  **Root cause:** The status-bar height is not a fixed constant; devices with Dynamic Island, notch, or no notch all have different top safe-area values.

## Trigger
Invoke on any iOS project that targets iPhone or iPad to verify safe-area insets are respected.

## Inputs
| Name | Type | Default | Description |
|------|------|---------|-------------|
| `project_root` | path | cwd | iOS/macOS project root |
| `shared_context` | object | nil | Pre-collected context from appstore-full-audit Phase 1 |

## Actions

### Phase 1: Context Collection
*Skip this phase if `shared_context` is provided.*

1. `Glob` `**/*.swift` — collect Swift source files.
2. `Glob` `**/*.m` — collect Objective-C source files.
3. `Glob` `**/*.storyboard` and `**/*.xib` — note Interface Builder files for manual safe-area review.

### Phase 2: Checks

1. **Full safe-area suppression (SwiftUI)**
   `Grep` pattern `\.edgesIgnoringSafeArea\(\.all\)` in `**/*.swift`
   Every match → 🟠 HIGH. Suppressing all safe-area insets risks content being clipped by hardware features on any device.

2. **Zero-inset layout (UIKit)**
   `Grep` pattern `UIEdgeInsets\.zero` in `**/*.swift` and `**/*.m`
   Review each match for proximity to layout constraint setup. When used to zero out system-defined safe-area insets → 🟠 HIGH.

3. **Hardcoded safe-area constants**
   `Grep` pattern `top:\s*44|bottom:\s*34|bottom:\s*83` in `**/*.swift` and `**/*.m`
   Every match → 🟠 HIGH. These magic numbers match specific device safe-area heights and will be wrong on other hardware.

4. **Unscoped ignoresSafeArea (SwiftUI)**
   `Grep` pattern `ignoresSafeArea\(\)` in `**/*.swift`
   Flag calls that do not include `.keyboard` as the region argument → 🟡 MEDIUM. Scoping to `.keyboard` is the safe pattern; bare `ignoresSafeArea()` suppresses all regions.

### Phase 3: Output
Collect all findings from Phase 2 and build the prioritised findings list below. Include file paths and line numbers. Omit tiers with no findings.

## Output Format

```
## Safe Area Compliance — Findings

### 🔴 CRITICAL — Guaranteed rejection
- [ ] TODO:  — `file:line` — HIG Adaptivity

### 🟠 HIGH — Very likely rejection
- [ ] TODO:  — `file:line` — HIG Adaptivity

### 🟡 MEDIUM — Possible rejection
- [ ] TODO:  — `file:line`

### 🟢 LOW — Best practice
- [ ] TODO: 
```

## Tools Used
`Glob`, `Grep`, `Read`

## Constraints
- Read-only. No file edits.
- No network calls.
- Skip Phase 1 if `shared_context` is provided by orchestrating agent.
- Works on Swift, Objective-C, React Native, Flutter projects.

## Quick Commands

Run these in your project root to check manually:

```bash
# Check for unsafe safe area overrides
!grep -rn "edgesIgnoringSafeArea\|ignoresSafeArea\|UIEdgeInsets\.zero" . --include="*.swift"

# Check for hardcoded inset values (44=nav bar, 34=home indicator)
!grep -rn "top:.*44\|bottom:.*34\|bottom:.*83" . --include="*.swift"
```

## Swift Anti-Pattern Reference
`examples/swift/LayoutPatterns.swift`

## Detection Steps

1. **Find target files**
   - Glob: `**/*.swift`, `**/*.m`, `**/*.storyboard`, `**/*.xib`

2. **Search for rejection patterns**
   - Grep `edgesForExtendedLayout = \[\]` — disables safe area extension
   - Grep `UIEdgeInsets(top: 0\|UIEdgeInsets(top: 20\|UIEdgeInsets(top: 44` — hardcoded status bar height
   - Grep `frame\.origin\.y = 0\|frame\.origin\.y = 20\|frame\.origin\.y = 44` — hardcoded Y origin
   - Grep `safeAreaInsets\|safeAreaLayoutGuide` — correct safe area handling (absence is the problem)

3. **Determine verdict**
   - Hardcoded `top: 20` or `top: 44` insets → 🟠 HIGH (content hidden behind Dynamic Island)
   - `edgesForExtendedLayout = []` without safe area compensation → 🟠 HIGH
   - `safeAreaLayoutGuide` used throughout → 🟢 pass

4. **Report**
   - File path + line of hardcoded inset
   - Fix: Replace hardcoded insets with `view.safeAreaInsets.top`; use `safeAreaLayoutGuide` anchors in Auto Layout

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [cruisediary](https://github.com/cruisediary)
- **Source:** [cruisediary/apple-app-review-skills](https://github.com/cruisediary/apple-app-review-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-cruisediary-apple-app-review-skills-safe-area-compliance
- Seller: https://agentstack.voostack.com/s/cruisediary
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
