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.
- 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.
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:
HLSDKandHLSDKSwift - UIKit app written in Objective-C:
HLSDK - ReplayKit broadcast upload extension:
HLSDKScreenSharingonly
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.
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.
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.
#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;
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.
Use HLCallConfiguration to select the presentation model.
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.
}
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.
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.
Screen sharing uses a ReplayKit broadcast upload extension, a shared
App Group, and the HLSDKScreenSharing package product. Follow the
iOS screen-sharing tutorial.
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.
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
HLCallImmersiveSpaceregistered by the application- A ReplayKit extension and shared App Group for screen sharing
Register the SDK immersive scene in the SwiftUI app:
import HLSDKSwift
var body: some Scene {
WindowGroup {
RootView()
}
#if os(visionOS)
HLCallImmersiveSpace()
#endif
}
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.
- Enroll in the Apple Developer Program as an organization.
- Request access to Apple’s enterprise APIs for visionOS. For main-camera details, also review Accessing the main camera.
- 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)
- Main Camera Access
(
- After approval, regenerate the required provisioning profiles.
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.
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.
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.
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.
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.
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