Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,22 @@ clix doctor

### `clix ios-setup`

Configure iOS capabilities required for the Clix SDK (Push Notifications and App Groups).
Configure iOS capabilities and Notification Service Extension (NSE) for the Clix SDK.

```bash
clix ios-setup
```

**What it does:**
1. Analyzes your iOS project structure
2. Checks current capabilities status
2. Checks current capabilities status (Push Notifications, App Groups)
3. Creates/modifies entitlements files
4. Guides you through Xcode and Apple Developer Portal configuration
4. Guides NSE setup for rich push notifications:
- Creates `{AppName}NotificationServiceExtension` target
- Implements `NotificationService.swift` with `ClixNotificationServiceExtension`
- Configures CocoaPods/SPM dependencies for extension target
- Sets build settings (`ENABLE_USER_SCRIPT_SANDBOXING` for Xcode 15+)
5. Guides you through Xcode and Apple Developer Portal configuration

**Note:** Some steps require manual action in Xcode and Apple Developer Portal.

Expand Down Expand Up @@ -277,7 +282,7 @@ Use these commands within the interactive chat (`clix`):
| `/install` | | Autonomous SDK installation |
| `/doctor` | | Check SDK integration status |
| `/debug` | | Interactive debugging assistant |
| `/ios-setup` | `/capabilities`, `/ios-capabilities` | Configure iOS capabilities |
| `/ios-setup` | `/capabilities`, `/ios-capabilities` | Configure iOS capabilities and NSE |

### Interactive Skills

Expand Down
40 changes: 27 additions & 13 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ These can be run from command-line (`clix <command>`) or chat mode:
- `/install` - Autonomous SDK installation with automatic file modifications
- `/doctor` - Analyze SDK integration status (automatic scan, JSON output)
- `/debug` - Interactive debugging assistant (asks for problem description)
- `/ios-setup` (aliases: `/capabilities`, `/ios-capabilities`) - Configure iOS capabilities for push notifications and app groups
- `/ios-setup` (aliases: `/capabilities`, `/ios-capabilities`) - Configure iOS capabilities and Notification Service Extension (NSE)

#### Interactive Skills (5 commands)

Expand Down Expand Up @@ -380,32 +380,44 @@ Describe the problem: Events not appearing in Clix dashboard
[Provides fix with exact file location]
```

#### `/ios-setup` - iOS Setup & Capabilities Configuration
#### `/ios-setup` - iOS Setup, Capabilities & NSE Configuration

**Category:** Autonomous Command

**Aliases:** `/capabilities`, `/ios-capabilities`

**What it does:** Configures iOS capabilities required for the Clix SDK, specifically Push Notifications and App Groups.
**What it does:** Configures iOS capabilities and Notification Service Extension (NSE) required for the Clix SDK.

**Capabilities configured:**
- **Push Notifications** - Enables APNs communication (entitlement: `aps-environment`)
- **App Groups** - Enables data sharing between app and Notification Service Extension (entitlement: `com.apple.security.application-groups`, format: `group.clix.{BUNDLE_ID}`)
- **App Groups** - Enables data sharing between app and NSE (entitlement: `com.apple.security.application-groups`, format: `group.clix.{BUNDLE_ID}`)

**Notification Service Extension (NSE) setup:**
- **Target name:** `{AppName}NotificationServiceExtension` (consistent across all steps)
- **NotificationService.swift:** Uses `ClixNotificationServiceExtension` base class with `register(projectId:)` call
- **Dependency setup:** CocoaPods (`pod 'Clix'` in extension target) or SPM (add Clix package to extension)
- **Build settings:** `ENABLE_USER_SCRIPT_SANDBOXING = No` for Xcode 15+
- **React Native + Firebase:** Move "Embed Foundation Extensions" above "[RNFB] Core Configuration"

**Workflow:**
1. Analyzes iOS project structure (finds .xcodeproj/.xcworkspace)
2. Detects Bundle ID and checks current capabilities status
3. Creates/modifies entitlements files for main app and extension
4. Provides step-by-step instructions for Xcode configuration
5. Guides through Apple Developer Portal setup
6. Outputs verification report
4. Guides NSE target creation and NotificationService.swift implementation
5. Provides CocoaPods/SPM setup instructions for extension target
6. Provides step-by-step instructions for Xcode configuration
7. Guides through Apple Developer Portal setup
8. Outputs verification report

**What can be automated:**
- Creating/modifying entitlements files
- Reading project configuration

**What requires manual action:**
- Creating NSE target in Xcode (File > New > Target > Notification Service Extension)
- Adding capabilities in Xcode UI (Signing & Capabilities)
- Adding Clix SDK to extension target (Podfile or SPM)
- Configuring build settings for Xcode 15+
- Enabling capabilities in Apple Developer Portal
- Registering App Group IDs
- Regenerating provisioning profiles
Expand All @@ -420,12 +432,14 @@ App Groups: not configured

Creating entitlements files...
✓ Created MyApp.entitlements
✓ Created NotificationServiceExtension.entitlements
✓ Created MyAppNotificationServiceExtension.entitlements

Manual steps required in Xcode:
1. Add Push Notifications capability to main target
2. Add App Groups capability with ID: group.clix.com.example.myapp
3. Add same App Group to extension target
Manual steps required:
1. Create NSE target: MyAppNotificationServiceExtension
2. Implement NotificationService.swift with ClixNotificationServiceExtension
3. Add Clix SDK to extension (Podfile or SPM)
4. Add Push Notifications and App Groups capabilities
5. Set ENABLE_USER_SCRIPT_SANDBOXING to No (Xcode 15+)

{verification report JSON}
```
Expand Down Expand Up @@ -1254,7 +1268,7 @@ When helping users with Clix CLI, keep these points in mind:
- "SDK integration" → Use `/install` for autonomous installation or `/integration` skill for guided steps
- "iOS installation" → Detect: Package.swift (SPM, preferred), Podfile (CocoaPods), or suggest SPM for bare Xcode projects. SPM is the modern, recommended approach.
- "SPM/Swift Package Manager" → Guide through Package.swift modification or Xcode UI (File > Add Package Dependencies) for adding packages
- "iOS capabilities" → Use `/ios-setup` to configure Push Notifications and App Groups
- "iOS capabilities" → Use `/ios-setup` to configure Push Notifications, App Groups, and Notification Service Extension (NSE)
- "Event tracking" → Use `/event-tracking` skill (interactive, creates event plans)
- "User management" → Use `/user-management` skill (setUserId, properties, logout handling)
- "Personalization" → Use `/personalization` skill (Liquid templates for messages)
Expand Down
81 changes: 81 additions & 0 deletions src/lib/embedded-skills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,32 @@ Only these require user action:

