Swift NSAttributedString Trim

Create extension of NSAttributedString as below.

extension NSAttributedString {
     public func attributedStringByTrimmingCharacterSet(charSet: CharacterSet) -> NSAttributedString {
         let modifiedString = NSMutableAttributedString(attributedString: self)
        modifiedString.trimCharactersInSet(charSet: charSet)
         return NSAttributedString(attributedString: modifiedString)
     }
}

extension NSMutableAttributedString {
     public func trimCharactersInSet(charSet: CharacterSet) {
        var range = (string as NSString).rangeOfCharacter(from: charSet as CharacterSet)

         // Trim leading characters from character set.
         while range.length != 0 && range.location == 0 {
            replaceCharacters(in: range, with: "")
            range = (string as NSString).rangeOfCharacter(from: charSet)
         }

         // Trim trailing characters from character set.
        range = (string as NSString).rangeOfCharacter(from: charSet, options: .backwards)
         while range.length != 0 && NSMaxRange(range) == length {
            replaceCharacters(in: range, with: "")
            range = (string as NSString).rangeOfCharacter(from: charSet, options: .backwards)
         }
     }
}

and use in viewController where you want to use. like this

let attstring = NSAttributedString(string: "this is test message. Please wait.                   ")
let result = attstring.attributedStringByTrimmingCharacterSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

This works even with emoji in the text

extension NSAttributedString {

    /** Will Trim space and new line from start and end of the text */
    public func trimWhiteSpace() -> NSAttributedString {
        let invertedSet = CharacterSet.whitespacesAndNewlines.inverted
        let startRange = string.utf16.description.rangeOfCharacter(from: invertedSet)
        let endRange = string.utf16.description.rangeOfCharacter(from: invertedSet, options: .backwards)
        guard let startLocation = startRange?.upperBound, let endLocation = endRange?.lowerBound else {
            return NSAttributedString(string: string)
        }

        let location = string.utf16.distance(from: string.startIndex, to: startLocation) - 1
        let length = string.utf16.distance(from: startLocation, to: endLocation) + 2
        let range = NSRange(location: location, length: length)
        return attributedSubstring(from: range)
    }

}

USAGE

let attributeString = NSAttributedString(string: "\n\n\n     Hi 👋 👩‍👩‍👧👩‍👩‍👦‍👦👩‍👩‍👧‍👧👨‍👨‍👦👩‍👦👨‍👨‍👧‍👧👨‍👨‍👦‍👦👨‍👨‍👧‍👦👩‍👧‍👦👩‍👦‍👦👩‍👧‍👧👨‍👦 buddy.              ")
let result = attributeString.trimWhiteSpace().string // Hi 👋 👩‍👩‍👧👩‍👩‍👦‍👦👩‍👩‍👧‍👧👨‍👨‍👦👩‍👦👨‍👨‍👧‍👧👨‍👨‍👦‍👦👨‍👨‍👧‍👦👩‍👧‍👦👩‍👦‍👦👩‍👧‍👧👨‍👦 buddy.