--- name: pushengage-ios description: Use ONLY when the active repo is a native iOS app (Podfile, Package.swift, or *.xcodeproj present at the project root) AND there is NO `pubspec.yaml` with a `flutter:` SDK block AND NO `package.json` with `react-native` or `expo` dependency. Handles full PushEngage integration end-to-end, plus debugging existing integrations. Do not use for Android, Flutter, or React Native apps even if PushEngage is mentioned. license: MIT compatibility: Works with any agent that supports the Agent Skills (SKILL.md) standard, including Claude Code and Cowork. Needs filesystem read access and a shell to detect the project type; some steps fetch allowlisted documentation URLs. metadata: author: PushEngage version: "1.0.0" --- # PushEngage — iOS Spoke You're working in an iOS app. This skill walks the customer through integrating PushEngage from zero to verified test push, or debugs a broken integration. ## Routing | Customer intent | Read this file next | |---|---| | "Integrate PushEngage" / "Set up PushEngage" (greenfield or partial) | This file's "Integration flow" section below. | | "PushEngage isn't working" / specific symptom | Hand off to `pushengage-debug/SKILL.md` (skill: `pushengage-debug`). | | "Audit my PushEngage setup" | Read `audit-checks.md` and run the checks. | | Concept / terminology question | Read `../pushengage/concepts.md`. | | Best practices / rule lookup | Read `best-practices.md` (iOS-specific) or `../pushengage/best-practices.md` (cross-platform). | | API surface / "does method X exist" | Read `version-matrix.md` first; if not listed, fetch only URLs from `references.md`. | ## Integration flow (greenfield) This is the happy path. Follow the parts strictly in order — earlier artifacts feed later steps. ### Part 1 — Discovery & prereqs Before touching anything, gather: 1. iOS deployment target (read project file / `Podfile` `platform :ios, 'X.Y'`). 2. Package manager: SPM only / CocoaPods only / both / neither (look for `Podfile`, `Package.swift`, `Pods/`, SPM `Package.resolved`). 3. UI framework: UIKit (find `AppDelegate.swift`) or SwiftUI (find `@main struct` and `@UIApplicationDelegateAdaptor`). 4. Existence of any other SDK that swizzles `UIApplicationDelegate` (search for `FirebaseApp.configure`, `OneSignal.initialize`, `Branch.getInstance`, etc.). 5. Whether the customer already has a PushEngage account + site → ask the customer. Output a one-paragraph integration plan in chat. Wait for the customer to confirm before any edits. ### Part 2 — APNs + dashboard (out-of-code, before any code edits) Counter-intuitive but right: do these BEFORE editing code. The dashboard's App ID is needed for `setAppID(id:)`; APNs cert generation has a real-world wait at Apple Developer portal. 1. Read `provider-setup.md`. Walk the customer through APNs cert generation. Capture: `.p12` (the file lives with the customer, not us), `.p12` password (NEVER ask the customer to paste this in chat), Bundle Identifier. 2. Read `dashboard-setup.md`. Walk the customer through Site Settings → Installation → iOS SDK. Capture: App ID UUID (ask the customer to paste this in chat). Do not proceed to Part 3 until both steps confirm. ### Part 3 — In-code edits #### 3a — Install Read `install.md`. Choose SPM vs CocoaPods per the decision rule there. - **Auto-edit + announce posture:** Podfile, Package.swift dep additions. Show the diff in chat, apply. - Run `pod install` (CocoaPods path) and confirm success. #### 3b — Main target init code Read `init-code.md`. Pick the template by UI framework + integration mode: - Default = swizzling. Switch to manual only on IOS-BP-02 trigger (Firebase, policy, etc.). - Templates: Swift/UIKit, Swift/SwiftUI, Objective-C — swizzling and manual variants exist. **Diff + confirm posture for AppDelegate edits.** Show the proposed diff. Ask the customer "apply?" before writing. Insert the App ID UUID captured in Part 2. Also: - Enable Push Notifications capability — auto-edit + announce. - Background Modes (Remote notifications, Background fetch): only if the customer will use silent/background pushes — see IOS-BP-03. Don't enable it by default for alert-only integrations. - Insert Info.plist keys per `init-code.md` ("Info.plist additions" section). #### 3c — Notification Service Extension (NSE) Read `nse-setup.md`. Required for rich-media notifications and reliable analytics. Default: do this. NSE target creation: instruct the customer via Xcode UI (don't try to edit `.pbxproj` programmatically). NSE source file: replace contents with the template (auto-edit + announce; it's a freshly generated file). From `1.0.0`, the NSE target uses the **`PushEngageExtension`** pod/product and `import PushEngageExtension` (NOT `PushEngage`); the three NSE methods are called on the `PushEngageExtension` class. App Groups setup is part of this — both main app and NSE target must share a group, and both Info.plists need `PushEngage_App_Group_Key`. #### 3d — Notification Content Extension (NCE) — OPTIONAL Read `nce-setup.md` only if the customer explicitly asks for custom expanded UI. Default: skip; mention it exists; ask if they want it. From `1.0.0`, the NCE target also uses the **`PushEngageExtension`** pod/product and `import PushEngageExtension`; `getCustomUIPayLoad(for:)` is called on the `PushEngageExtension` class. ### Part 4 — Verification The success criterion is **a real test notification reaches the customer's device**. 1. Customer connects a real device (NOT simulator — APNs requires real device). 2. Customer launches the app once → grants notification permission when prompted. 3. Customer goes to PushEngage dashboard → Campaign → Push Broadcasts → Create New Push Broadcast → fills minimal fields → sends to the test device. 4. Ask the customer: "Did the notification arrive?" **If yes** → go to Part 5. **If no** → hand off to `pushengage-debug/SKILL.md` with the symptom "test push didn't arrive." ### Part 5 — Post-integration best-practices nudge Single short message. Don't auto-apply; list rule IDs and one-line summaries: - XP-BP-01: move the App ID UUID out of source (you currently have it hardcoded). - XP-BP-02: consider a second PushEngage site for test/QA traffic. - XP-BP-03: request notification permission at a meaningful user moment, not on launch. - XP-BP-07: ensure `enableLogging` is gated by `#if DEBUG`. (Customize the list to what you actually saw in the customer's code — don't dump all of them if some don't apply.) ## Debugging entry points If the customer says any of the following — or if Part 4 verification fails — invoke `pushengage-debug/SKILL.md`: - "Notifications aren't arriving" - "Permission dialog never shows" / "always returns true immediately" - "Deep link is broken" - "Subscriber count looks wrong" / "I'm not registering as a subscriber" - "App crashes on launch after install" - "Build fails" The debug skill handles audit + known-issues + symptom tree. ## What you must not do - Don't invent PushEngage method names. If you're not sure a method exists, check `version-matrix.md`. If still unsure, fetch an allowlisted URL from `references.md`. If still unsure, say so. - Don't auto-edit AppDelegate without showing the diff and getting confirmation (entry-point code is diff + confirm). - Don't touch files outside the integration scope. No refactoring, no Swift-version migrations, no formatting passes. - Don't fetch URLs not in `references.md`. - Don't ask the customer for the `.p12` private key password in chat — they enter it directly on the dashboard.