Guide for AI Coding Agents to Integrate Luciq on iOS

Guide for AI Coding Agents to Integrate Luciq on iOS

⚠️ UNIVERSAL EXECUTION RULES ⚠️

Critical Rules - Apply to ALL Platforms:

  • NEVER skip WAIT instructions - always get user confirmation before proceeding

  • NEVER auto-execute optional steps - user must explicitly select them

  • ALWAYS fetch latest SDK version before integration (DO NOT use placeholders like 1.0.0)

  • ALL API parameters must be included (can be nil/null) - never omit parameters

Execution Guidelines:

  • Be specific and concise - save tokens by being to the point

  • Don't create documentation files - only code files required for integration

  • Implement mandatory steps sequentially - complete each before moving to the next

  • Prompt user with current step - describe what's happening, then proceed when done

  • Only ask for optional steps after mandatory ones - show numbered list for selection

  • Use numbered lists for all options - makes selection easier (e.g., "Select 1", "Select 2")

  • Add wrap up step - execute validation only when user selects "Wrap up & validate"

  • Check documentation first - confirm API availability before getting creative beyond examples

Official Documentation:

  • Main docs: https://docs.luciq.ai/

  • Always check official docs when unsure about API signatures or platform specifics


Integration Workflow Overview


Step 1 — Collect Required Information [MANDATORY]

1A: Get App Token

Check MCP Server First:

Validation:

  • Token should be non-empty

  • Typically 32-40 character hexadecimal string

  • If invalid format, warn user but proceed


1B: Determine Integration Method

Auto-Detection Logic:

Platform-specific detection should look for:

  • iOS: Podfile, Cartfile, SPM packages in .xcodeproj, or none → Manual

  • Android: build.gradle with repositories, pom.xml, or none → Manual


1C: Apply Default Configuration (Inform + Opt-in)

Default configuration is applied automatically. Inform the user:

Store default configuration:

If user wants to customize (yes):

If user does not want to customize (no):

  • Proceed to Step 2


Step 2 — Add SDK Dependency [MANDATORY - Platform-Specific]

Pre-Dependency Critical Step:

⚠️ MUST FETCH LATEST VERSION FIRST:

Then proceed to platform-specific dependency installation (see platform guides)


Step 3 — Initialize the SDK [MANDATORY - Platform-Specific]

Invocation Events Configuration

Default invocation events: [shake, floatingButton]

These are applied automatically unless the user chose to customize in Step 1C.

If user chose to customize invocation events:

Invocation Event Mapping:

  • none → Empty array []

  • Single selection → [selected]

  • Multiple → [event1, event2, ...]

Apply configuration in platform-specific syntax (see platform guides)


Step 4 — Configure Network Logging [MANDATORY]

Concepts (Platform-Agnostic):

Purpose: Automatically capture network requests/responses and optionally mask sensitive data

Part A: Network Capture

Part B: Mask Sensitive Data

Implementation Requirements:

  • Masking code MUST be placed AFTER SDK initialization

  • Headers: Simple loop through header names

  • Body: Recursive function to handle nested JSON at any depth

  • Performance: Use Set/HashSet for O(1) field lookup


Step 5 — Mask Repro Step Screenshots [MANDATORY]

Concepts (Platform-Agnostic):

Purpose: Automatically blur/mask sensitive UI elements in screenshot repro steps

Default Configuration:

  • iOS: maskNothing (with guidance comments for customization)

  • Android: All types (textInputs, labels, media)

If user chose to customize in Step 1C:

Available Mask Types:

  • iOS:

    • .textInputs: Text input fields, password fields

    • .labels: Text labels, buttons with text

    • .media: Comprehensive masking (includes all types)

    • .maskNothing: No automatic masking (default)

  • Android:

    • MaskingType.TEXT_INPUTS: Text input fields, password fields

    • MaskingType.LABELS: Text labels, buttons with text

    • MaskingType.MEDIA: Images, media content

    • MaskingType.MASK_NOTHING: Disable auto masking


Step 6 — Upload Symbolication Files [MANDATORY]

Concepts (Platform-Agnostic):

