A text-preserving accessibility injector for Xcode Storyboards and XIB files.
- 🎯 Automatically adds accessibility identifiers to UI elements in Storyboard/XIB files
- 🔒 Preserves exact formatting and indentation
- ⚡ Fast SAX-based parsing with minimal memory footprint
- 🛠️ Works as both CLI tool and programmatic API
- ✨ Handles self-closing tags correctly
- 📝 Generates consistent, predictable identifiers
npm install -g parsenodenpm install parsenode --save-devProcess a single file:
parsenode --file path/to/YourView.storyboard --applyProcess multiple files with glob patterns:
parsenode --glob "Views/**/*.storyboard" --applyDry run (preview changes without applying):
parsenode --file path/to/YourView.storyboardimport { parseStoryboardFile } from 'parsenode';
import { computePatchOpsForFile } from 'parsenode';
import { applyPatchOpsToFile } from 'parsenode';
import { readFileSync } from 'fs';
// Parse storyboard and get UI elements
const elements = parseStoryboardFile('./path/to/View.storyboard');
// Compute what changes to make
const rawText = readFileSync('./path/to/View.storyboard', 'utf8');
const ops = computePatchOpsForFile(rawText, elements);
// Apply changes
await applyPatchOpsToFile(
'./path/to/View.storyboard',
rawText,
ops,
{ dryRun: false, backup: true }
);ParseNode scans your Storyboard/XIB files for UI elements (buttons, labels, text fields, etc.) that don't have accessibility identifiers. It then generates and injects <accessibility> tags with identifiers based on the element type and existing ID attributes.
Before:
<button opaque="NO" contentMode="scaleToFill" id="abc-123">
<rect key="frame" x="0" y="0" width="100" height="44"/>
</button>After:
<button opaque="NO" contentMode="scaleToFill" id="abc-123">
<rect key="frame" x="0" y="0" width="100" height="44"/>
<accessibility key="accessibilityConfiguration" identifier="btn_abc-123" label="btn_abc-123"/>
</button>- button
- label
- textField
- textView
- imageView
- switch
- slider
- stepper
- segmentedControl
- tableViewCell
- collectionViewCell
- view
- barButtonItem
- navigationItem
- navigationBar
- stackView
- tableView
- collectionView
--file <path>- Process a single file--glob <pattern>- Process files matching glob pattern--apply- Apply changes (omit for dry run)
MIT
Contributions are welcome! Please feel free to submit a Pull Request.