Open channel events
Use OpenChannelHandler (Objective-C protocol name: NCOpenChannelHandler) to receive events from open channels. A single unified handler protocol covers all event types: enter/exit lifecycle, metadata changes, member changes, multi-device sync, and mute/ban notifications.
Register the handler via NCEngine with a unique identifier string. The identifier lets you add multiple independent listeners and remove them individually when no longer needed.
- Swift
- Objective-C
import NexconnChatSDK
// Register
NCEngine.addOpenChannelHandler(identifier: "MY_OPEN_CHANNEL_HANDLER", handler: self)
// Remove
NCEngine.removeOpenChannelHandler(forIdentifier: "MY_OPEN_CHANNEL_HANDLER")
// Register
[NCEngine addOpenChannelHandlerWithIdentifier:@"MY_OPEN_CHANNEL_HANDLER" handler:self];
// Remove
[NCEngine removeOpenChannelHandlerForIdentifier:@"MY_OPEN_CHANNEL_HANDLER"];
Enter and exit events
Adopt the NCOpenChannelHandler protocol and implement the callbacks you need. All methods are optional.
- Swift
- Objective-C
import NexconnChatSDK
final class MyViewController: NSObject, OpenChannelHandler {
// Starting to enter the open channel
func onEntering(_ event: OpenChannelEnteringEvent) {
print("Entering channel: \(event.channelId)")
}
// Successfully entered the open channel
func onEntered(_ event: OpenChannelEnteredEvent) {
// event.response may be nil for legacy callbacks
print("Entered channel: \(event.channelId), members: \(event.response?.memberCount ?? 0)")
}
// Failed to enter the open channel
func onEnterFailed(_ event: OpenChannelEnterFailedEvent) {
print("Failed to enter channel \(event.channelId): \(event.error.localizedDescription)")
}
// Open channel was reset (SDK rejoined after a connection interruption)
func onReset(_ event: OpenChannelResetEvent) {
print("Channel reset: \(event.channelId)")
}
// Successfully exited the open channel
func onExited(_ event: OpenChannelExitedEvent) {
print("Exited channel: \(event.channelId)")
}
// Open channel was destroyed
func onChannelDestroyed(_ event: OpenChannelDestroyedEvent) {
if event.destroyType == .manual {
print("Channel \(event.channelId) was manually destroyed.")
} else {
print("Channel \(event.channelId) was recycled due to inactivity.")
}
}
}
@interface MyViewController () <NCOpenChannelHandler>
@end
@implementation MyViewController
// Starting to enter the open channel
- (void)onEntering:(NCOpenChannelEnteringEvent *)event {
NSLog(@"Entering channel: %@", event.channelId);
}
// Successfully entered the open channel
- (void)onEntered:(NCOpenChannelEnteredEvent *)event {
// event.response may be nil for legacy callbacks
NSLog(@"Entered channel: %@, members: %ld",
event.channelId, (long)event.response.memberCount);
}
// Failed to enter the open channel
- (void)onEnterFailed:(NCOpenChannelEnterFailedEvent *)event {
NSLog(@"Failed to enter channel %@: %@", event.channelId, event.error);
}
// Open channel was reset (SDK rejoined after a connection interruption)
- (void)onReset:(NCOpenChannelResetEvent *)event {
NSLog(@"Channel reset: %@", event.channelId);
}
// Successfully exited the open channel
- (void)onExited:(NCOpenChannelExitedEvent *)event {
NSLog(@"Exited channel: %@", event.channelId);
}
// Open channel was destroyed
- (void)onChannelDestroyed:(NCOpenChannelDestroyedEvent *)event {
if (event.destroyType == NCOpenChannelDestroyTypeManual) {
NSLog(@"Channel %@ was manually destroyed.", event.channelId);
} else {
NSLog(@"Channel %@ was recycled due to inactivity.", event.channelId);
}
}
@end
NCOpenChannelEnterResponseInfo properties
When onEntered: fires, event.response provides the initial channel state:
| Property | Type | Description |
|---|---|---|
memberCount | NSInteger | Current participant count |
createTime | int64_t | Channel creation timestamp (ms) |
enterTime | int64_t | Time the current user entered (ms) |
isAllChannelMuted | BOOL | Whether global mute is enabled for the channel |
isCurrentUserMuted | BOOL | Whether the current user is muted |
isCurrentChannelMuted | BOOL | Whether the channel is muted for the current user |
isCurrentChannelInAllowlist | BOOL | Whether the current user is in the allowlist |
Metadata events
onMetadataSynced: fires once when you first enter a channel, after the channel's metadata has been pulled down. onMetadataChanged: fires whenever a key is updated or deleted while you are in the channel.
- Swift
- Objective-C
import NexconnChatSDK
// Initial metadata sync completed on enter
func onMetadataSynced(_ event: OpenChannelMetadataSyncedEvent) {
print("Metadata synced for channel: \(event.channelId)")
}
// Metadata updated or deleted
func onMetadataChanged(_ event: OpenChannelMetadataChangedEvent) {
for change in event.changeInfo {
if change.operationType == .remove {
print("Key deleted in channel \(change.channelId): \(change.key)")
} else {
print("Key updated in channel \(change.channelId): \(change.key) = \(change.value ?? "")")
}
}
}
// Initial metadata sync completed on enter
- (void)onMetadataSynced:(NCOpenChannelMetadataSyncedEvent *)event {
NSLog(@"Metadata synced for channel: %@", event.channelId);
}
// Metadata updated or deleted
- (void)onMetadataChanged:(NCOpenChannelMetadataChangedEvent *)event {
for (NCOpenChannelMetadataChangeInfo *change in event.changeInfo) {
if (change.operationType == NCOpenChannelMetadataOperationTypeRemove) {
NSLog(@"Key deleted in channel %@: %@", change.channelId, change.key);
} else {
NSLog(@"Key updated in channel %@: %@ = %@",
change.channelId, change.key, change.value);
}
}
}
Member change events
Receive notifications when participants join or leave the channel. To enable this feature, turn on Enable auto messaging for participant events in the Nexconn Console under Chat > Chat settings > Open Channels.
When this service is enabled, join/leave events are delivered as messages, which increases total message volume.
- Swift
- Objective-C
import NexconnChatSDK
func onMemberChanged(_ event: OpenChannelMemberChangedEvent) {
for action in event.actions {
if action.action == .enter {
print("Participant joined: \(action.userId)")
} else {
print("Participant left: \(action.userId)")
}
}
print("Current member count: \(event.memberCount)")
}
- (void)onMemberChanged:(NCOpenChannelMemberChangedEvent *)event {
for (NCOpenChannelMemberActionInfo *action in event.actions) {
if (action.action == NCOpenChannelMemberActionTypeEnter) {
NSLog(@"Participant joined: %@", action.userId);
} else {
NSLog(@"Participant left: %@", action.userId);
}
}
NSLog(@"Current member count: %ld", (long)event.memberCount);
}
Multi-device sync events
When the current user joins or exits the same open channel on another device, onNotifyMultiLoginSync: fires on this device.
- Swift
- Objective-C
import NexconnChatSDK
func onNotifyMultiLoginSync(_ event: OpenChannelNotifyMultiLoginSyncEvent) {
if event.info.status == .enter {
print("Joined channel \(event.info.channelId) on another device.")
} else {
print("Left channel \(event.info.channelId) on another device (reason: \(event.info.reason.rawValue)).")
}
}
- (void)onNotifyMultiLoginSync:(NCOpenChannelNotifyMultiLoginSyncEvent *)event {
if (event.info.status == NCOpenChannelSyncStatusEnter) {
NSLog(@"Joined channel %@ on another device.", event.info.channelId);
} else {
NSLog(@"Left channel %@ on another device (reason: %ld).",
event.info.channelId, (long)event.info.reason);
}
}
Ban events
onMemberBanned: fires when users are banned from or unbanned in the channel via the Server API (with needNotify: true).
- Swift
- Objective-C
import NexconnChatSDK
func onMemberBanned(_ event: OpenChannelMemberBannedEvent) {
let info = event.info
// info.channelId — channel ID
// info.banType — NCOpenChannelMemberBanType (.ban or .unban)
// info.userIds — affected user IDs
// info.durationTime — ban duration in minutes; 43200 = one month, -1 = permanent
// info.operateTime — operation timestamp (ms)
print("Ban event in channel \(info.channelId), type: \(info.banType.rawValue), users: \(info.userIds)")
}
- (void)onMemberBanned:(NCOpenChannelMemberBannedEvent *)event {
NCOpenChannelMemberBannedInfo *info = event.info;
// info.channelId — channel ID
// info.banType — NCOpenChannelMemberBanType (.ban or .unban)
// info.userIds — affected user IDs
// info.durationTime — ban duration in minutes; 43200 = one month, -1 = permanent
// info.operateTime — operation timestamp (ms)
NSLog(@"Ban event in channel %@, type: %ld, users: %@",
info.channelId, (long)info.banType, info.userIds);
}
Mute events
onMemberMuted: fires when users are muted or unmuted in the channel via the Server API (with needNotify: true).
- Swift
- Objective-C
import NexconnChatSDK
func onMemberMuted(_ event: OpenChannelMemberMutedEvent) {
let info = event.info
// info.channelId — channel ID
// info.muteType — NCOpenChannelMemberMuteType (see table below)
// info.userIds — affected user IDs
// info.durationTime — mute duration in minutes; 43200 = one month, -1 = permanent
// info.operateTime — operation timestamp (ms)
print("Mute event in channel \(info.channelId), type: \(info.muteType.rawValue), users: \(info.userIds)")
}
- (void)onMemberMuted:(NCOpenChannelMemberMutedEvent *)event {
NCOpenChannelMemberMutedInfo *info = event.info;
// info.channelId — channel ID
// info.muteType — NCOpenChannelMemberMuteType (see table below)
// info.userIds — affected user IDs
// info.durationTime — mute duration in minutes; 43200 = one month, -1 = permanent
// info.operateTime — operation timestamp (ms)
NSLog(@"Mute event in channel %@, type: %ld, users: %@",
info.channelId, (long)info.muteType, info.userIds);
}
NCOpenChannelMemberMuteType values
| Value | Description |
|---|---|
NCOpenChannelMemberMuteTypeMuteUsers | Mute specific users |
NCOpenChannelMemberMuteTypeUnmuteUsers | Unmute specific users |
NCOpenChannelMemberMuteTypeMuteAll | Enable global mute for all users |
NCOpenChannelMemberMuteTypeUnmuteAll | Disable global mute for all users |
NCOpenChannelMemberMuteTypeAddAllowlist | Add users to the mute allowlist |
NCOpenChannelMemberMuteTypeRemoveAllowlist | Remove users from the mute allowlist |
NCOpenChannelMemberMuteTypeMuteGlobal | Apply global mute to specific users |
NCOpenChannelMemberMuteTypeUnmuteGlobal | Remove global mute from specific users |
Callback reference
| Callback | Event type | Trigger |
|---|---|---|
onEntering: | NCOpenChannelEnteringEvent | Starting to enter the open channel |
onEntered: | NCOpenChannelEnteredEvent | Successfully entered; event.response contains initial channel state |
onEnterFailed: | NCOpenChannelEnterFailedEvent | Failed to enter; event.error contains the reason |
onReset: | NCOpenChannelResetEvent | Channel state was reset after a reconnection |
onExited: | NCOpenChannelExitedEvent | Successfully exited the channel |
onChannelDestroyed: | NCOpenChannelDestroyedEvent | Channel destroyed manually or recycled automatically |
onMetadataSynced: | NCOpenChannelMetadataSyncedEvent | Initial metadata pull completed on enter |
onMetadataChanged: | NCOpenChannelMetadataChangedEvent | One or more metadata keys updated or deleted; use event.changeInfo to iterate |
onMemberChanged: | NCOpenChannelMemberChangedEvent | Participant joined or left; use event.actions to iterate |
onNotifyMultiLoginSync: | NCOpenChannelNotifyMultiLoginSyncEvent | Current user joined or left this channel on another device |
onMemberMuted: | NCOpenChannelMemberMutedEvent | Participants muted or unmuted via Server API |
onMemberBanned: | NCOpenChannelMemberBannedEvent | Participants banned or unbanned via Server API |