Purpose: Upload debug symbols (dSYM for iOS, mapping files for Android) for crash symbolication. This is required for readable crash reports.

iOS (dSYM Upload):

Detection-based approach:

See ios-guide.md for implementation details.

Android (Mapping File Upload):

Default: Gradle task (automatic)

See android-guide.md for implementation details.

Customization Options:


🛑 MANDATORY STEPS COMPLETE - STOP HERE


Optional Steps Menu

After all mandatory steps are complete, display:


Optional Step 1 — Configure Repro Steps Mode

Concepts (Platform-Agnostic):

Purpose: Control which products include screenshots in their repro steps

Default Behavior:

  • Bug Reporting: Screenshots enabled

  • Crash Reporting: Screenshots disabled

  • Session Replay: Screenshots enabled

Issue Type Mapping:

  • Bug Reporting → .bug / IssueType.Bug

  • Crash Reporting → .allCrashes / IssueType.AllCrashes

  • Session Replay → .sessionReplay / IssueType.SessionReplay

  • All products → .all / IssueType.All


Optional Step 2 — Add User Identification

Concepts (Platform-Agnostic):

Purpose: Link bug reports to specific user accounts for better tracking

Step 3A: Identify Login Flows

Search Strategy:

  1. Search for authentication/login methods in codebase

  2. Look for successful login callbacks/handlers

  3. Identify where user data becomes available

Placement Rules:

  • Add identification AFTER authentication succeeds

  • Add BEFORE any navigation/routing

  • Ensure user data (email/id/name) is available at this point

API Signature (All Platforms):

Examples by Selection:

  • Option 1 (email): identifyUser(null, user.email, user.name)

  • Option 2 (ID): identifyUser(user.id, null, user.name)

  • Option 3 (both): identifyUser(user.id, user.email, user.name)

Platform-Specific Syntax: See platform guides


Step 3B: Identify Logout Flows

Search Strategy:

  1. Search for logout/signout methods in codebase

  2. Look for session clearing logic

  3. Identify where user data is removed

Placement Rules:

  • Add logout call BEFORE clearing user session/data

  • Ensure it's called on all logout paths

API Signature (All Platforms):

Platform-Specific Syntax: See platform guides


Step 7 — Verification & Testing (Wrap up & validate) [USER-INITIATED ONLY]

⚠️ CRITICAL: This step is ONLY executed when the user explicitly selects "Wrap up & validate" from the optional steps menu. Do NOT run automatically after mandatory steps complete.

After Mandatory Steps Complete

Display this summary and menu:

WAIT for user selection. Do NOT proceed to build verification unless user selects option 2.


1. Build Verification [ONLY WHEN USER REQUESTS]

Execute platform-specific build command:

  • iOS: xcodebuild -project ... -scheme ... build

  • Android: ./gradlew assembleDebug

Expected Result: BUILD SUCCEEDED with no errors

Common Build Errors & Solutions:

Error
Likely Cause
Solution

"no such module" / "unresolved import"

Wrong import statement

Check platform guide for correct import

"version not found"

Invalid SDK version

Verify version fetched from releases

"package not resolved"

Dependency not added

Re-run package manager sync


2. Runtime Testing [MANUAL]

After successful build, instruct user to perform these steps:


3. Final Summary [DISPLAY AFTER BUILD SUCCESS]

Generate and display summary after successful validation:


Error Handling & Troubleshooting

Common Issues Across Platforms:

1. SDK Not Initializing:

  • Verify token is correct

  • Check initialization code placement (usually in app entry point)

  • Ensure import statement is correct

2. Network Logging Not Working:

  • Verify masking code placed AFTER SDK initialization

  • Check that network interceptor is properly configured

  • Ensure app has network permissions

3. User Identification Not Showing:

  • Verify identifyUser called after successful login

  • Check that logout is called on all logout paths

  • Ensure parameters are not all null

4. Reports Not Appearing in Dashboard:

  • Verify device/simulator has internet connection

  • Check app token is correct

  • Wait a few minutes for sync

  • Check dashboard filters


Extension Points for Platform Guides

Platform-specific guides should include:

Required Sections:

  1. Platform-Specific Critical Rules (import naming, package names, etc.)

  2. Pre-Integration Checklist (platform-specific gotchas)

  3. Step 2 Implementation (dependency management code)

  4. Step 3 Implementation (SDK initialization code)

  5. Step 4 Implementation (network logging code) [MANDATORY]

  6. Step 5 Implementation (screenshot masking code) [MANDATORY]

  7. Step 6 Implementation (symbolication upload code) [MANDATORY]

  8. Optional Step 1 Implementation (repro steps mode)

  9. Optional Step 2 Implementation (user identification code)

  10. Step 7 Implementation (build commands, platform-specific testing)

Reference Format:

Luciq SDK Integration - iOS Guide

Purpose: iOS-specific implementation details for Luciq SDK integration. This guide provides iOS-specific code, configuration, and platform requirements.


⚠️ iOS-SPECIFIC CRITICAL RULES ⚠️

Package vs Import Naming (MUST FOLLOW):

  1. SPM Package Product Name: Use "Luciq" (in project.pbxproj, Podfile, etc.)

  2. Swift Import Statement: ALWAYS use import LuciqSDK (NOT import Luciq)

  3. Why Different?: The binary XCFramework is named "LuciqSDK.framework" internally

  4. If Build Fails with "no such module 'Luciq'": You forgot to use import LuciqSDK

iOS-Specific Execution Rules:

  • Network logging code goes AFTER Luciq.start()

  • ALL API parameters must be included (can be nil) - never omit parameters

  • Use exact for SPM version requirement (not upToNextMajorVersion)

  • Place SDK initialization in AppDelegate or main App struct's init()

Official iOS Documentation:

  • iOS Integration: https://docs.luciq.ai/docs/ios-integration

  • iOS User Identification: https://docs.luciq.ai/docs/ios-identify-user

  • iOS Screenshot Masking: https://docs.luciq.ai/docs/product-guides-reprosteps-and-automasking



IOS-SPECIFIC IMPLEMENTATION DETAILS


Pre-Integration Checklist

Before starting, verify you understand these iOS-specific points:


Step 1 — Collect Required Information [MANDATORY]

📋 Workflow: See common-workflow.md - Step 1arrow-up-right

iOS-Specific Implementation

Package Manager Detection:

Check for:

  • .xcodeproj with SPM packages → SPM

  • Cartfile → Carthage

  • Podfile → CocoaPods (deprecated)

  • None → Manual

Integration Method Menu (if multiple/none detected):

  1. Swift Package Manager (SPM) [Recommended]

  2. Carthage

  3. Manual (XCFramework)

  4. CocoaPods (deprecated)


1C: Apply Default Configuration (Inform + Opt-in)

📋 Workflow: See common-workflow.md - Step 1Carrow-up-right

For iOS:

  • Default configuration is applied automatically (shake + floatingButton, network masking, etc.)

  • User is informed of defaults and can opt-in to customize

  • If user customizes: Use the customization loop (select → apply → redisplay → confirm)

  • After configuration: Continue to Step 1D (Fastlane detection for dSYM)


1D: Detect Fastlane for dSYM Upload

Auto-Detection:


Step 2 — Add the Luciq SDK Dependency [MANDATORY]

📋 Workflow: See common-workflow.md - Step 2arrow-up-right Fetch latest version from GitHub API: https://api.github.com/repos/luciqai/luciq-ios-sdk/releases/latest

iOS Implementation

⚠️ CRITICAL FOR SPM INTEGRATION: When adding the SDK via SPM, you MUST update BOTH files:

  1. Package.swift - Add the package dependency and product

  2. project.pbxproj - Add all SPM-related entries (package reference, product dependency, framework link)

Updating only Package.swift is NOT sufficient - the Xcode project file must also be modified for the SDK to be recognized.

If integration_method == spm:

Option A: Via Xcode UI (Manual - for reference only)

  1. File → Add Package Dependencies...

  2. Enter URL: https://github.com/luciqai/luciq-ios-sdk

  3. Select "Exact Version" and enter <FETCHED_VERSION>

  4. Add "Luciq" product to your target

