Tag Management

Complete guide to working with tag operations in the Zync SDK.

Table of contents

  1. Adding Tags
  2. Editing Tags
  3. Deleting Tags
  4. Getting Tags for a Module
  5. Finding Tags by Name
  6. Real-time Updates
    1. Observe Tag Changes

The Zync SDK provides comprehensive tag management through the ZyncTagsManager. Tags are used to categorize and organize content across different modules in the Zuper system. The SDK provides operations to add new tags, edit existing tags, delete tags, and search for tags by name.

Adding Tags

Create a new company tag in a specific module:

val result = zync.tags.addTag(
    module = ZuperModule.JOB,
    tagName = "urgent"
)

when (result) {
    is AddTagResult.Success -> {
        val createdTag = result.tag
        println("Created tag: ${createdTag.tagName} (${createdTag.tagUid})")
    }
    is AddTagResult.Failure -> {
        println("Error: ${result.error.message}")
        when (result.error) {
            is ZyncError.Network -> {
                println("Check your internet connection")
            }
            is ZyncError.Error -> {
                println("Error: ${result.error.message}")
            }
        }
    }
}
let result = try await zync.tags.addTag(
    module: ZuperModule.job,
    tagName: "urgent"
)

switch onEnum(of: result) {
case .success(let success):
    let createdTag = success.tag
    print("Created tag: \(createdTag.tagName) (\(createdTag.tagUid))")
case .failure(let failure):
    print("Error: \(failure.error.message)")
    switch onEnum(of: failure.error) {
    case .network:
        print("Check your internet connection")
    case .error(let error):
        print("Error: \(error.message)")
    }
}

Editing Tags

Update an existing company tag name:

val result = zync.tags.editTag(
    tagUid = "tag_uid_123",
    newTagName = "Updated Tag Name"
)

when (result) {
    is ZyncResult.Success -> {
        println("Tag updated successfully")
    }
    is ZyncResult.Failure -> {
        println("Error: ${result.error.message}")
        when (result.error) {
            is ZyncError.Network -> {
                println("Check your internet connection")
            }
            is ZyncError.Error -> {
                println("Error: ${result.error.message}")
            }
        }
    }
}
let result = try await zync.tags.editTag(
    tagUid: "tag_uid_123",
    newTagName: "Updated Tag Name"
)

switch onEnum(of: result) {
case .success:
    print("Tag updated successfully")
case .failure(let failure):
    print("Error: \(failure.error.message)")
    switch onEnum(of: failure.error) {
    case .network:
        print("Check your internet connection")
    case .error(let error):
        print("Error: \(error.message)")
    }
}

Deleting Tags

Soft delete a company tag by marking it as deleted:

val result = zync.tags.deleteTag("tag_uid_123")

when (result) {
    is ZyncResult.Success -> {
        println("Tag deleted successfully")
    }
    is ZyncResult.Failure -> {
        println("Error: ${result.error.message}")
        when (result.error) {
            is ZyncError.Network -> {
                println("Check your internet connection")
            }
            is ZyncError.Error -> {
                println("Error: ${result.error.message}")
            }
        }
    }
}
let result = try await zync.tags.deleteTag(tagUid: "tag_uid_123")

switch onEnum(of: result) {
case .success:
    print("Tag deleted successfully")
case .failure(let failure):
    print("Error: \(failure.error.message)")
    switch onEnum(of: failure.error) {
    case .network:
        print("Check your internet connection")
    case .error(let error):
        print("Error: \(error.message)")
    }
}

Getting Tags for a Module

Get tags for any module with offline-first approach and optional search functionality:

// Get all tags for a specific module
val result = zync.tags.getTags(ZuperModule.JOB)

// Get tags with search query
val searchResult = zync.tags.getTags(
    module = ZuperModule.GALLERY,
    searchQuery = "urgent"
)

when (result) {
    is MasterTagsResult.Success -> {
        val tags = result.data
        println("Found ${tags.size} tags")
        tags.forEach { tag ->
            println("- ${tag.tagName} (${tag.tagUid})")
        }
    }
    is MasterTagsResult.Failure -> {
        println("Error: ${result.error.message}")
    }
}
// Get all tags for a specific module
let result = try await zync.tags.getTags(module: ZuperModule.job)

