iOS

The Help Lightning iOS SDK embeds Help Lightning calls in SwiftUI, UIKit, and Objective-C applications. This guide documents SDK 26.5.3.

SDK 26.5.3 is not compatible with legacy client SDKs. Before deploying, confirm that every participating Web, Android, and iOS integration uses a mutually compatible current release. Mixed calls between SDK 26.5.3 and legacy client SDKs are not supported. Xamarin SDK 17.x is also a legacy client and cannot participate in calls with SDK 26.5.3.

If you are upgrading from 17.x, read the iOS SDK 26.5.3 release note. The deprecated 17.x guide remains available only for applications that have not migrated.

If you use an AI coding agent to integrate or migrate the SDK, give it the iOS AI Agent Reference. That document is structured for machine retrieval and includes the supported public API surface, migration constraints, and verification checklist.

Requirements

  • Xcode 16 or later with the Swift 6 toolchain; Swift 5 language mode remains supported
  • iOS 17.0 or later
  • A Help Lightning API key
  • An integration server that creates or retrieves the call session
  • Compatible current client SDK releases for every call participant

Native Vision Pro applications require visionOS 2.1 or later and a SwiftUI app lifecycle.

The main application should include meaningful NSCameraUsageDescription and NSMicrophoneUsageDescription values. Enable the Audio and Voice over IP background modes for call continuity.

Install the SDK

SDK 26.5.3 is distributed as a binary Swift package. In Xcode, choose File > Add Package Dependencies and enter:

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

Pin the package to exact version 26.5.3.

Add products according to the target:

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

Do not link HLSDKScreenSharing to the main application target.

Every app or extension target that links a Help Lightning product must add -ObjC to Other Linker Flags for both Debug and Release.

SwiftUI source can import HLSDK for the core call types and HLSDKSwift for the Swift facade. Selecting the HLSDKSwift product also supplies its required core SDK dependency.

Obtain a call session

Before starting a call, obtain these values through your integration server:

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

The server authentication and session endpoints are specific to your integration. Do not copy credentials from a sample, commit production API keys, or log session tokens.

Create HLCall in Swift

import HLSDK

guard let call = HLCall(
    sessionId: sessionID,
    sessionToken: sessionToken,
    userToken: userToken,
    gssUrl: callServiceURL,
    helplightningAPIKey: apiKey,
    localUserDisplayName: displayName,
    localUserAvatarUrl: avatarURL,
    autoEnableCamera: cameraEnabled,
    autoEnableMicrophone: microphoneEnabled
) else {
    // Report invalid or incomplete call data.
    return
}

call.dataCenterID = kHLDataCenterID_US1

Use kHLDataCenterID_US1 for the US data center or kHLDataCenterID_EU1 for the EU data center, according to the session. Do not default to a different region.

Create HLCall in Objective-C

#import <HLSDK/HLSDK.h>

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 or incomplete call data.
    return;
}

call.dataCenterID = kHLDataCenterID_US1;

Configure the client delegate

Assign an HLClientDelegate before starting a call. The delegate is weak, so the application must retain its delegate owner for the entire call.

Swift:

import HLSDK
import HLSDKSwift

@MainActor
final class CallCoordinator: NSObject, HLClientDelegate {
    var callEndedHandler: ((String) -> Void)?

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

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

Objective-C:

@interface CallController () <HLClientDelegate>
@end

@implementation CallController

- (void)viewDidLoad {
    [super viewDidLoad];
    [HLClient sharedInstance].delegate = self;
}

- (void)hlCall:(HLCall *)call
    didEndWithReason:(NSString *)reason {
    dispatch_async(dispatch_get_main_queue(), ^{
        // Restore the host application UI.
    });
}

@end

Use hlCall:didEndWithReason: rather than its deprecated predecessor. The same delegate also supplies optional HLCallPluginDelegate callbacks such as screen-sharing configuration and call minimization.

Start and present a call

Use HLCallConfiguration to select the presentation model.

SwiftUI

The application owns call presentation. Create a SwiftUI configuration and start it through the async Swift facade:

import HLSDK
import HLSDKSwift

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

do {
    try await HLClientSwift.shared.startCallAsync(
        configuration: configuration
    )
    // Mark the call active and present HLCallView.
} catch {
    // Report the error and restore the host application UI.
}

Show the call view only after call start succeeds:

HLCallView()
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(Color.black)
    .ignoresSafeArea()

The host application owns presentation and dismissal. If the user dismisses the call without minimizing it, stop the call:

do {
    try await HLClientSwift.shared.stopCurrentCallAsync()
} catch {
    // Report or log the call-stop failure.
}

UIKit with Swift

Provide the view controller from which the SDK should present the call:

import HLSDK
import HLSDKSwift

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

do {
    try await HLClientSwift.shared.startCallAsync(
        configuration: configuration
    )
} catch {
    // Report the error and restore the host application UI.
}

The SDK presents and dismisses the SwiftUI-based call interface through UIKit.

UIKit with Objective-C

HLCallConfiguration *configuration =
    [HLCallConfiguration
        uikitConfigurationWithCall:call
        presentingViewController:viewController];

if (configuration == nil) {
    // Report an invalid call configuration.
    return;
}

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

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

The older startCall:withPresentingViewController: API remains available for source compatibility. New and migrated integrations should use HLCallConfiguration.

Optional integrations

Screen sharing

Screen sharing uses a ReplayKit broadcast upload extension, a shared App Group, and the HLSDKScreenSharing package product. Follow the iOS screen-sharing tutorial.

Call minimization

SwiftUI applications on iOS can show HLCallPiPView() while the SDK call is minimized. Implement the existing minimization delegate callbacks so the host application can switch between HLCallView and HLCallPiPView. This view is not available on visionOS.

UIKit applications can continue using SDK-managed presentation and the existing minimization delegate flow.

Native Vision Pro

This section applies only to applications with a native visionOS target. An iPad or iOS application can still run on Vision Pro in compatibility mode, but it does not use these native visionOS APIs.

Native Vision Pro integration requires:

