app-extensions
Generates app extension infrastructure for Share Extensions, Action Extensions, Keyboard Extensions, and Safari Web Extensions with data sharing via App Groups. Use when user wants to add a share extension, action extension, keyboard extension, Safari web extension, or any app extension type.
What this skill does
# App Extensions Generator
Generate production app extension infrastructure -- Share Extensions for receiving content from other apps, Action Extensions for manipulating content in-place, Keyboard Extensions for custom input, and Safari Web Extensions for browser integration. Includes App Group data sharing between the host app and extensions.
## When This Skill Activates
Use this skill when the user:
- Asks to "add a share extension" or "share sheet extension"
- Wants to "receive content from other apps" or "accept shared content"
- Mentions "action extension" or "content manipulation extension"
- Wants to "add a custom keyboard" or "keyboard extension"
- Asks about "Safari extension" or "Safari web extension"
- Mentions "app extension" or "extension target" generically
- Wants to "share data between app and extension" or "App Groups"
## Pre-Generation Checks
### 1. Project Context Detection
- [ ] Check deployment target (iOS 16+ / macOS 13+)
- [ ] Check Swift version (requires Swift 5.9+)
- [ ] Identify project structure (find .xcodeproj or Package.swift)
- [ ] Identify source file locations
### 2. Existing Extension Detection
Search for existing extension targets:
```
Glob: **/*Extension*/*.swift, **/*Extension*/Info.plist
Grep: "NSExtensionPointIdentifier" or "NSExtensionPrincipalClass"
```
If existing extensions found:
- Ask if user wants to add another or modify existing
- Identify existing App Groups configuration
### 3. App Groups Detection
Check for existing App Groups setup:
```
Glob: **/*.entitlements
Grep: "com.apple.security.application-groups"
```
If App Groups exist, reuse the existing group identifier.
## Configuration Questions
Ask user via AskUserQuestion:
1. **What type of extension?**
- Share Extension (accept content from other apps, display share UI)
- Action Extension (manipulate content in-place -- transform text, edit images)
- Keyboard Extension (custom input keyboard with KeyboardViewController)
- Safari Web Extension (inject JavaScript/CSS into web pages)
2. **What content types does it handle?**
- Text (plain text, rich text)
- URLs (web links, deep links)
- Images (photos, screenshots)
- Files (documents, PDFs, archives)
- All (any content type)
3. **Does the extension need to share data with the main app?**
- Yes -- needs App Groups (shared UserDefaults, shared file container, shared Keychain)
- No -- extension is self-contained
## Generation Process
### Step 1: Read Templates
Read `templates.md` for production Swift code.
### Step 2: Create Extension Files
Based on extension type selected:
**Share Extension:**
1. `ShareViewController.swift` -- Main share extension view controller with content handling
2. `Info.plist` -- Extension configuration with activation rules
**Action Extension:**
3. `ActionViewController.swift` -- Action extension with content manipulation
4. `Info.plist` -- Extension configuration
**Keyboard Extension:**
5. `KeyboardViewController.swift` -- Custom keyboard with UIInputViewController
6. `Info.plist` -- Keyboard extension configuration
**Safari Web Extension:**
7. `SafariWebExtensionHandler.swift` -- Native message handler
8. `manifest.json` -- Web extension manifest
9. `content.js` -- Content script template
### Step 3: Create Shared Infrastructure
If data sharing selected:
10. `SharedDataManager.swift` -- App Group data sharing helper
### Step 4: Determine File Location
Extensions are separate targets:
- Share Extension -> `ShareExtension/`
- Action Extension -> `ActionExtension/`
- Keyboard Extension -> `KeyboardExtension/`
- Safari Web Extension -> `SafariWebExtension/`
- Shared code -> `Shared/` or within main app target
## Output Format
After generation, provide:
### Files Created
**Share Extension:**
```
ShareExtension/
├── ShareViewController.swift # Main share extension view controller
└── Info.plist # Extension activation rules & config
```
**Action Extension:**
```
ActionExtension/
├── ActionViewController.swift # Content manipulation controller
└── Info.plist # Extension activation rules & config
```
**Keyboard Extension:**
```
KeyboardExtension/
├── KeyboardViewController.swift # UIInputViewController subclass
└── Info.plist # Keyboard extension config
```
**Safari Web Extension:**
```
SafariWebExtension/
├── SafariWebExtensionHandler.swift # Native message handler
└── Resources/
├── manifest.json # Web extension manifest
├── content.js # Content script
└── popup.html # Popup UI (optional)
```
**Shared (if data sharing enabled):**
```
Shared/
└── SharedDataManager.swift # App Group data sharing
```
### Integration Steps
**1. Add Extension Target in Xcode:**
- File > New > Target
- Select the extension type (Share, Action, Keyboard, Safari Web)
- Configure bundle identifier: `com.yourapp.ShareExtension`
- Xcode creates the target with boilerplate -- replace with generated code
**2. Configure App Groups (if data sharing):**
- Select main app target > Signing & Capabilities > Add "App Groups"
- Add group: `group.com.yourapp.shared`
- Select extension target > Signing & Capabilities > Add "App Groups"
- Add the same group identifier
**3. Share code between targets:**
- Add shared files to both the app and extension targets
- Or create a shared framework target
### Extension Content Handling
**Accept shared URLs:**
```swift
if provider.hasItemConformingToTypeIdentifier(UTType.url.identifier) {
provider.loadItem(forTypeIdentifier: UTType.url.identifier) { item, error in
guard let url = item as? URL else { return }
// Process URL
}
}
```
**Accept shared images:**
```swift
if provider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
provider.loadItem(forTypeIdentifier: UTType.image.identifier) { item, error in
if let imageURL = item as? URL {
let imageData = try? Data(contentsOf: imageURL)
// Process image data
}
}
}
```
**Share data to main app via App Groups:**
```swift
let shared = SharedDataManager.shared
shared.saveSharedContent(url.absoluteString, forKey: "lastSharedURL")
```
### Testing
**Share Extension:**
1. Build and run the extension scheme
2. Select a host app (Safari, Photos, etc.)
3. Share content and verify your extension appears
4. Test with different content types
**Action Extension:**
1. Build and run the extension scheme
2. Open content in a supported app
3. Tap the share/action button and select your action
**Keyboard Extension:**
1. Build and run the keyboard extension scheme
2. Go to Settings > General > Keyboard > Keyboards > Add New Keyboard
3. Select your keyboard
4. Open any text field and switch to your keyboard
**Safari Web Extension:**
1. Build and run the app (which contains the extension)
2. Go to Safari > Settings > Extensions
3. Enable your extension
4. Navigate to a web page and verify behavior
## Extension Lifecycle and Limits
### Memory Limits
- Share Extension: ~120 MB
- Action Extension: ~120 MB
- Keyboard Extension: ~48 MB (very constrained)
- Safari Web Extension: ~6 MB for content scripts
### Execution Limits
- Extensions must complete work quickly (no long background execution)
- Must call `completeRequest()` or `cancelRequest()` when done
- No access to HealthKit, CallKit, or some restricted frameworks
- Network requests are allowed but should be brief
### Extension Termination
The system can terminate extensions at any time for resource reclamation. Save state frequently and handle interruption gracefully.
## Gotchas
### completeRequest Must Be Called
The extension host waits for `extensionContext?.completeRequest(returningItems:)`. If you never call it, the share sheet hangs and the user is stuck. Always call it in both success and error paths.
### Keyboard Extensions Need Open Access for Network
By default keyboard extensions have no network access. The user must expRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.