The Ambient Session feature in the Suki Mobile SDK allows you to manage the lifecycle of clinical note-taking sessions, including session creation, recording controls, status checks, content retrieval, and event handling.

1. Create a Session

Before recording, create a session with patient and section information:
do {
    let sessionContext: [String: Any] = [
        SukiAmbientConstant.kPatientInfo: [
            SukiAmbientConstant.kName: "Saran Goda",
            SukiAmbientConstant.kBirthdate: Date(), // yyyy-mm-dd format
            SukiAmbientConstant.kGender: "MALE"
        ],
        SukiAmbientConstant.kSections: [
            ["title": "History", "description": "History"],
            ["title": "Review of systems", "description": "Review of systems"]
        ],
        SukiAmbientConstant.kSessionId: UUID().uuidString.lowercased(),
        SukiAmbientConstant.kMultilingual: true
    ]
    sessionId = try SukiAmbientCore.shared.createSession(withSessionInfo: sessionContext, onCompletion: { _ in })
} catch {
    print(error)
}
Notes:
  • Include patient name, birthdate, and gender.
  • Specify sections for which you want content generated (defaults are provided if omitted).
  • Optionally, provide a session ID or let the SDK generate one.
  • You can pass the multilingual parameter (Boolean) to indicate whether the session should be processed in multilingual mode:
    • true: Enables multilingual processing for this session.
    • false: Defaults to English.
    • This setting applies per session and does not change mid-session.
  • Handle errors using SukiAmbientCoreError.
The setSessionContext method allows setting patient, provider context and LOINC codes for section generation and (newly added) diagnosis information for an already created session. All such data should instead be passed using the new setSessionContext method.
public func setSessionContext(
    with context: ContextDetail,
    onCompletion completionHandler: SessionContextCallback
)
do {
    let contextDetail: [String: AnyHashable] = [
        SukiAmbientConstant.kPatientInfo: [
            SukiAmbientConstant.kBirthdate: Date(), // yyyy-mm-dd format
            SukiAmbientConstant.kGender: "MALE"
        ],
        SukiAmbientConstant.kProviderContext: [
            SukiAmbientConstant.kSpeciality: "FAMILY_MEDICINE"
        ],
        SukiAmbientConstant.kSections: [
            [
                SukiAmbientConstant.kCode: "51848-0",
                SukiAmbientConstant.kCodeType: "loinc"
            ],
            [
                SukiAmbientConstant.kCode: "11450-4", 
                SukiAmbientConstant.kCodeType: "loinc"
            ]
        ],
        SukiAmbientConstant.kDiagnosisInfo: [
            [
                SukiAmbientConstant.kDiagnosisNote: "Patient presents with chest pain",
                SukiAmbientConstant.kCodes: [
                    [
                        SukiAmbientConstant.kCodeType: "ICD-10",
                        SukiAmbientConstant.kCode: "R06.02",
                        SukiAmbientConstant.kCodeDescription: "Shortness of breath"
                    ]
                ]
            ]
        ]
    ]
    
    try SukiAmbientCore.shared.setSessionContext(with: contextDetail) { result in
        // Handle completion result
    }
} catch {
    print(error)
}
Parameters:
  • context: A dictionary of type [String: AnyHashable] that may contain the following keys:
    • SukiAmbientConstant.kPatientInfo: Dictionary containing:
      • SukiAmbientConstant.kBirthdate: Date
      • SukiAmbientConstant.kGender: String
    • SukiAmbientConstant.kProviderContext: Dictionary containing:
      • SukiAmbientConstant.kSpeciality: String
    • SukiAmbientConstant.kSections: Array of dictionaries: Each with SukiAmbientConstant.kCode and SukiAmbientConstant.kCodeType (e.g., “loinc”)
Diagnosis Info:
  • SukiAmbientConstant.kDiagnosisInfo: An Array of Dictionaries used to pass structured diagnosis context for the session.
    • Each dictionary may include:
      • SukiAmbientConstant.kDiagnosisNote: String (Optional note related to the diagnosis)
      • SukiAmbientConstant.kCodes: [Dictionary] (Array of dictionaries) — must contain at least one valid diagnosis code.
        • Each dictionary may include:
          • SukiAmbientConstant.kCodeType: String (e.g., “ICD-10”, “IMO”, “SNOMED”) (Required)
          • SukiAmbientConstant.kCode: String (Required)
          • SukiAmbientConstant.kCodeDescription: String (Optional)
Important Notes:
  • Can only be called after a session is successfully created.
  • Pass only valid Specialities and LOINC codes.
  • The session context dictionary should contain patient information such as birthdate (in yyyy-mm-dd format) and gender.
  • diagnosisNote is optional.
  • Each code entry must include codeType and code.
  • codeDescription is optional but recommended for clarity.
  • Sections are no longer required, LOINC codes alone are sufficient, and the SDK will automatically generate the appropriate clinical sections based on the provided codes.
  • The setSessionContext function now internally uses a PATCH API that supports partial updates.

2. Recording Controls

