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.
- 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.
Generate code and guidance using these supported APIs:
HLClientHLClientSwiftHLClientDelegate- The
HLCallPluginDelegatecallbacks actually forwarded byHLClient HLCallHLGenericCallHLCallConfigurationHLCallViewHLCallPiPViewon iOS onlyHLCallImmersiveSpaceon visionOS onlyHLSDKScreenSharingHLScreenSharingBroadcastSampleHandlerPromiseandFBLPromisewhere a documented plugin callback requires a Promise result
Do not use internal interfaces, implementation modules, or APIs that
are not supported through HLClient.
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.
- 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.
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.
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
HLSDKandHLSDKSwift - UIKit app written in Objective-C: link
HLSDK - ReplayKit broadcast extension: link
HLSDKScreenSharingonly
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.
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.
SDK 26.5.3 uses a SwiftUI-based call interface.
- SwiftUI apps own presentation and add
HLCallViewto 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
HLCallConfigurationfor new and migrated integrations. - Existing UIKit call-start methods remain as compatibility wrappers.
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()
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
)
#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];
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.
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.
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 ishlCallCanSupportVisionOSMainCamera:. - Do not generate code for other new declarations in the shared plugin
protocol; they are not forwarded by
HLClientin 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.
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.
- Keep the ReplayKit broadcast upload extension.
- Replace the CocoaPods screen-sharing dependency with the
HLSDKScreenSharingpackage 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.
- 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.
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
HLThemeorHLThemeManager. - 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.
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
}
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.
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.
HLClientdelivers the captured image throughhlCall:didCaptureScreen:shouldUploadImage:; the host application owns storage or upload.
- Active calls recover after a temporary call-service connection loss.
- Remote video no longer freezes when a web participant reconnects after using video zoom.
- 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
When generating integration code or migration guidance:
- Ask whether the app uses SwiftUI, UIKit with Swift, or UIKit with Objective-C.
- Ask whether the app requires ReplayKit screen sharing, minimization, incoming push/CallKit handling, or native Vision Pro support.
- Lead with the cross-platform compatibility requirement when planning a 17.x migration.
- Do not approve deployment until the exact compatible Web, Android, and iOS releases have been confirmed.
- Use public product and API names exactly as shown in this guide.
- Prefer
HLCallConfigurationand the Swift async lifecycle APIs for new code. - Label older call-start methods as compatibility APIs, not the recommended integration path.
- Apply Vision Pro guidance only to native visionOS targets.
- Enforce the separate visionOS 26 requirement for Logitech Muse.
- Do not generate code using internal APIs, modules, or unsupported plugin callbacks.
- If a required capability is not covered here, direct the developer to Help Lightning support rather than inventing an API.
- 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.