Help Lightning API Documentation / SDKs / Clients / iOS AI Agent Reference

iOS AI Agent Reference

This reference is for AI coding agents that help developers integrate or migrate to Help Lightning iOS SDK 26.5.3. Use it together with the iOS SDK guide.

Metadata

  • Audience: customer AI coding agents and application developers
  • SDK version: 26.5.3
  • Migration baseline: 17.x
  • Last verified: 2026-07-29
  • Human-readable integration guide: iOS SDK guide
  • Human-readable release note: iOS SDK 26.5.3
  • Current sample: SamplePresence

If this guide conflicts with the published SDK package or the current SamplePresence project, follow the published package and sample.

Supported integration scope

Generate code and guidance using these supported APIs:

  • HLClient
  • HLClientSwift
  • HLClientDelegate
  • The HLCallPluginDelegate callbacks actually forwarded by HLClient
  • HLCall
  • HLGenericCall
  • HLCallConfiguration
  • HLCallView
  • HLCallPiPView on iOS only
  • HLCallImmersiveSpace on visionOS only
  • HLSDKScreenSharing
  • HLScreenSharingBroadcastSampleHandler
  • Promise and FBLPromise where a documented plugin callback requires a Promise result

Do not use internal interfaces, implementation modules, or APIs that are not supported through HLClient.

Hard compatibility rule

SDK 26.5.3 is not interoperable with legacy client SDKs.

  • Every participant must use compatible current Web, Android, or iOS SDK releases.
  • A mixed deployment containing legacy client SDKs cannot place calls with iOS SDK 26.5.3.
  • Xamarin SDK 17.x is a legacy client and cannot participate in calls with iOS SDK 26.5.3.
  • Tell integrators to coordinate rollout across all client platforms before deploying 26.5.3.
  • This guide does not define exact compatible Web or Android version numbers. Confirm the current cross-platform release set with Help Lightning before approving a rollout.

Requirements

  • Xcode 16 or later with the Swift 6 toolchain; Swift 5 language mode remains supported
  • iOS 17.0 or later
  • visionOS 2.1 or later for native Vision Pro apps
  • visionOS 26 or later for the Logitech Muse measurement tool
  • A Help Lightning API key
  • An integration server that creates or retrieves call sessions

An application that must support iOS 16 or earlier cannot use SDK 26.5.3.

Information required before generating code

Ask the developer for:

  • UI stack: SwiftUI, UIKit with Swift, or UIKit with Objective-C
  • Application deployment target and Xcode version
  • Help Lightning data center used by the session
  • Existing integration-server session contract
  • Whether the app creates sessions, retrieves sessions by PIN, or both
  • Whether ReplayKit screen sharing is required
  • Whether call minimization is required
  • Whether a native visionOS target is required
  • Whether incoming push/CallKit flows are required

Do not select a data center, App Group, bundle identifier, API key, or cross-platform SDK version on the developer’s behalf.

Distribution

Use the binary Swift package:

https://github.com/VIPAAR/hlsdk-ios-spm.git

Pin the package to exact version 26.5.3.

Products and targets:

  • SwiftUI app: link HLSDKSwift
  • UIKit app written in Swift: link HLSDK and HLSDKSwift
  • UIKit app written in Objective-C: link HLSDK
  • ReplayKit broadcast extension: link HLSDKScreenSharing only

Every target linking one of these products must add -ObjC to Other Linker Flags. Never link HLSDKScreenSharing to the main app target.

A SwiftUI target links the HLSDKSwift product. Its source imports HLSDK for HLCall, HLCallConfiguration, and delegate types, and imports HLSDKSwift for HLClientSwift, HLCallView, HLCallPiPView, and HLCallImmersiveSpace. The HLSDKSwift product provides the required core SDK dependency.

The 17.x CocoaPods dependencies HLSDK, HLSDKSwift, and HLSDK/ScreenSharing are not the supported 26.5.3 distribution.

Session data and HLCall

The application must obtain these values from its Help Lightning integration-server flow before starting a call:

  • Session ID
  • Session token
  • User token
  • Call-service URL
  • Help Lightning API key
  • Local display name
  • Optional local avatar URL
  • Initial camera and microphone preferences