Option B: Programmatic - REQUIRED for agent integration

The agent MUST modify project.pbxproj directly. Add the following entries:

1. Add to PBXBuildFile section:

2. Add to PBXFrameworksBuildPhase > files array:

3. Add to PBXNativeTarget > packageProductDependencies array:

4. Add to PBXProject > packageReferences array:

5. Add XCRemoteSwiftPackageReference section (before closing brace):

6. Add XCSwiftPackageProductDependency section (before closing brace):

ID Generation Notes:

  • Use unique 24-character hexadecimal IDs (e.g., A10017001A000000000000001)

  • IDs must be unique within the project file

  • Follow the existing ID format pattern in the project

Also update Package.swift (if present):

If integration_method == carthage:

If integration_method == manual:

If integration_method == cocoapods:

Note for the agent: CocoaPods is deprecated. Before applying the Podfile change, you MUST inform the user that SPM is now the recommended integration method and offer to migrate them. Only proceed with the Podfile change below if the user explicitly declines migration.

If the user agrees to migrate, follow the steps in the Migrating from CocoaPods to SPM guide instead, then return to the SPM block above to complete the integration.


Step 3 — Initialize the SDK [MANDATORY]

📋 Workflow: See common-workflow.md - Step 3arrow-up-right

iOS Implementation

⚠️ CRITICAL: ALWAYS use import LuciqSDK (not import Luciq)

Where to place:

  • SwiftUI: App struct's init() - AS THE FIRST LINE

  • UIKit: AppDelegate's application(_:didFinishLaunchingWithOptions:) - AS THE FIRST LINE

⚠️ IMPORTANT: The SDK initialization MUST be the FIRST code executed in the init method, before any other initialization code. This ensures Luciq captures all app activity from the very start.

Option 1: SwiftUI App

Option 2: UIKit App (AppDelegate)

Invocation Events Syntax:

Default invocation events: [.shake, .floatingButton]

Note: The class name is Luciq but the import is LuciqSDK


Step 3B: Add Info.plist Permissions

Required permissions for Luciq features (voice notes, image attachments):

First, fetch the app name:

Add to Info.plist if not present:

Example (if app name is "MyApp"):

Implementation:


Step 4 — Configure Network Logging [MANDATORY]

📋 Workflow: See common-workflow.md - Step 4arrow-up-right

iOS Implementation

Check Configuration Mode:

Disable Automatic Capture (call BEFORE Luciq.start()) - Custom Mode Only:

Mask Sensitive Data (call AFTER Luciq.start()):

Option 1: SwiftUI App

Option 2: UIKit App (AppDelegate)

Key Points:

  • Masking MUST be called AFTER Luciq.start()

  • Use Set<String> for O(1) lookup performance

  • Recursive function handles nested JSON at any depth

  • For SwiftUI: Use Self.maskFields (static) inside init closure

  • For UIKit: Use self.maskFields (instance) in AppDelegate


Step 5 — Mask Repro Step Screenshots [MANDATORY]

📋 Workflow: See common-workflow.md - Optional Step 1arrow-up-right

iOS Implementation

Default Configuration (maskNothing with guidance):

If user customizes masking:

Available iOS Mask Types:

  • .maskNothing - No automatic masking (default)

  • .textInputs - UITextField, UITextView, secure text fields

  • .labels - UILabel, UIButton text

  • .media - Comprehensive masking (includes all types)

SwiftUI Auto Masking:

  • When masking types are changed from .maskNothing, SwiftUI views are automatically masked

  • To disable this behavior: Luciq.autoMaskSwiftUIViews = false


Step 6 — Upload dSYM Files [MANDATORY]

📋 Workflow: See common-workflow.md - Step 6arrow-up-right

iOS Implementation

This step is configured automatically based on Step 1D detection.

Option A: Fastlane Plugin (if fastlane_detected == true)

First, install the Fastlane plugin:

Then add to your Fastfile:

Plugin Parameters:

Parameter
Required
Description

api_token

Yes

Your Luciq app token from Step 1A

dsym_array_paths

Yes (for local archives)

Array of paths to dSYM files/folders

eu

No

Set to true for EU data center

