Tag channels
- Tag operations use
NCTaginstance methods.- Before tagging channels, create the tag first. See Manage tag data.
- This feature does not apply to open channels.
Each user can create up to 20 tags, and each tag can contain up to 1,000 channels. If a tag already has 1,000 channels, adding another channel succeeds but removes the earliest tagged channel.
Use cases
Channel tags let users group channels. After users create tags (NCTag), they can assign one or more tags to each channel.
Tagged channels support grouped retrieval, display, deletion, unread counts per tag, and per-tag pinning.
- Scenario 1: Tag each channel in the list (e.g., "External", "Department", "Personal").
- Scenario 2: Group contacts by tag (e.g., "Family", "Friends", "Colleagues").
- Scenario 3: Group the channel list by tag (similar to Telegram's tab-based layout).
Tag a channel
After creating a tag (NCTag), users can tag channels. The SDK treats tagging as adding the channel to the tag.
Add channels to a tag
- Swift
- Objective-C
import NexconnChatSDK
// Obtain an NCTag instance via [NCTag createTagWithParams:completion:] or [NCTag getTagsWithCompletion:]
// NCTag has no public initializer — always use the factory/query methods.
let tag: Tag? = nil // Replace with a Tag instance from Tag.createTag/getTags
guard let tag else { return }
let identifier = ChannelIdentifier(channelType: .direct, channelId: "targetUserId")
tag.addChannels(identifiers: [identifier]) { error in
if error == nil {
print("Channel added to tag")
}
}
// Obtain an NCTag instance via [NCTag createTagWithParams:completion:] or [NCTag getTagsWithCompletion:]
// NCTag has no public initializer — always use the factory/query methods.
NCTag *tag; // obtained from createTagWithParams: or getTagsWithCompletion:
NCChannelIdentifier *identifier = [[NCChannelIdentifier alloc] initWithChannelType:NCChannelTypeDirect
channelId:@"targetUserId"];
[tag addChannels:@[identifier] completion:^(NCError * _Nullable error) {
if (error == nil) {
NSLog(@"Channel added to tag");
}
}];
Remove channels from a tag
- Swift
- Objective-C
import NexconnChatSDK
let tag: Tag? = nil // Replace with a Tag instance from Tag.createTag/getTags
guard let tag else { return }
let identifier = ChannelIdentifier(channelType: .direct, channelId: "targetUserId")
tag.deleteChannels(identifiers: [identifier]) { error in
if error == nil {
print("Channel removed from tag")
}
}
NCTag *tag; // obtained from createTagWithParams: or getTagsWithCompletion:
NCChannelIdentifier *identifier = [[NCChannelIdentifier alloc] initWithChannelType:NCChannelTypeDirect
channelId:@"targetUserId"];
[tag deleteChannels:@[identifier] completion:^(NCError * _Nullable error) {
if (error == nil) {
NSLog(@"Channel removed from tag");
}
}];
Remove tags from a channel
- Swift
- Objective-C
import NexconnChatSDK
guard let channel = DirectChannel(channelId: "targetUserId") else { return }
channel.deleteTags(["tagId1", "tagId2"]) { error in
if error == nil {
print("Tags removed")
}
}
NCDirectChannel *channel = [[NCDirectChannel alloc] initWithChannelId:@"targetUserId"];
[channel deleteTags:@[@"tagId1", @"tagId2"] completion:^(NCError * _Nullable error) {
if (error == nil) {
NSLog(@"Tags removed");
}
}];
Get all tags for a channel
Call getTagsWithCompletion: on a channel instance to get all tags. The callback returns an array of NCChannelTagInfo objects, each containing the tag (NCTag) and pinned status.
- Swift
- Objective-C
import NexconnChatSDK
guard let channel = DirectChannel(channelId: "targetUserId") else { return }
channel.getTags { tags, error in
if error == nil {
for info in tags ?? [] {
print("Tag: \(info.tag.tagName), Pinned: \(info.isPinned)")
}
}
}
NCDirectChannel *channel = [[NCDirectChannel alloc] initWithChannelId:@"targetUserId"];
[channel getTagsWithCompletion:^(NSArray<NCChannelTagInfo *> * _Nullable tags, NCError * _Nullable error) {
if (error == nil) {
for (NCChannelTagInfo *info in tags) {
NSLog(@"Tag: %@, Pinned: %@", info.tag.tagName, info.isPinned ? @"YES" : @"NO");
}
}
}];
NCChannelTagInfo properties:
| Property | Type | Description |
|---|---|---|
| tag | NCTag | The tag instance |
| isPinned | BOOL | Whether the channel is pinned within this tag |
Multi-device tag sync
The SDK supports multi-device login. Register an NCTagEventHandler to receive notifications when tags are modified on the user's other devices.
- Register the handler after initialization but before connecting.
- Local tag modifications do not trigger this callback — only changes from other devices do.
- Swift
- Objective-C
import NexconnChatSDK
final class MyTagHandler: NSObject, TagHandler {}
let tagHandler = MyTagHandler()
NCEngine.addTagHandler(identifier: "MyTagHandler", handler: tagHandler)
// Remove handler
NCEngine.removeTagHandler(forIdentifier: "MyTagHandler")
[NCEngine addTagHandlerWithIdentifier:@"MyTagHandler" handler:self];
// Remove handler
[NCEngine removeTagHandlerForIdentifier:@"MyTagHandler"];
Implement the NCTagEventHandler protocol:
- Swift
- Objective-C
import NexconnChatSDK
func onTagChanged(_ event: TagChangedEvent) {
// Tag data changed — refresh the tag list
Tag.getTags { tags, error in
// Update UI
}
}
func onChannelTagChanged(_ event: ChannelTagChangedEvent) {
// Channel-tag binding changed — refresh channel tags
}
- (void)onTagChanged {
// Tag data changed — refresh the tag list
[NCTag getTagsWithCompletion:^(NSArray<NCTag *> * _Nullable tags, NCError * _Nullable error) {
// Update UI
}];
}
- (void)onChannelTagChanged {
// Channel-tag binding changed — refresh channel tags
}
Operations by tag
After tagging channels, you can perform the following operations:
Get tagged channel list (paginated)
- Swift
- Objective-C
import NexconnChatSDK
let params = TaggedChannelsQueryParams()
params.tagId = "tagId"
params.pageSize = 20
params.startTime = 0
let query = Tag.createTaggedChannelsQuery(params: params)
query.loadNextPage { page, error in
if error == nil {
for channel in page?.data ?? [] {
print("Channel: \(channel.channelId)")
}
}
}
NCTaggedChannelsQueryParams *params = [[NCTaggedChannelsQueryParams alloc] init];
params.tagId = @"tagId";
params.pageSize = 20;
params.startTime = 0;
NCTaggedChannelsQuery *query = [NCTag createTaggedChannelsQueryWithParams:params];
[query loadNextPageWithCompletion:^(NSArray<NCBaseChannel *> * _Nullable channels, NCError * _Nullable error) {
if (error == nil) {
for (NCBaseChannel *channel in channels) {
NSLog(@"Channel: %@", channel.channelId);
}
}
}];
Get untagged channel list
- Swift
- Objective-C
import NexconnChatSDK
let params = UntaggedChannelsQueryParams()
params.pageSize = 20
params.topPriority = true
let query = Tag.createUntaggedChannelsQuery(params: params)
query.loadNextPage { page, error in
if error == nil {
print("Untagged channels: \(page?.data.count ?? 0)")
}
}
NCUntaggedChannelsQueryParams *params = [[NCUntaggedChannelsQueryParams alloc] init];
params.pageSize = 20;
params.topPriority = YES;
NCUntaggedChannelsQuery *query = [NCTag createUntaggedChannelsQueryWithParams:params];
[query loadNextPageWithCompletion:^(NSArray<NCBaseChannel *> * _Nullable channels, NCError * _Nullable error) {
if (error == nil) {
NSLog(@"Untagged channels: %lu", (unsigned long)channels.count);
}
}];
Get unread count by tag
- Swift
- Objective-C
import NexconnChatSDK
let tag: Tag? = nil // Replace with a Tag instance from Tag.createTag/getTags
guard let tag else { return }
tag.getUnreadCount(containNoDisturb: false) { count, error in
if error == nil {
print("Unread count for tag: \(count)")
}
}
NCTag *tag; // obtained from createTagWithParams: or getTagsWithCompletion:
[tag getUnreadCountWithContainNoDisturb:NO
completion:^(NSInteger count, NCError * _Nullable error) {
if (error == nil) {
NSLog(@"Unread count for tag: %ld", (long)count);
}
}];
Clear unread count by tag
- Swift
- Objective-C
import NexconnChatSDK
let tag: Tag? = nil // Replace with a Tag instance from Tag.createTag/getTags
guard let tag else { return }
tag.clearUnreadCount { isCleared, error in
if isCleared {
print("Unread count cleared")
}
}
NCTag *tag; // obtained from createTagWithParams: or getTagsWithCompletion:
[tag clearUnreadCountWithCompletion:^(BOOL isSuccess, NCError * _Nullable error) {
if (isSuccess) {
NSLog(@"Unread count cleared");
}
}];
Delete channels by tag
Call clearChannelsWithIsDeleteMessage:completion: on an NCTag instance to delete all channels under the tag and unbind them:
- Swift
- Objective-C
import NexconnChatSDK
let tag: Tag? = nil // Replace with a Tag instance from Tag.createTag/getTags
guard let tag else { return }
// YES: also delete local messages. NO: only remove the channel record.
tag.clearChannels(isDeleteMessage: true) { error in
if error == nil {
print("Channels deleted")
}
}
NCTag *tag; // obtained from createTagWithParams: or getTagsWithCompletion:
// YES: also delete local messages. NO: only remove the channel record.
[tag clearChannelsWithIsDeleteMessage:YES completion:^(NCError * _Nullable error) {
if (error == nil) {
NSLog(@"Channels deleted");
}
}];
- If you keep local messages, users can see chat history when a new message arrives.
- If you delete local messages, history is no longer available locally. If cloud message storage is enabled, messages are still stored on the server. Use the server-side message deletion API to remove them.