Item

protocol Item : Sendable, ItemReflection

Protocol that all SDK modules must conform to.

Implementing this protocol allows a module to be registered with the SDK and participate in the module lifecycle. All methods are static and receive an isolated MoEngageSDKInstance, so they execute on the instance’s actor without an extra hop.

Implementation Guidelines

State Management

  • Store per-instance state keyed by the SDK instance’s workspace ID
  • Clean up state in the Event.deinit case

Event Handling

  • Return quickly from process(event:sdkInstance:); spawn an unstructured Task { } for expensive or async work you do not need to await
  • Use process(event:sdkInstance:) async only for operations the SDK must await before proceeding (e.g. flushing data before logout)

Error Handling

  • Don’t throw errors from these methods
  • Log errors internally and handle gracefully

Example Implementation

final class AnalyticsModule: MoEngageModule.Item {

    static func getInfo(sdkInstance: isolated MoEngageSDKInstance) -> MoEngageModule.Info? {
        return .init(
            name: "analytics",
            version: "3.0.0",
            metadata: ["features": ["events", "userAttributes"]]
        )
    }

    static func process(event: MoEngageModule.Event, sdkInstance: isolated MoEngageSDKInstance) {
        switch event {
        case .init:
            setupObservers(for: sdkInstance)
        case .start:
            Task { await trackAppOpened(for: sdkInstance) }
        case .deinit:
            removeState(for: sdkInstance)
        default:
            break
        }
    }

    static func process(event: MoEngageModule.AsyncEvent, sdkInstance: isolated MoEngageSDKInstance) async {
        switch event {
        case .willLogout:
            await flushPendingEvents(for: sdkInstance)
        default:
            break
        }
    }

    static func listensToAdditionalNotifications() -> [Notification.Name] { [] }
}
  • Returns metadata about this module.

    Called when the SDK needs to identify the module (for logging, analytics, or debugging). This method may be called multiple times and should return consistent information.

    Implementation Notes

    • Return a constant or cached value for performance
    • The name should be unique within the SDK
    • The version should follow semantic versioning

    Example

    static func getInfo(sdkInstance: isolated MoEngageSDKInstance) -> MoEngageModule.Info? {
        return MoEngageModule.Info(
            name: "myModule",
            version: "1.0.0",
            metadata: ["buildNumber": "123"]
        )
    }
    

    Declaration

    Swift

    static func getInfo(sdkInstance: isolated MoEngageSDKInstance) -> Info?

    Parameters

    sdkInstance

    The isolated SDK instance requesting the info.

    Return Value

    Module metadata including name and version, or nil if this module does not apply to the given instance.

  • Processes a synchronous lifecycle event for this module.

    Called by the SDK at key lifecycle points and for SDK state changes. Runs on the MoEngageSDKInstance actor’s executor.

    Actor Isolation

    This method runs on sdkInstance‘s actor. Spawn an unstructured Task { } for work that should not block the actor.

    Event Guarantees

    • .init is always called before .start
    • .start is only called once per instance
    • .deinit is called at most once per instance
    • Events are delivered in order

    Example

    static func process(event: MoEngageModule.Event, sdkInstance: isolated MoEngageSDKInstance) {
        switch event {
        case .init:
            setupModule()
        case .start:
            Task { await startProcessing() }
        case .deinit:
            cleanup()
        default:
            break
        }
    }
    

    Declaration

    Swift

    static func process(event: Event, sdkInstance: isolated MoEngageSDKInstance)

    Parameters

    event

    The lifecycle event being delivered.

    sdkInstance

    The isolated SDK instance delivering the event.

  • Processes an async lifecycle event for this module and suspends until it finishes.

    Called by the SDK for events that must complete before the SDK proceeds, such as flushing data before logout or vetoing an unregister operation. Runs on the MoEngageSDKInstance actor’s executor and is awaited by the SDK.

    Event Guarantees

    • The SDK awaits the returned task before continuing.
    • Implementations must not block indefinitely.

    Example

    static func process(event: MoEngageModule.AsyncEvent, sdkInstance: isolated MoEngageSDKInstance) async {
        switch event {
        case .willLogout:
            await flushPendingData(for: sdkInstance)
        default:
            break
        }
    }
    

    Declaration

    Swift

    static func process(event: AsyncEvent, sdkInstance: isolated MoEngageSDKInstance) async

    Parameters

    event

    The async lifecycle event being delivered.

    sdkInstance

    The isolated SDK instance delivering the event.

  • Returns the additional Notification.Name values this module wants to observe.

    The SDK calls this once during module registration and routes any matching Notification to process(event:sdkInstance:) as a .didRecieveFromSystem(_:) event.

    Return an empty array (the default) if the module does not need extra notifications.

    Example

    static func listensToAdditionalNotifications() -> [Notification.Name] {
        return [UIApplication.didReceiveMemoryWarningNotification]
    }
    

    Declaration

    Swift

    static func listensToAdditionalNotifications() -> [Notification.Name]