For these, provide brief instructions but don't wait for confirmation.

### iOS Notification Service Extension (Recommended)

For rich push notifications (images, buttons), create a Notification Service Extension:

1. In Xcode: File > New > Target > Notification Service Extension
2. Add Clix SDK to the extension target:
- **CocoaPods**: Add \`target 'YourExtension' do pod 'Clix' end\` to Podfile, then \`pod install\`
- **SPM**: Add Clix package to extension target in Xcode (General > Frameworks)
3. Implement NotificationService.swift:
\`\`\`swift
import UserNotifications
import Clix

class NotificationService: ClixNotificationServiceExtension {
override func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
register(projectId: "YOUR_PROJECT_ID")
super.didReceive(request, withContentHandler: contentHandler)
}
}
\`\`\`
4. Add App Groups capability to both main app and extension (same group ID: \`group.clix.{BUNDLE_ID}\`)
5. For Xcode 15+: Set \`ENABLE_USER_SCRIPT_SANDBOXING\` to "No" in extension's Build Settings

For detailed setup, run \`clix ios-setup\` or \`/ios-setup\` in interactive mode.

## Output Format

After completion, report:
Expand Down Expand Up @@ -1486,6 +1512,61 @@ Create or modify entitlements files. Use Write/Edit tools for these operations.

**Note:** Replace \`{BUNDLE_ID}\` with the actual bundle identifier (e.g., \`com.example.myapp\`).

### Phase 3.5: Notification Service Extension Setup

Create a Notification Service Extension for rich push notifications (images, buttons, etc.).

**Create Extension Target in Xcode:**
\`\`\`text
1. File > New > Target
2. Select "Notification Service Extension"
3. Name it "{AppName}NotificationServiceExtension" (e.g., "MyAppNotificationServiceExtension")
4. Click "Finish" (Cancel the "Activate scheme" dialog)
5. Note: Use this exact name consistently in Podfile, entitlements path, and SPM setup
\`\`\`

**Implement NotificationService.swift:**

\`\`\`swift
import UserNotifications
import Clix

class NotificationService: ClixNotificationServiceExtension {
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
register(projectId: "YOUR_PROJECT_ID")
super.didReceive(request, withContentHandler: contentHandler)
}
}
\`\`\`

**Note:** Replace \`YOUR_PROJECT_ID\` with your actual Clix project ID from <https://console.clix.so/>

**Add Clix SDK to Extension Target:**

For CocoaPods projects, add to Podfile:
\`\`\`ruby
target '{AppName}NotificationServiceExtension' do
pod 'Clix'
end
\`\`\`
Then run: \`cd ios && pod install\`

For SPM projects in Xcode:
1. Select the extension target
2. Go to General > Frameworks, Libraries, and Embedded Content
3. Click + and add the Clix package

**Configure Build Settings (Xcode 15+):**

For the extension target:
- Set \`ENABLE_USER_SCRIPT_SANDBOXING\` to "No" in Build Settings

For React Native projects with Firebase:
- In Build Phases, move "Embed Foundation Extensions" above "[RNFB] Core Configuration"

### Phase 4: Apple Developer Portal Configuration

Guide user through manual portal configuration. These steps CANNOT be automated.
Expand Down
67 changes: 37 additions & 30 deletions src/lib/ios/agent-prompt-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ Modify the Xcode project file (.pbxproj) to link the entitlements file:

#### 2. Create Notification Service Extension [Required]
Create a new Notification Service Extension target for rich push notifications:
- Target name: \`${context.appName}NotificationServiceExtension\` or \`NotificationServiceExtension\`
- Bundle ID: \`${context.bundleId}.NotificationServiceExtension\`
- Target name: \`${context.appName}NotificationServiceExtension\`
- Bundle ID: \`${context.bundleId}.${context.appName}NotificationServiceExtension\`
- Deployment target: Same as main app or iOS 14.0+
- Create necessary files in the extension directory

Expand All @@ -53,41 +53,40 @@ Create the NotificationService.swift file with Clix SDK integration:

\`\`\`swift
import UserNotifications
import ClixSDK

class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
import Clix

class NotificationService: ClixNotificationServiceExtension {
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

if let bestAttemptContent = bestAttemptContent {
// Let Clix SDK handle the notification
Clix.shared.handleNotificationServiceExtension(
request: request,
content: bestAttemptContent
) { processedContent in
contentHandler(processedContent)
}
}
}

override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler,
let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
register(projectId: "YOUR_PROJECT_ID")
super.didReceive(request, withContentHandler: contentHandler)
}
}
\`\`\`

#### 4. Create Extension Entitlements [Required]
Create entitlements file for the extension at \`${context.iosDir}/NotificationServiceExtension/NotificationServiceExtension.entitlements\`:
**Note:** Replace \`YOUR_PROJECT_ID\` with your actual Clix project ID from https://console.clix.so/

#### 4. Add Clix SDK to Extension Target [Required]

**For CocoaPods projects:**
Add to your Podfile:
\`\`\`ruby
target '${context.appName}NotificationServiceExtension' do
pod 'Clix'
end
\`\`\`
Then run: \`cd ios && pod install\`

**For SPM projects:**
In Xcode:
1. Select the extension target
2. Go to General > Frameworks, Libraries, and Embedded Content
3. Click + and add the Clix package

#### 5. Create Extension Entitlements [Required]
Create entitlements file for the extension at \`${context.iosDir}/${context.appName}NotificationServiceExtension/${context.appName}NotificationServiceExtension.entitlements\`:

\`\`\`xml
<?xml version="1.0" encoding="UTF-8"?>
Expand All @@ -102,7 +101,7 @@ Create entitlements file for the extension at \`${context.iosDir}/NotificationSe
</plist>
\`\`\`

#### 5. Update Extension Info.plist [Required]
#### 6. Update Extension Info.plist [Required]
Ensure the extension's Info.plist has the correct NSExtension configuration:

\`\`\`xml
Expand All @@ -115,11 +114,19 @@ Ensure the extension's Info.plist has the correct NSExtension configuration:
</dict>
\`\`\`

#### 7. Configure Build Settings [Required - Xcode 15+]

For the extension target in Xcode:
- Set \`ENABLE_USER_SCRIPT_SANDBOXING\` to "No" in Build Settings

For React Native projects with Firebase:
- In Build Phases, move "Embed Foundation Extensions" above "[RNFB] Core Configuration"

### Important Notes
- The extension must share the same App Group as the main app
- The extension's bundle ID must be a child of the main app's bundle ID
- Add the ClixSDK to the extension target's frameworks
- Ensure the extension is added to the app's "Embed App Extensions" build phase
- Replace \`YOUR_PROJECT_ID\` with your actual Clix project ID

Please complete these tasks by modifying the Xcode project files directly.`;
}
Expand Down
26 changes: 26 additions & 0 deletions src/lib/skills/install/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,32 @@ Only these require user action:

For these, provide brief instructions but don't wait for confirmation.

### iOS Notification Service Extension (Recommended)

For rich push notifications (images, buttons), create a Notification Service Extension:

1. In Xcode: File > New > Target > Notification Service Extension
2. Add Clix SDK to the extension target:
- **CocoaPods**: Add `target 'YourExtension' do pod 'Clix' end` to Podfile, then `pod install`
- **SPM**: Add Clix package to extension target in Xcode (General > Frameworks)
3. Implement NotificationService.swift:
```swift
import UserNotifications
import Clix

class NotificationService: ClixNotificationServiceExtension {
override func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
register(projectId: "YOUR_PROJECT_ID")
super.didReceive(request, withContentHandler: contentHandler)
}
}
```
4. Add App Groups capability to both main app and extension (same group ID: `group.clix.{BUNDLE_ID}`)
5. For Xcode 15+: Set `ENABLE_USER_SCRIPT_SANDBOXING` to "No" in extension's Build Settings

For detailed setup, run `clix ios-setup` or `/ios-setup` in interactive mode.

## Output Format

After completion, report:
Expand Down
Loading