// Get tags with search query
let searchResult = try await zync.tags.getTags(
    module: ZuperModule.gallery,
    searchQuery: "urgent"
)

switch onEnum(of: result) {
case .success(let success):
    let tags = success.data
    print("Found \(tags.count) tags")
    for tag in tags {
        print("- \(tag.tagName) (\(tag.tagUid))")
    }
case .failure(let failure):
    print("Error: \(failure.error.message)")
}

Finding Tags by Name

Search for tags by matching tag names within a specific module:

val result = zync.tags.getTagsByName(
    module = ZuperModule.JOB,
    tagNames = listOf("urgent", "high-priority", "critical")
)

when (result) {
    is GetTagsByNameResult.Success -> {
        val matchingTags = result.data
        println("Found ${matchingTags.size} matching tags")
        matchingTags.forEach { tag ->
            println("- ${tag.tagName} (${tag.tagUid})")
        }
    }
    is GetTagsByNameResult.Failure -> {
        println("Error: ${result.error.message}")
        when (result.error) {
            is ZyncError.Network -> {
                println("Check your internet connection")
            }
            is ZyncError.Error -> {
                println("Error: ${result.error.message}")
            }
        }
    }
}
let result = try await zync.tags.getTagsByName(
    module: ZuperModule.job,
    tagNames: ["urgent", "high-priority", "critical"]
)

switch onEnum(of: result) {
case .success(let success):
    let matchingTags = success.data
    print("Found \(matchingTags.count) matching tags")
    for tag in matchingTags {
        print("- \(tag.tagName) (\(tag.tagUid))")
    }
case .failure(let failure):
    print("Error: \(failure.error.message)")
    switch onEnum(of: failure.error) {
    case .network:
        print("Check your internet connection")
    case .error(let error):
        print("Error: \(error.message)")
    }
}

Real-time Updates

Observe Tag Changes

Monitor tag changes in real-time using delta sync events. This provides efficient updates when tags are modified via background sync:

// Collect tag changes for a specific module
val job = launch {
    zync.tags.observeTagChanges(ZuperModule.JOB)
        .collect { changeEvent ->
            when (changeEvent) {
                is TagChangeEvent.DeltaSync -> {
                    val updatedTags = changeEvent.tags
                    
                    // Sample 1: Show "New Updates Available" notification
                    if (updatedTags.isNotEmpty()) {
                        pendingTagUpdates += updatedTags.size
                        showUpdateAvailableChip("${updatedTags.size} new tag updates available")
                    }
                    
                    // Sample 2: Smart update/add logic
                    updatedTags.forEach { updatedTag ->
                        val existingIndex = currentTagList.indexOfFirst { it.tagUid == updatedTag.tagUid }
                        if (existingIndex != -1) {
                            // Update existing tag
                            currentTagList[existingIndex] = updatedTag
                            println("Updated existing tag: ${updatedTag.tagName}")
                        } else {
                            // Add new tag
                            currentTagList.add(updatedTag)
                            println("Added new tag: ${updatedTag.tagName}")
                        }
                    }
                    
                    // Refresh UI with updated list
                    notifyTagListChanged()
                }
            }
        }
}

// Cancel when done
job.cancel()
// Observe tag changes using SKIE's AsyncSequence support
let task = Task {
    for await changeEvent in zync.tags.observeTagChanges(module: .job) {
        switch changeEvent {
        case .deltaSync(let updatedTags):
            // Sample 1: Show "New Updates Available" notification
            if !updatedTags.isEmpty {
                pendingTagUpdates += updatedTags.count
                await showUpdateAvailableChip("\(updatedTags.count) new tag updates available")
            }
            
            // Sample 2: Smart update/add logic
            for updatedTag in updatedTags {
                if let existingIndex = currentTagList.firstIndex(where: { $0.tagUid == updatedTag.tagUid }) {
                    // Update existing tag
                    currentTagList[existingIndex] = updatedTag
                    print("Updated existing tag: \(updatedTag.tagName)")
                } else {
                    // Add new tag
                    currentTagList.append(updatedTag)
                    print("Added new tag: \(updatedTag.tagName)")
                }
            }
            
            // Refresh UI with updated list
            await notifyTagListChanged()
        }
    }
}

// Cancel when done
task.cancel()

Copyright © 2025 Zuper Inc. All rights reserved. This software is proprietary and confidential.