import CoreMedia import Foundation import NaturalLanguage extension AttributedString { public func sentences(maxLength: Int? = nil) -> [AttributedString] { let tokenizer = NLTokenizer(unit: .sentence) let string = String(characters) tokenizer.string = string let sentenceRanges = tokenizer.tokens(for: string.startIndex.. maxLength else { return [sentenceRange] } let wordTokenizer = NLTokenizer(unit: .word) wordTokenizer.string = string var wordRanges = wordTokenizer.tokens(for: sentenceStringRange).map { AttributedString.Index($0.lowerBound, within: self)! ..< AttributedString.Index($0.upperBound, within: self)! } guard !wordRanges.isEmpty else { return [sentenceRange] } wordRanges[0] = sentenceRange.lowerBound..] = [] for wordRange in wordRanges { if let lastRange = ranges.last, self[lastRange].characters.count + self[wordRange].characters.count <= maxLength { ranges[ranges.count - 1] = lastRange.lowerBound..