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:

  • Podfile → CocoaPods

  • Cartfile → Carthage

  • .xcodeproj with SPM packages → SPM

  • None → Manual

Integration Method Menu (if multiple/none detected):

  1. Swift Package Manager (SPM) [Recommended]

  2. CocoaPods

  3. Carthage

  4. Manual (XCFramework)


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 == cocoapods:

If integration_method == carthage:

If integration_method == manual:


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