Browse SDKs · iOS
Platform
SDKsiOS

Send a custom signal

Send and receive custom signals in a call room with the OpenIM iOS SDK.

Copy

Transmit lightweight coordination data within an ongoing call room using signalingSendCustomSignal:customInfo:onSuccess:onFailure:. Use custom signaling for events like raising hands, requesting layout changes, or syncing transient presentation flags. Custom signaling is distinct from chat messages and does not substitute for media engine data channels.

Parameters

ParameterTypeRequiredDescription
roomIDNSString *YesTarget call room identifier matching the active call session.
customInfoNSString *YesApplication-defined string payload. When serializing JSON, include a schema version and an idempotency event ID.

Code example

NSDictionary *signal = @{
    @"version": @1,
    @"eventID": NSUUID.UUID.UUIDString.lowercaseString,
    @"type": @"hand-raised",
    @"userID": currentUserID,
    @"sentAt": @((NSInteger64)(NSDate.date.timeIntervalSince1970 * 1000)),
};

NSData *data = [NSJSONSerialization dataWithJSONObject:signal options:0 error:nil];
NSString *customInfo = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

[[OIMManager manager] signalingSendCustomSignal:roomID
                                      customInfo:customInfo
                                       onSuccess:^{
    [self markSignalSubmitted:signal[@"eventID"]];
}
                                       onFailure:^(NSInteger code, NSString * _Nullable message) {
    [self showCallError:code message:message ?: @"Failed to send custom signal"];
}];

Return value

The onSuccess callback indicates that OpenIMServer accepted the signaling payload and dispatched it to room participants. It does not signify that other participants have processed or rendered the payload. Custom signaling is designed for lightweight, ephemeral coordination; do not transmit large binaries, message histories, or persistent records over this channel.

Receive custom signals

Implement onReceiveCustomSignal: from the OIMSignalingListener protocol to intercept incoming custom signals. The delegate provides the raw JSON string; parse and validate the payload according to your agreed client schema:

@interface CallSignalStore () <OIMSignalingListener>
@end

@implementation CallSignalStore

- (void)startListening {
    [[OIMManager callbacker] addSignalingListener:self];
}

- (void)stopListening {
    [[OIMManager callbacker] removeSignalingListener:self];
}

- (void)onReceiveCustomSignal:(NSString *)rawSignal {
    NSDictionary *signal = [self parseAndValidateCallSignal:rawSignal];
    if (signal == nil) return;
    if (![signal[@"roomID"] isEqualToString:self.activeRoomID]) return;
    if ([self hasAppliedSignal:signal[@"eventID"]]) return;

    [self applySignal:signal];
}

@end

Retain the listener instance strongly and remove it using removeSignalingListener: upon account logout or when exiting the call session.

Because the incoming delegate method delivers only the raw string without a dedicated top-level room field, embed roomID inside your custom JSON dictionary and verify it matches the current room before executing UI changes. Deduplicate signals using eventID to handle potential out-of-order deliveries.

Signals and durable state

Custom signals operate purely as transient real-time broadcasts rather than queryable server state. Devices that were offline, views that initialize after broadcast, or listeners registered late will miss earlier signals. Store persistent state in backend application databases or standard chat messages. To synchronize active call room membership, query current snapshots via Retrieve a group call room.