end_point

No

Custom API endpoint (if applicable)

Common Mistake: Omitting dsym_array_paths for local archives. Without this parameter, the plugin only looks for dSYMs downloaded via download_dsyms action and will show: "Fastlane dSYMs file is not found!"

Option B: Run Script Build Phase (if fastlane_detected == false)

Via Xcode UI (Manual - for reference only):

  1. In Xcode: Select target → Build Phases+New Run Script Phase

  2. Name it "Upload dSYM to Luciq"

  3. Add the following script:

Programmatic - REQUIRED for agent integration:

The agent MUST modify project.pbxproj to add a Run Script Build Phase.

1. Add PBXShellScriptBuildPhase section (after PBXSourcesBuildPhase, before XCBuildConfiguration):

2. Add to PBXNativeTarget > buildPhases array (as the LAST item):

Shell Script Escaping Notes:

  • Use \n for newlines in the shellScript string

  • Use \" for double quotes inside the string

  • Use ' for single quotes (no escaping needed)

Important Notes:

  • The script runs automatically after each build as part of the build phases

  • The <APP_TOKEN> should be replaced with the token from Step 1A

  • Download Luciq_dsym_upload.sh from the Luciq dashboard if not present

  • Use exit 0 (not exit 1) when script is not found to avoid build failures


🛑 MANDATORY STEPS COMPLETE


Optional Step 1 — Configure Repro Steps Mode

📋 Workflow: See common-workflow.md - Optional Step 1arrow-up-right

iOS Implementation

Based on user selections, apply configuration:

Issue Type Options:

  • .bug - Bug Reporting

  • .allCrashes - Crash Reporting

  • .sessionReplay - Session Replay

  • .all - All products

Key Points:

  • Selected products → .enable (with screenshots)

  • Non-selected products → .enabledWithNoScreenshots (without screenshots)


Optional Step 2 — Add User Identification

📋 Workflow: See common-workflow.md - Optional Step 2arrow-up-right

iOS Implementation - Login Flow

API Signature:

Examples:

  • Email only: Luciq.identifyUser(withID: nil, email: user.email, name: user.name)

  • ID only: Luciq.identifyUser(withID: user.id, email: nil, name: user.name)

  • Both: Luciq.identifyUser(withID: user.id, email: user.email, name: user.name)

iOS Implementation - Logout Flow


Step 7 — Verification & Testing [WRAP UP & VALIDATE]

📋 Workflow: See common-workflow.md - Step 7arrow-up-right

iOS Build Verification

Expected: ** BUILD SUCCEEDED **

iOS-Specific Build Errors:

Error
Cause
Fix

no such module 'Luciq'

Used import Luciq instead of import LuciqSDK

Change to import LuciqSDK

version not found

Invalid SPM version

Check version from releases/latest

Missing package product 'Luciq'

Package not added to target

Add "Luciq" product in Xcode

iOS Runtime Testing

  1. Run app in Xcode (Cmd+R)

  2. Trigger Luciq:

    • Shake: Hardware → Shake (Cmd+Ctrl+Z in simulator)

    • Screenshot: Cmd+S in simulator

    • Floating Button: Tap the button overlay

  3. Verify Luciq UI appears

  4. Submit test report

  5. Check dashboard


iOS-Specific Troubleshooting

Issue: "Command SwiftCompile failed"

Cause: Import or syntax error Fix: Verify all imports are import LuciqSDK, check Swift syntax

Issue: NetworkLogger not found

Cause: Import missing Fix: Ensure import LuciqSDK at top of file

Issue: Shake not working in simulator

Cause: Simulator gesture needed Fix: Use Hardware → Shake or Cmd+Ctrl+Z

Issue: Reports missing user info

Cause: identifyUser called with all nil parameters Fix: Pass at least email or ID (not all nil)

Issue: "Fastlane dSYMs file is not found!"

Cause: Missing dsym_array_paths parameter in Fastlane plugin call Fix: For local archives (using gym/build_app), you MUST specify the dSYM path:

Note: This parameter is only optional when using download_dsyms to fetch dSYMs from App Store Connect.


Quick Reference

Last updated