Install
$ agentstack add skill-cruisediary-apple-app-review-skills-safe-area-compliance ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
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: 44inset — 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.
Glob**/*.swift— collect Swift source files.Glob**/*.m— collect Objective-C source files.Glob**/*.storyboardand**/*.xib— note Interface Builder files for manual safe-area review.
Phase 2: Checks
- 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.
- 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.
- 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.
- 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_contextis provided by orchestrating agent. - Works on Swift, Objective-C, React Native, Flutter projects.
Quick Commands
Run these in your project root to check manually:
# 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
- Find target files
- Glob:
**/*.swift,**/*.m,**/*.storyboard,**/*.xib
- 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)
- Determine verdict
- Hardcoded
top: 20ortop: 44insets → 🟠 HIGH (content hidden behind Dynamic Island) edgesForExtendedLayout = []without safe area compensation → 🟠 HIGHsafeAreaLayoutGuideused throughout → 🟢 pass
- Report
- File path + line of hardcoded inset
- Fix: Replace hardcoded insets with
view.safeAreaInsets.top; usesafeAreaLayoutGuideanchors 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
- Source: cruisediary/apple-app-review-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.