MimiSDK 12 Migration Guide

MimiSDK 12 brings small but API-breaking changes to the public model layer. This document outlines the changes required to migrate to MimiSDK 12 from MimiSDK 11.

Requirements

  • iOS 15 or above.
  • Xcode 26
  • Swift 5.9

API Changes

MimiSDK 12 introduces API-breaking changes that should be made aware of. These changes are documented in the Changelog.

MimiPersonalization.Preset.payload is now a base64-encoded String

In MimiSDK 11 and earlier, MimiPersonalization.Preset.payload was exposed as a Data value: the SDK silently base64-decoded the payload string returned by the backend before exposing it. This forced every consumer that needed to ship the payload to the Firmware to base64-encode it again, and diverged from the Android SDK, which exposes the payload as the original base64-encoded string.

Starting with MimiSDK 12, MimiPersonalization.Preset.payload is the base64-encoded String exactly as delivered by the backend.

Reading the payload

// Before (MimiSDK 11)
let preset: MimiPersonalization.Preset = ...
let payloadData: Data = preset.payload
let base64Payload: String = preset.payload.base64EncodedString()
// After (MimiSDK 12)
let preset: MimiPersonalization.Preset = ...
let base64Payload: String = preset.payload
// If you need raw bytes:
let payloadData: Data? = Data(base64Encoded: preset.payload)

MimiProcessingSession.voiceClarity is now an activation controller

In MimiSDK 11 and earlier, MimiProcessingSession.voiceClarity was exposed as a passive MimiVoiceClarityFeature? value. There was no way to programmatically activate or deactivate voice clarity through the SDK, and the feature value reflected only the state the device was in at session-build time.

Starting with MimiSDK 12, MimiProcessingSession.voiceClarity is exposed as AnyMimiProcessingFeatureControlling<MimiVoiceClarityFeature>? — a controller that:

  • Provides activate() / deactivate() to turn voice clarity on or off on the processor.
  • Exposes featurePublisher: AnyPublisher<MimiVoiceClarityFeature?, Never>, which emits the wrapped feature while voice clarity is running and nil when it is not.

AnyMimiProcessingFeatureControlling<Feature> is a type-eraser for the MimiProcessingFeatureControlling<Feature> protocol. It exists so the property type stays usable on iOS 15, where the parameterized existential any MimiProcessingFeatureControlling<Feature> lacks runtime metadata. The type is deprecated on iOS 16 and will be removed when the minimum deployment target moves to iOS 16; on iOS 16+ the MimiProcessingFeatureControlling protocol is the supported access path.

Reading the active feature

// Before (MimiSDK 11)
let session: MimiProcessingSession = ...
let ambientEnabled: Bool? = session.voiceClarity?.ambient?.isEnabled.value
// After (MimiSDK 12)
import Combine

private var voiceClarityFeature: MimiVoiceClarityFeature?
private var cancellables = Set<AnyCancellable>()

session.voiceClarity?.featurePublisher
    .sink { [weak self] in self?.voiceClarityFeature = $0 }
    .store(in: &cancellables)

// Later, while voice clarity is running:
let ambientEnabled: Bool? = voiceClarityFeature?.ambient?.isEnabled.value

When the session is created while voice clarity is already running on the device, featurePublisher seeds with a non-nil feature on subscription — no activate() call is required to observe the current state.

Activating and deactivating voice clarity

// New in MimiSDK 12
try await session.voiceClarity?.activate()
// featurePublisher now emits a non-nil MimiVoiceClarityFeature

try await session.voiceClarity?.deactivate()
// featurePublisher emits nil

MimiProcessingController.session has been removed

In MimiSDK 11 and earlier, MimiProcessingController exposed a session convenience property returning the latest value emitted by sessionPublisher. Holding on to that value was risky: the property could return a session reference that was subsequently invalidated by a deactivate() call without the holder being notified. The Android SDK does not expose an equivalent convenience.

Starting with MimiSDK 12, MimiProcessingController.session has been removed. Consumers must observe sessionPublisher (or retain the session value returned by activate(configuration:)) to track the current session.

Reading the current session

// Before (MimiSDK 11)
if let session = core.processing.session {
    _ = try? await session.suspend()
}
// After (MimiSDK 12)
import Combine

private var currentSession: MimiProcessingSession?
private var cancellables = Set<AnyCancellable>()

core.processing.sessionPublisher
    .sink { [weak self] in self?.currentSession = $0 }
    .store(in: &cancellables)

// Later:
if let session = currentSession {
    _ = try? await session.suspend()
}