The ID, token, URL, API-key, display-name, and avatar values map to Swift String/Objective-C NSString. The media preferences are Boolean values. Token lifetime, refresh, and retry behavior belong to the customer integration-server contract and must be supplied by the developer.

Do not invent session values or copy credentials from a sample. Do not log tokens or commit real API keys to source control. The exact authentication and session endpoints are integration-specific; the endpoints in SamplePresence are a demo-server contract, not a required public application-server API.

Construct the call after validating the required values:

enum IntegrationError: Error {
    case invalidCallConfiguration
}

guard let call = HLCall(
    sessionId: sessionID,
    sessionToken: sessionToken,
    userToken: userToken,
    gssUrl: callServiceURL,
    helplightningAPIKey: apiKey,
    localUserDisplayName: displayName,
    localUserAvatarUrl: avatarURL,
    autoEnableCamera: cameraEnabled,
    autoEnableMicrophone: microphoneEnabled
) else {
    throw IntegrationError.invalidCallConfiguration
}

Objective-C:

HLCall *call =
    [[HLCall alloc]
        initWithSessionId:sessionID
        sessionToken:sessionToken
        userToken:userToken
        gssUrl:callServiceURL
        helplightningAPIKey:apiKey
        localUserDisplayName:displayName
        localUserAvatarUrl:avatarURL
        autoEnableCamera:cameraEnabled
        autoEnableMicrophone:microphoneEnabled];
if (call == nil) {
    // Report invalid call data to the host application.
    return;
}

Set the data center that corresponds to the session environment before creating HLCallConfiguration:

call.dataCenterID = kHLDataCenterID_US1

kHLDataCenterID_US1 is an example, not a universal default. If the session’s data center is unknown, stop and ask the developer or Help Lightning support.

Call presentation model

SDK 26.5.3 uses a SwiftUI-based call interface.

  • SwiftUI apps own presentation and add HLCallView to their view hierarchy.
  • UIKit and Objective-C apps supply a presenting view controller. The SDK presents and dismisses the SwiftUI-based call interface.
  • The legacy UIKit call screen is no longer available.
  • Use HLCallConfiguration for new and migrated integrations.
  • Existing UIKit call-start methods remain as compatibility wrappers.

SwiftUI

import HLSDK
import HLSDKSwift

call.dataCenterID = kHLDataCenterID_US1

guard let configuration =
    HLCallConfiguration.swiftUIConfiguration(with: call) else {
    return
}

try await HLClientSwift.shared.startCallAsync(
    configuration: configuration
)

Render while the call is active:

HLCallView()
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .ignoresSafeArea()

UIKit with Swift

import HLSDK
import HLSDKSwift

call.dataCenterID = kHLDataCenterID_US1

guard let configuration = HLCallConfiguration.uikitConfiguration(
    with: call,
    presenting: viewController
) else {
    return
}

try await HLClientSwift.shared.startCallAsync(
    configuration: configuration
)

UIKit with Objective-C

#import <HLSDK/HLSDK.h>

call.dataCenterID = kHLDataCenterID_US1;

HLCallConfiguration *configuration =
    [HLCallConfiguration
        uikitConfigurationWithCall:call
        presentingViewController:viewController];
if (configuration == nil) {
    // Report invalid call configuration to the host application.
    return;
}

FBLPromise *startPromise = [[HLClient sharedInstance]
    startCallWithConfiguration:configuration];

Observe startPromise with the then and catch handlers shown under “Client ownership, call state, and errors.”

Legacy compatibility API:

[[HLClient sharedInstance]
    startCall:call
    withPresentingViewController:viewController];

Swift concurrency

The native Swift async lifecycle APIs are:

try await HLClientSwift.shared.startCallAsync(
    configuration: configuration
)

try await HLClientSwift.shared.stopCurrentCallAsync()

Do not rewrite plugin delegate callbacks as Swift async methods. Plugin callbacks that return a result remain Promise-based in 26.5.3.

Client ownership, call state, and errors

Use the shared client instance. Assign its delegate before starting a call, and keep the delegate owner alive for the complete call. The client delegate is weak.

For Swift, use a main-actor coordinator and explicit host-application state:

import Observation

enum CallPhase: Equatable {
    case idle
    case starting
    case active
    case ended(String)
}

@Observable
@MainActor
final class CallCoordinator: NSObject, HLClientDelegate {
    var phase: CallPhase = .idle

