Integrating the SDK into your application
This guide provides a quick reference for integrating the Cognitive3D Analytics SDK into a visionOS application.
Note: Scene and Dynamic Object (meshes, textures) uploads to the Cognitive3D platform is currently a manual process. Reach out to the team via Intercom or Discord for help setting up your Scenes and Dynamic Objects. Our roadmap includes a GUI tool to make uploading these easy and straightforward.
Using the Cognitive3D Analytics SDK
You hae a choice of how to use the analytics SDK with your application:
- as a framework as a Swift package
- as soure code
As a framework
The framework will work on device and in the visionOS simulator.
- copy the framework and Swift.package file into a subfolder
- add the framework as a local Swift package
As source code
You can use the analytics directly in your project as source code.
- create a workspace
-
add your visionOS project to the workspace
-
add the analytics project into the workspace
- add the analytics code as a dependancy in your project
Import the framework
import Cognitive3DAnalytics
Initial setup in your application
Initialize the SDK at app startup
// In your App struct's init method
init() {
// Initialize the C3D SDK when app starts up
cognitiveSDKInit()
}
Configure the SDK
The sceneName
, sceneId
, versionNumber
, and versionId
for a scene in your application can be found on the Scene page for your Project on the Cognitive3D dashboard. Hover over the information icon next to the Media button.
The APPLICATION_API_KEY
can be found or reset on the Organization Settings page for your project on the Cognitive3D dashboard.
Important: Never store the APPLICATION_API_KEY in your source code directly, and we strongly recommend not storing it in your source control system, like a git repository. The Application Key is what your application uses to allow the Cognitive3D SDK to communicate with the analytics data pipeline and is unique to your application / project.
TODO: Where do we recommend this value be stored?
The values for setParticipantId
and setParticipantFullName
are up to you to set as makes sense for your application. These could be a username and real name, or they could be another form of identification, like an employee number and name.
fileprivate func cognitiveSDKInit() {
// Prepare scene data for the SDK
let sceneData = SceneData(
sceneName: "your-scene-name",
sceneId: "your-scene-id",
versionNumber: 1,
versionId: 1234
)
let core = Cognitive3DAnalyticsCore.shared
// Configure settings
let settings = CoreSettings()
settings.defaultSceneName = sceneData.sceneName
settings.allSceneData = [sceneData]
// Set logging level
settings.loggingLevel = .all
settings.isDebugVerbose = false
// Set Application API key (from Info.plist or another configuration source)
let apiKey = Bundle.main.object(forInfoDictionaryKey: "APPLICATION_API_KEY") as? String ?? "default-value"
settings.apiKey = apiKey
// Set participant information
core.setParticipantId("participant-id")
core.setParticipantFullName("Participant Name")
// Start synchronous initialization
Task {
do {
try await core.configure(with: settings)
// Register code related to dynamic objects
configureDynamicObject(settings)
// Optional: Configure session behaviour
core.config?.shouldEndSessionOnBackground = false
// Set session delegate to handle session events
core.sessionDelegate = yourSessionDelegate
} catch {
print("Failed to configure Cognitive3D Analytics: \(error)")
}
}
}
Set Up scene phase handling
// In your app's WindowGroup
WindowGroup {
ContentView()
// Add this modifier to enable scene phase handling
.observeCognitive3DScenePhase()
}
Dynamic Objects setup
Register components and systems
fileprivate func configureDynamicObject(_ settings: CoreSettings) {
// Register the dynamic component
DynamicComponent.registerComponent()
// Register the dynamic object system
DynamicObjectSystem.registerSystem()
}
Configure Dynamic Objects in a scene
func configureDynamicObjects(rootEntity: Entity) async {
guard let objManager = Cognitive3DAnalyticsCore.shared.dynamicDataManager else {
return
}
// Find all entities with DynamicComponent
let dynamicEntities = findEntitiesWithComponent(rootEntity, componentType: DynamicComponent.self)
// Register each dynamic object with the SDK
for (entity, comp) in dynamicEntities {
await objManager.registerDynamicObject(id: comp.dynamicId, name: comp.name, mesh: comp.mesh)
}
}
Content entity for raycasting
This is required to record gaze with RealityKit
entities that have a DynamicComponent
.
// In your RealityView setup
if let contentEntity = try? await Entity(named: "YourScene", in: realityKitContentBundle) {
// ...
// Provide the entity to the SDK for raycasting and collision detection
let core = Cognitive3DAnalyticsCore.shared
core.contentEntity = contentEntity
}
Session Management
Implement session delegates
// Conform to SessionDelegate
class YourAppModel: SessionDelegate {
// Handle session end events
nonisolated func sessionDidEnd(sessionId: String, sessionState: SessionState) {
Task { @MainActor in
switch sessionState {
case .endedIdle(timeInterval: let timeInterval):
// Handle idle timeout
case .endedBackground:
// Handle app going to background
default:
// Handle other cases
}
}
}
}
// Conform to IdleSessionDelegate
class YourAppModel: IdleSessionDelegate {
nonisolated func sessionDidEndDueToIdle(sessionId: String, idleDuration: TimeInterval) {
Task { @MainActor in
// Handle idle session end
}
}
}
Starting and ending sessions
Note: Your application should typically only start and end a session once in it's usage lifecycle. If your app starts and ends sessions during typical usage, i.e. while the Participant is using the app continuously, you will see separate sessions on the dashboard for each start-session/end-session pair, which is undesirable.
// Start a session
Cognitive3DAnalyticsCore.shared.startSession()
// End a session
Cognitive3DAnalyticsCore.shared.endSession()
Creating and sending Custom Events
Custom Events are used to track what happens in your application at a given time and location. These are associated with a session and will appear in that session's timeline on the dashboard.
func createCustomEvent(dynamicId: String) {
let core = Cognitive3DAnalyticsCore.shared
// Create an event
let event = CustomEvent(
name: "tapEvent",
properties: [
"timestamp": Date().timeIntervalSince1970
],
dynamicObjectId: dynamicId,
core: core
)
let success = event.send()
}
Working with ExitPoll surveys
The ExitPoll system can be used to prompt Participants for their opinions or feedback while your application is running. The responses are gathered by the SDK and are visible on the dashboard.
TODO: Link to the ExitPolls section of the dashboard documentation.
// Create an exit poll survey
let exitPollSurvey = ExitPollSurveyViewModel()
exitPollSurvey.loadSurvey(hook: "your-survey-hook")
// Submit survey answers
Task {
let result = await exitPollSurvey.sendSurveyAnswers()
switch result {
case .success:
print("Survey answers submitted successfully.")
case .failure(let error):
print("Failed to submit survey answers: \(error)")
}
}
Changing Scenes
Scenes are typically separate virtual locations in your application. In a game application you might have a Lobby Scene and a Gameplay Scene. For training applications you might have a Login Scene and one or more training scenario Scenes.
Note: Reminder that uploading scene data (meshes, textures) is a manual process currently. Reach out via Intercom or Discord for help from the Cognitive3D team.
// Set a different scene during runtime
Cognitive3DAnalyticsCore.shared.setSceneById(
sceneId: "new-scene-id",
version: 1,
versionId: 1234
)
If you have a question or any feedback about our documentation please use the Intercom button (purple circle) in the lower right corner of any web page or join our Discord.