$npx -y skills add rshankras/claude-code-apple-skills --skill app-extensionsGenerates 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 ex
| 1 | # App Extensions Generator |
| 2 | |
| 3 | 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. |
| 4 | |
| 5 | ## When This Skill Activates |
| 6 | |
| 7 | Use this skill when the user: |
| 8 | - Asks to "add a share extension" or "share sheet extension" |
| 9 | - Wants to "receive content from other apps" or "accept shared content" |
| 10 | - Mentions "action extension" or "content manipulation extension" |
| 11 | - Wants to "add a custom keyboard" or "keyboard extension" |
| 12 | - Asks about "Safari extension" or "Safari web extension" |
| 13 | - Mentions "app extension" or "extension target" generically |
| 14 | - Wants to "share data between app and extension" or "App Groups" |
| 15 | |
| 16 | ## Pre-Generation Checks |
| 17 | |
| 18 | ### 1. Project Context Detection |
| 19 | - [ ] Check deployment target (iOS 16+ / macOS 13+) |
| 20 | - [ ] Check Swift version (requires Swift 5.9+) |
| 21 | - [ ] Identify project structure (find .xcodeproj or Package.swift) |
| 22 | - [ ] Identify source file locations |
| 23 | |
| 24 | ### 2. Existing Extension Detection |
| 25 | Search for existing extension targets: |
| 26 | ``` |
| 27 | Glob: **/*Extension*/*.swift, **/*Extension*/Info.plist |
| 28 | Grep: "NSExtensionPointIdentifier" or "NSExtensionPrincipalClass" |
| 29 | ``` |
| 30 | |
| 31 | If existing extensions found: |
| 32 | - Ask if user wants to add another or modify existing |
| 33 | - Identify existing App Groups configuration |
| 34 | |
| 35 | ### 3. App Groups Detection |
| 36 | Check for existing App Groups setup: |
| 37 | ``` |
| 38 | Glob: **/*.entitlements |
| 39 | Grep: "com.apple.security.application-groups" |
| 40 | ``` |
| 41 | |
| 42 | If App Groups exist, reuse the existing group identifier. |
| 43 | |
| 44 | ## Configuration Questions |
| 45 | |
| 46 | Ask user via AskUserQuestion: |
| 47 | |
| 48 | 1. **What type of extension?** |
| 49 | - Share Extension (accept content from other apps, display share UI) |
| 50 | - Action Extension (manipulate content in-place -- transform text, edit images) |
| 51 | - Keyboard Extension (custom input keyboard with KeyboardViewController) |
| 52 | - Safari Web Extension (inject JavaScript/CSS into web pages) |
| 53 | |
| 54 | 2. **What content types does it handle?** |
| 55 | - Text (plain text, rich text) |
| 56 | - URLs (web links, deep links) |
| 57 | - Images (photos, screenshots) |
| 58 | - Files (documents, PDFs, archives) |
| 59 | - All (any content type) |
| 60 | |
| 61 | 3. **Does the extension need to share data with the main app?** |
| 62 | - Yes -- needs App Groups (shared UserDefaults, shared file container, shared Keychain) |
| 63 | - No -- extension is self-contained |
| 64 | |
| 65 | ## Generation Process |
| 66 | |
| 67 | ### Step 1: Read Templates |
| 68 | Read `templates.md` for production Swift code. |
| 69 | |
| 70 | ### Step 2: Create Extension Files |
| 71 | Based on extension type selected: |
| 72 | |
| 73 | **Share Extension:** |
| 74 | 1. `ShareViewController.swift` -- Main share extension view controller with content handling |
| 75 | 2. `Info.plist` -- Extension configuration with activation rules |
| 76 | |
| 77 | **Action Extension:** |
| 78 | 3. `ActionViewController.swift` -- Action extension with content manipulation |
| 79 | 4. `Info.plist` -- Extension configuration |
| 80 | |
| 81 | **Keyboard Extension:** |
| 82 | 5. `KeyboardViewController.swift` -- Custom keyboard with UIInputViewController |
| 83 | 6. `Info.plist` -- Keyboard extension configuration |
| 84 | |
| 85 | **Safari Web Extension:** |
| 86 | 7. `SafariWebExtensionHandler.swift` -- Native message handler |
| 87 | 8. `manifest.json` -- Web extension manifest |
| 88 | 9. `content.js` -- Content script template |
| 89 | |
| 90 | ### Step 3: Create Shared Infrastructure |
| 91 | If data sharing selected: |
| 92 | 10. `SharedDataManager.swift` -- App Group data sharing helper |
| 93 | |
| 94 | ### Step 4: Determine File Location |
| 95 | Extensions are separate targets: |
| 96 | - Share Extension -> `ShareExtension/` |
| 97 | - Action Extension -> `ActionExtension/` |
| 98 | - Keyboard Extension -> `KeyboardExtension/` |
| 99 | - Safari Web Extension -> `SafariWebExtension/` |
| 100 | - Shared code -> `Shared/` or within main app target |
| 101 | |
| 102 | ## Output Format |
| 103 | |
| 104 | After generation, provide: |
| 105 | |
| 106 | ### Files Created |
| 107 | |
| 108 | **Share Extension:** |
| 109 | ``` |
| 110 | ShareExtension/ |
| 111 | ├── ShareViewController.swift # Main share extension view controller |
| 112 | └── Info.plist # Extension activation rules & config |
| 113 | ``` |
| 114 | |
| 115 | **Action Extension:** |
| 116 | ``` |
| 117 | ActionExtension/ |
| 118 | ├── ActionViewController.swift # Content manipulation controller |
| 119 | └── Info.plist # Extension activation rules & config |
| 120 | ``` |
| 121 | |
| 122 | **Keyboard Extension:** |
| 123 | ``` |
| 124 | KeyboardExtension/ |
| 125 | ├── KeyboardViewController.swift # UIInputViewController subclass |
| 126 | └── Info.plist # Keyboard extension config |
| 127 | ``` |
| 128 | |
| 129 | **Safari Web Extension:** |
| 130 | ``` |
| 131 | SafariWebExtension/ |
| 132 | ├── SafariWebExtensionHandler.swift # Native message handler |
| 133 | └── Resources/ |
| 134 | ├── manifest.json # Web extension manifest |
| 135 | ├── conte |