    override init() {
        super.init()
        HLClientSwift.shared.delegate = self
    }

    func start(call: HLCall, presenting: UIViewController? = nil) async {
        guard phase != .starting, phase != .active else {
            return
        }
        phase = .starting
        let configuration: HLCallConfiguration
        if let presenting {
            guard let value = HLCallConfiguration.uikitConfiguration(
                with: call,
                presenting: presenting
            ) else {
                phase = .ended("Invalid UIKit call configuration")
                return
            }
            configuration = value
        } else {
            guard let value =
                HLCallConfiguration.swiftUIConfiguration(with: call)
            else {
                phase = .ended("Invalid SwiftUI call configuration")
                return
            }
            configuration = value
        }

        do {
            try await HLClientSwift.shared.startCallAsync(
                configuration: configuration
            )
            if phase == .starting {
                phase = .active
            }
        } catch {
            phase = .ended(error.localizedDescription)
        }
    }

    func stop() async {
        do {
            try await HLClientSwift.shared.stopCurrentCallAsync()
            phase = .idle
        } catch {
            phase = .ended(error.localizedDescription)
        }
    }

    nonisolated func hlCall(
        _ call: HLCall,
        didEndWithReason reason: String
    ) {
        Task { @MainActor in
            self.phase = .ended(reason)
        }
    }
}

Adapt observation to the application’s architecture. In SwiftUI, show HLCallView() only after the async start succeeds and the phase becomes active. Dismissing the host presentation while the call is active must call stopCurrentCallAsync() unless the call is being minimized into HLCallPiPView.

Objective-C must handle a nil configuration and the returned promise:

HLCallConfiguration *configuration =
    [HLCallConfiguration uikitConfigurationWithCall:call
                           presentingViewController:viewController];
if (configuration == nil) {
    // Report invalid call configuration to the host application.
    return;
}

FBLPromise *startPromise =
    [[HLClient sharedInstance]
        startCallWithConfiguration:configuration];

[startPromise then:^id _Nullable(id _Nullable value) {
        // Mark the call active in the host application.
        return nil;
    }].catch(^(NSError *error) {
    // Report the failure and restore the host application UI.
});

Do not discard thrown Swift errors or rejected Objective-C promises.

Delegate behavior

Continue assigning an HLClientDelegate. HLClientDelegate inherits from HLCallPluginDelegate, so one retained coordinator can implement the call-lifecycle and supported plugin callbacks below.

  • Use hlCall:didEndWithReason: instead of its deprecated predecessor.
  • Screen sharing still requires hlCallNeedScreenSharingInfo:.
  • The screen-sharing and call-minimization callback signatures shown below are unchanged from 17.x.
  • Quick Knowledge, knowledge-overlay, and captured-image callback signatures are unchanged from 17.x but are outside the core integration contract defined here.
  • For HLClient, the new supported plugin callback is hlCallCanSupportVisionOSMainCamera:.
  • Do not generate code for other new declarations in the shared plugin protocol; they are not forwarded by HLClient in 26.5.3.

Swift main-camera callback:

enum VisionCapabilities {
    // Change to true only in the approved, licensed visionOS target.
    static let mainCameraEnabled = false
}

nonisolated func hlCallCanSupportVisionOSMainCamera(
    _ call: any HLGenericCall
) -> Bool {
    VisionCapabilities.mainCameraEnabled
}

Return true only when the native visionOS app is signed with the approved main-camera entitlement and includes its Enterprise.license.

For HLClient integrations, use only the plugin callbacks described in this guide. Do not assume every declaration in a shared protocol is supported by HLClient.

Optional-flow boundaries

Once the customer supplies the session contract, data-center mapping, and platform identifiers listed above, this guide defines the client integration for creating or joining that server-provided session, presenting and ending its call, ReplayKit screen sharing, minimization, and the documented native visionOS features.

It does not define:

  • Incoming push-notification or CallKit registration
  • Customer integration-server authentication endpoints
  • Quick Knowledge payloads
  • Knowledge-overlay payloads
  • Captured-image storage or upload contracts

For one of these flows, preserve an existing working 17.x host implementation until its 26.5.3 contract has been verified against the current public headers and Help Lightning guidance. Do not infer a callback signature, payload key, endpoint, or authentication scheme from the feature name.