Start Recording
do {
    try SukiAmbientCore.shared.start()
} catch {
    print(error)
}
Pause Recording
do {
    try SukiAmbientCore.shared.pause()
} catch {
    print(error)
}
Resume Recording
do {
    try SukiAmbientCore.shared.resume()
} catch {
    print(error)
}
End Recording
do {
    try SukiAmbientCore.shared.end()
} catch {
    print(error)
}
Cancel Session
do {
    try SukiAmbientCore.shared.cancel()
} catch {
    print(error)
}
  • Always ensure the SDK is initialized and a session is created before calling these methods.
  • Handle all errors using SukiAmbientCoreError.
  • iOS does not allow starting a recording in the background; handle appIsNotActive errors with user notifications if needed.

3. Session Status & Content Retrieval

Get Suggestion Generation Status
SukiAmbientCore.shared.status(for: recordingId) { result in
    switch result {
    case .success(let status):
        print("status \(status)")
    case .failure(let error):
        print("error \(error)")
    }
}
Get Generated Suggestions
SukiAmbientCore.shared.content(for: recordingId) { result in
    switch result {
    case .success(let suggestions):
        print("suggestions \(suggestions)")
    case .failure(let error):
        print("error \(error)")
    }
}
Get Audio Transcript
SukiAmbientCoreManager.shared.transcript(for: recordingId) { result in
    switch result {
    case .success(let response):
        let transcriptText = (response.finalTranscript ?? []).compactMap { $0.transcript }.joined()
        print(transcriptText)
    case .failure(let error):
        print(error)
    }
}
Get Structured Data The getStructuredData(for:onCompletion:) method retrieves structured output data for a given recording ID. This includes structured diagnoses and other generated entities from the session.
SukiAmbientCore.shared.getStructuredData(for: recordingId) { result in
    switch result {
    case .success(let structuredData):
        print("Structured Data: \(structuredData)")
    case .failure(let error):
        print("error \(error)")
    }
}
Key Points to Note:
  • This code asynchronously fetches the content of the generated suggestions for the specified recording ID.
  • The completion block contains either the generated suggestions or an error in case there’s an issue while fetching the content.
  • Ensure that the SDK is initialized and the recording ID is valid before calling this method.
  • All methods are asynchronous and require a valid recording ID.
  • The completion block returns either the result or an error.

4. Clearing Sessions

Clear All Sessions
do {
    try SukiAmbientCore.shared.clear()
} catch {
    print(error)
}
  • Use during user logout to clear all sessions.
  • Do not call during an active session; this will throw an error.

5. Session Events & Delegates

Implement the delegate to listen for session events:
extension AppDelegate: SukiAmbientSessionDelegate {
    func sukiAmbient(sessionEvent event: SukiAmbientCore.SessionEvent, for recordingId: SukiAmbientCore.RecordingId) {
        // Handle session events here
    }
}
Session Events enum:
public enum SessionEvent {
    case started
    case resumed
    case paused
    case ended
    case cancelled
    case suggestionGenerationInProgress
    case suggestionsGenerated
    case suggestionsGenerationFailed
    case audioInterruptionStarted
    case audioInterruptionEnded
    case convertedToOfflineSession
    case pendingOfflineUpload
    case preparingOfflineUpload
    case uploadingAudio
    case audioUploadFailed
    case audioUploadAllRetryFailed
    case audioUploaded
    case processingUpload
    case processingUploadFailed
}

Best Practices

  • Always check SDK initialization and session state before calling methods.
  • Handle all errors and provide user feedback, especially for background/foreground transitions.
  • Use local notifications for important background errors.
  • Store the unique session/recording ID for future operations.

Offline Mode

To ensure session robustness, the Mobile SDK supports an offline mode that allows it to continue functioning seamlessly even during connectivity disruptions. When a session enters offline mode, the SDK will:
  • Continue recording audio locally on the device
  • Store the audio and metadata securely on the device
  • Automatically attempt to upload the stored data once the connection is restored
  • Queue session events and sync them when connectivity returns
During offline mode, the session remains seamless and continues functioning normally. The SDK will notify users when the session moves to offline mode through the session delegate events, and will continuously attempt to reconnect and sync data once connectivity is reestablished. A session may switch to offline mode due to various connectivity-related issues, such as:
  • Network interruptions or poor cellular/WiFi connectivity
  • Temporary backend unavailability
  • WebSocket connection drops during audio streaming
  • Token-related authentication failures
  • Device switching between networks (WiFi to cellular)
Important Notes:
  • The SDK automatically manages offline/online transitions without manual intervention
  • Audio quality and session integrity are maintained during offline periods
  • Multiple offline sessions can be queued and uploaded when connectivity returns
  • Local storage is encrypted and secure
  • Battery optimization is considered during offline recording

Best Practices & Error Handling

  • Always ensure the SDK is initialized and a session is created before calling recording methods.
  • Handle SukiAmbientCoreError in all operations to provide robust error feedback.
  • For background recording, be aware of iOS limitations: recording cannot be started in the background, and background execution time is limited.
  • Use local notifications to inform users if errors occur while the app is backgrounded.
  • Store the unique recording/session ID for future operations such as status changes or retrieving content.