Mentions in Posts

Mentions enable users to tag other community members in posts, creating direct engagement opportunities and enhancing social interaction. The social.plus SDK provides comprehensive mention functionality with metadata support for custom rendering and notification systems.

Overview

Enhanced Engagement

Direct user engagement through mentions increases interaction and community building

Custom Rendering

Flexible metadata system supports custom mention display and interaction patterns

Mention Features

FeatureDescriptionBenefit
User TaggingTag specific users in post contentDirect engagement
Metadata SupportCustom rendering informationFlexible UI design
Notification IntegrationAutomatic notifications for mentioned usersReal-time engagement
ValidationVerify user existence and permissionsData integrity
Update SupportModify mentions in existing postsContent maintenance

Create Post with Mentions

Include user mentions when creating new posts with comprehensive metadata for custom rendering.
import AmitySDK

class PostMentionManager {
    private let client: AmityClient
    
    init(client: AmityClient) {
        self.client = client
    }
    
    // Create text post with mentions
    func createTextPostWithMentions(
        text: String,
        mentionedUserIds: [String],
        communityId: String? = nil,
        completion: @escaping (Result<AmityPost, Error>) -> Void
    ) {
        // Build mention metadata
        let mentionMetadata = buildMentionMetadata(text: text, userIds: mentionedUserIds)
        
        let builder = AmityTextPostBuilder()
            .setText(text)
            .setMentionUsers(mentionedUserIds)
            .setMetadata(mentionMetadata)
        
        let repository = AmityPostRepository(client: client)
        
        if let communityId = communityId {
            repository.createPost(builder, targetId: communityId, targetType: .community)
                .subscribe { result in
                    completion(result)
                }
        } else {
            repository.createPost(builder, targetType: .user)
                .subscribe { result in
                    completion(result)
                }
        }
    }
    
    // Build mention metadata for rendering
    private func buildMentionMetadata(text: String, userIds: [String]) -> [String: Any] {
        var mentions: [[String: Any]] = []
        
        for userId in userIds {
            // Find mention positions in text
            let mentionPattern = "@\(userId)"
            let ranges = text.ranges(of: mentionPattern)
            
            for range in ranges {
                mentions.append([
                    "userId": userId,
                    "type": "user",
                    "index": text.distance(from: text.startIndex, to: range.lowerBound),
                    "length": mentionPattern.count
                ])
            }
        }
        
        return [
            "mentioned": mentions
        ]
    }
    
    // Create post with advanced mention formatting
    func createPostWithFormattedMentions(
        text: String,
        mentions: [(userId: String, displayName: String, range: NSRange)],
        communityId: String? = nil
    ) {
        let userIds = mentions.map { $0.userId }
        
        // Build rich metadata
        let mentionObjects = mentions.map { mention in
            return [
                "userId": mention.userId,
                "displayName": mention.displayName,
                "type": "user",
                "index": mention.range.location,
                "length": mention.range.length
            ]
        }
        
        let metadata = [
            "mentioned": mentionObjects,
            "version": "1.0"
        ]
        
        let builder = AmityTextPostBuilder()
            .setText(text)
            .setMentionUsers(userIds)
            .setMetadata(metadata)
        
        let repository = AmityPostRepository(client: client)
        
        if let communityId = communityId {
            repository.createPost(builder, targetId: communityId, targetType: .community)
                .subscribe { result in
                    print("Post with mentions created: \(result)")
                }
        }
    }
    
    // Validate mentions before creating post
    func validateAndCreatePost(
        text: String,
        mentionedUserIds: [String],
        completion: @escaping (Result<AmityPost, Error>) -> Void
    ) {
        // Validate users exist
        let userRepository = AmityUserRepository(client: client)
        
        let group = DispatchGroup()
        var validUserIds: [String] = []
        var errors: [Error] = []
        
        for userId in mentionedUserIds {
            group.enter()
            
            userRepository.getUser(withId: userId) { result in
                switch result {
                case .success:
                    validUserIds.append(userId)
                case .failure(let error):
                    errors.append(error)
                }
                group.leave()
            }
        }
        
        group.notify(queue: .main) {
            if !errors.isEmpty {
                completion(.failure(errors.first!))
                return
            }
            
            self.createTextPostWithMentions(
                text: text,
                mentionedUserIds: validUserIds,
                completion: completion
            )
        }
    }
}

extension String {
    func ranges(of substring: String) -> [Range<String.Index>] {
        var ranges: [Range<String.Index>] = []
        var startIndex = self.startIndex
        
        while startIndex < self.endIndex,
              let range = self.range(of: substring, range: startIndex..<self.endIndex) {
            ranges.append(range)
            startIndex = range.upperBound
        }
        
        return ranges
    }
}

Update Post with Mentions

Modify existing posts to add, remove, or update user mentions while maintaining post integrity.
The pattern for adding mentions to posts is consistent across all post types (text, image, video, file). The examples show text posts, but the same creation process applies to any post type.
// Update existing post with new mentions
func updatePostWithMentions(
    postId: String,
    newText: String,
    mentionedUserIds: [String],
    completion: @escaping (Result<AmityPost, Error>) -> Void
) {
    // Build updated mention metadata
    let mentionMetadata = buildMentionMetadata(text: newText, userIds: mentionedUserIds)
    
    let builder = AmityTextPostBuilder()
        .setText(newText)
        .setMentionUsers(mentionedUserIds)
        .setMetadata(mentionMetadata)
    
    let repository = AmityPostRepository(client: client)
    repository.editPost(withId: postId, builder: builder)
        .subscribe { result in
            completion(result)
        }
}

// Remove all mentions from a post
func removeMentionsFromPost(
    postId: String,
    newText: String,
    completion: @escaping (Result<AmityPost, Error>) -> Void
) {
    let builder = AmityTextPostBuilder()
        .setText(newText)
        .setMentionUsers([]) // Empty mention list
        .setMetadata([:])    // Empty metadata
    
    let repository = AmityPostRepository(client: client)
    repository.editPost(withId: postId, builder: builder)
        .subscribe { result in
            completion(result)
        }
}

Advanced Mention Features

Best Practices

Performance

Validate mentions before post creation and batch operations for efficiency

User Experience

Provide clear visual feedback for mentions and auto-completion features

Privacy

Respect user privacy settings and community mention policies

Accessibility

Ensure mentions work with screen readers and keyboard navigation

Render Mentions

For comprehensive mention rendering guidelines, including metadata structure, custom mention objects, and UI implementation patterns, refer to the Mentions Core Concept documentation.

Common Implementation Patterns

class MentionInputViewController: UIViewController {
    @IBOutlet weak var textView: UITextView!
    private let mentionManager = PostMentionManager()
    
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        let currentText = textView.text as NSString
        let updatedText = currentText.replacingCharacters(in: range, with: text)
        
        // Check if user is typing a mention
        if text == "@" {
            showUserSuggestions()
        } else if updatedText.contains("@") {
            updateUserSuggestions(for: updatedText)
        }
        
        return true
    }
    
    private func showUserSuggestions() {
        // Show user picker or autocomplete list
    }
    
    private func updateUserSuggestions(for text: String) {
        let mentions = mentionManager.extractMentionsFromText(text)
        // Update suggestion list based on partial mentions
    }
}
Notification Behavior: When updating posts with mentions, the mentioned users will NOT receive new notifications. Mention notifications are only sent when posts are initially created.
Cross-Platform Consistency: The mention metadata structure is consistent across all platforms, enabling seamless mention rendering regardless of the client implementation.