Screen sharing

  • Keep the ReplayKit broadcast upload extension.
  • Replace the CocoaPods screen-sharing dependency with the HLSDKScreenSharing package product.
  • The sample handler continues to inherit from HLScreenSharingBroadcastSampleHandler.
  • The app and extension must have matching App Group entitlements.
  • The extension must be embedded in the app.
  • hlCallNeedScreenSharingInfo: must return the App Group and current broadcast extension bundle identifier.
  • Both targets must include -ObjC.

Swift delegate:

nonisolated func hlCallNeedScreenSharingInfo(
    _ call: any HLGenericCall
) -> [String: Any] {
    [
        kHLCallPluginScreenSharingAppGroupName: appGroup,
        kHLCallPluginScreenSharingBroadcastExtensionBundleId:
            extensionBundleIdentifier
    ]
}

Objective-C delegate:

- (NSDictionary *)hlCallNeedScreenSharingInfo:
    (id<HLGenericCall>)call {
    return @{
        kHLCallPluginScreenSharingAppGroupName: appGroup,
        kHLCallPluginScreenSharingBroadcastExtensionBundleId:
            extensionBundleIdentifier
    };
}

Broadcast upload extension:

import ReplayKit
import HLSDKScreenSharing

final class SampleHandler: HLScreenSharingBroadcastSampleHandler {
    override func getAppGroupName() -> String {
        appGroup
    }
}

Replace appGroup and extensionBundleIdentifier with values from the customer project. The App Group returned by both the app delegate and the extension handler must be identical. A conventional arrangement is an extension bundle ID formed by appending .ScreenSharingExtension to the application bundle ID and an App Group formed by prefixing that extension ID with group., but preserve an existing valid identifier instead of renaming it without a migration plan.

For iOS call continuity, configure the main application for the audio and voip background modes. Provide customer-appropriate strings for NSCameraUsageDescription and NSMicrophoneUsageDescription, and verify the denial and later Settings-enabled permission paths. Verify entitlements, provisioning, extension embedding, and the ReplayKit flow on a physical device.

Call minimization

  • SwiftUI apps can display HLCallPiPView() while the call is minimized.
  • Keep the existing minimization delegate callbacks.
  • UIKit apps can continue using SDK-managed call presentation and the existing minimization flow.

For a SwiftUI iOS app, return Promise results from the unchanged plugin callbacks and let host state switch between HLCallView and HLCallPiPView. Place this state and these methods in the retained main-actor coordinator:

import Promises

var pipEnabled = false

private nonisolated func boolPromise(
    _ value: Bool
) -> FBLPromise<AnyObject> {
    Promise<AnyObject>(NSNumber(value: value)).asObjCPromise()
}

private nonisolated func updateHostPiPState(_ enabled: Bool) {
    Task { @MainActor in
        self.pipEnabled = enabled
    }
}

nonisolated func hlCall(
    _ call: any HLGenericCall,
    canMinimizeCallViewWithCallInfo callInfo: [String: Any]?
) -> FBLPromise<AnyObject>? {
    boolPromise(true)
}

nonisolated func hlCall(
    _ call: any HLGenericCall,
    didMinimizeCallViewWithCallInfo callInfo: [String: Any]?
) -> FBLPromise<AnyObject>? {
    updateHostPiPState(true)
    return boolPromise(true)
}

nonisolated func hlCall(
    _ call: any HLGenericCall,
    didRestoreCallViewWithCallInfo callInfo: [String: Any]?
) {
    updateHostPiPState(false)
}

updateHostPiPState is application code and must transfer UI-state changes to the main actor. Return false from the first callback on platforms or application flows that do not support minimization.

Theming

The SwiftUI-based call interface does not consume legacy HLTheme icon or color customization.

  • The binary Swift package does not expose the legacy theme object as a supported customer integration type.
  • Remove imports and code that construct or apply HLTheme or HLThemeManager.
  • Flag legacy per-icon or per-color branding requirements as unsupported and update related tests after the customer accepts the new SwiftUI call interface. This guide defines no replacement theming API.

Native Vision Pro integration

Distinguish these app types:

  • A native Vision Pro app has a visionOS target and uses the SwiftUI app lifecycle.
  • An iPad or iOS app can run on Vision Pro in compatibility mode, but the native visionOS setup below does not apply to it.