  • visionOS 2.1 or later
  • A SwiftUI app lifecycle
  • HLCallImmersiveSpace registered by the application
  • A ReplayKit extension and shared App Group for screen sharing

Register the immersive scene

Register the SDK immersive scene in the SwiftUI app:

import HLSDKSwift

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

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

Request main-camera and passthrough access

Main-camera access and passthrough in screen capture use Apple’s enterprise APIs for visionOS. They are not available with a standard App Store distribution profile alone.

  1. Enroll in the Apple Developer Program as an organization.
  2. Request access to Apple’s enterprise APIs for visionOS. For main-camera details, also review Accessing the main camera.
  3. Request both capabilities:
    • Main Camera Access (com.apple.developer.arkit.main-camera-access.allow)
    • Passthrough in Screen Capture (com.apple.developer.screen-capture.include-passthrough)
  4. After approval, regenerate the required provisioning profiles.

Configure entitlements and the enterprise license

Add the Main Camera Access entitlement to the native visionOS app:

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

Add the Passthrough in Screen Capture entitlement to the visionOS ReplayKit extension:

<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 application target
  • Its ReplayKit broadcast upload extension

The license is private to the approved organization. Never commit it to source control.

The app and extension must share the same App Group, and the app must embed the extension. Follow the screen-sharing tutorial for the package, handler, App Group, and delegate setup.

Enable main-camera support

After the app has the approved entitlement, provisioning profile, and license, opt in through the retained HLClientDelegate:

nonisolated func hlCallCanSupportVisionOSMainCamera(
    _ call: any HLGenericCall
) -> Bool {
    true
}

Return false until all main-camera requirements are satisfied. Passthrough screen sharing is enabled by the extension entitlement, license, and normal screen-sharing configuration; there is no separate HLClient toggle.

Test main-camera access and passthrough on a physical Vision Pro using the approved signing profiles.

Logitech Muse measurement tool

The Logitech Muse measurement tool additionally requires visionOS 26 or later, a connected Muse, and local screen sharing. The SDK supplies the measurement controls; the host application does not enable them through a separate public API.

The primary Muse button marks the start and end points. The secondary button expands or collapses the controls; holding it for two seconds captures the immersive view. HLClient delivers the captured image through the existing hlCall:didCaptureScreen:shouldUploadImage: delegate callback; the host application owns storage or upload.

Legacy theming

The SwiftUI-based call interface does not support legacy HLTheme icon or color customizations. The binary Swift package does not expose the legacy theme object as a supported customer integration type.

Review the new in-call appearance with your product team, then remove imports and code that construct or apply HLTheme or HLThemeManager and update related tests.

Sample application

Use SamplePresence as the current integration reference. It provides separate targets for:

  • iOS SwiftUI
  • iOS UIKit with Swift
  • iOS UIKit with Objective-C
  • visionOS SwiftUI

The legacy SampleSwift and SampleObjC projects remain frozen at the 17.x CocoaPods integration.

For AI-assisted integrations, also use the iOS AI Agent Reference.

Verify the integration

Before release:

  • Confirm all participating client platforms use compatible releases
  • Build every app and ReplayKit extension target in Debug and Release
  • Test call creation failures, start, remote end, local end, and temporary network interruption
  • Verify camera, microphone, speaker, background modes, and permission handling on a physical iOS 17 or later device
  • Test minimization and restoration if supported by the application
  • Test the ReplayKit extension and App Group if screen sharing is enabled
  • Test native visionOS enterprise capabilities on a physical Vision Pro using the approved profile and license