The native visionOS app must register:

import HLSDKSwift

var body: some Scene {
    WindowGroup {
        RootView()
    }

    #if os(visionOS)
    HLCallImmersiveSpace()
    #endif
}

Main camera and passthrough

These capabilities require Apple approval for enterprise APIs for visionOS.

The customer’s Apple Developer Program organization must request the required capabilities through Apple’s visionOS enterprise APIs process. For main-camera requirements, also follow Apple’s main-camera guidance.

Native visionOS app entitlement:

<key>com.apple.developer.arkit.main-camera-access.allow</key>
<true/>

ReplayKit broadcast extension entitlement:

<key>com.apple.developer.screen-capture.include-passthrough</key>
<true/>

Add the Apple-issued Enterprise.license to Copy Bundle Resources for both the native visionOS app target and its ReplayKit extension. Never commit this license to source control.

The app and extension must share an App Group. Test these capabilities on a physical Vision Pro using the approved signing profile.

Main-camera access is enabled only when the native app has the approved entitlement and license and its retained HLClientDelegate returns true from hlCallCanSupportVisionOSMainCamera:. Passthrough screen sharing is enabled through the ReplayKit extension entitlement, license, matching App Group, extension embedding, and screen-sharing delegate configuration; do not invent a separate SDK toggle.

Logitech Muse measurement tool

This feature requires visionOS 26 or later, a connected Logitech Muse, and local screen sharing.

There is no separate public HLClient enablement API documented for this tool. Once the native visionOS, screen-sharing, OS, and accessory requirements are satisfied, the SDK’s call interface supplies the measurement controls.

  • The primary button marks the start and end points.
  • The immersive view shows the points, connecting line, and distance.
  • Multiple completed measurements remain visible.
  • A short secondary-button press expands or collapses controls.
  • Holding the secondary button for two seconds captures the immersive view. HLClient delivers the captured image through hlCall:didCaptureScreen:shouldUploadImage:; the host application owns storage or upload.

Reliability changes in 26.5.3

  • Active calls recover after a temporary call-service connection loss.
  • Remote video no longer freezes when a web participant reconnects after using video zoom.

Unsupported or replaced items

  • Interoperation with legacy Web, Android, or iOS client SDKs
  • Legacy UIKit in-call screen
  • Legacy call-theme overrides on the SwiftUI interface
  • CocoaPods-based 17.x distribution and samples
  • iOS versions earlier than 17.0
  • visionOS versions earlier than 2.1 for native Vision Pro apps

Instructions for customer AI coding agents

When generating integration code or migration guidance:

  1. Ask whether the app uses SwiftUI, UIKit with Swift, or UIKit with Objective-C.
  2. Ask whether the app requires ReplayKit screen sharing, minimization, incoming push/CallKit handling, or native Vision Pro support.
  3. Lead with the cross-platform compatibility requirement when planning a 17.x migration.
  4. Do not approve deployment until the exact compatible Web, Android, and iOS releases have been confirmed.
  5. Use public product and API names exactly as shown in this guide.
  6. Prefer HLCallConfiguration and the Swift async lifecycle APIs for new code.
  7. Label older call-start methods as compatibility APIs, not the recommended integration path.
  8. Apply Vision Pro guidance only to native visionOS targets.
  9. Enforce the separate visionOS 26 requirement for Logitech Muse.
  10. Do not generate code using internal APIs, modules, or unsupported plugin callbacks.
  11. If a required capability is not covered here, direct the developer to Help Lightning support rather than inventing an API.

Verification checklist

  • Confirm every Web, Android, and iOS integration uses a compatible current release.
  • Confirm required session values come from the customer’s integration server and match the selected data center.
  • Build all app and ReplayKit extension targets in Debug and Release.
  • Test call creation failures, call-start errors, start, minimize, restore, remote end, local end, and reconnection.
  • If the product includes incoming calls, separately verify its approved push-notification and CallKit flow.
  • Test camera, microphone, speaker, and permissions.
  • Test screen sharing and App Group configuration on a physical device.
  • Verify any host-provided Quick Knowledge or plugin callbacks.
  • Confirm the new call UI has no dependency on legacy theming.
  • Test entitlement-dependent visionOS features on a physical Vision Pro with the approved profile and license.