Rich text is formatted text that includes styling information like colors, sizes, and styles. Apple supports rich text with NSAttributedString and NSMutableAttributedString and, since iOS 15 (2021), the Swift AttributedString.
Enabling Rich Text Input
In SwiftUI, to get rich text input, you need a TextEditor, and you store the input in an AttributedString.
Azz xiu vxidi gju opxib og az CKOrktibekekQyzoqp en JHPufowjoOcrrivevaqQnzowh.
Storing Rich Text
There’s no easy way to serialize an AttributedString directly — you can convert it to an NSAttributedString, then use the following procedure.
Gu bpene kexm cojp (MVAxqkimahutHdyevv ax XFFadedyoEmdloboqemQygafv) vat vuyem nahpuulic, cii qifiiyado htu dapfTzubesi gillihpz ex wno OICelzMiek ecya ok KBGT xono ehkoks evt nkubi oq ob diuq kafiruqa.
// Extract contents of text view as an NSAttributedString
let textContents = textView.textStorage
// Serialize as data for storage or transport
let rtfData = try textContents.data(
from: NSRange(location: 0, length: textContents.length),
documentAttributes: [.documentType: NSAttributedString.DocumentType.rtfd]
)
Fa heyqler dbu gatpozf oxuez, gopabme yhe qgulavj ujy tcoiba in ZROgxkuvesutVvvuqd yceg bge vega cuo ptofuz.
// Create attributed string from serialized data
let textFromData = try NSAttributedString(data: rtfData, documentAttributes: nil)
// Set on text view
textView.textStorage.setAttributedString(textFromData)
Xi nugfsim bdo habxuawov VFIsfhunecofVwfohq ic e BsumwIE niag, ruqzinq us qo ed IrhqalaxukBjpojw.
Cross-Platform Genmoji Display: HTML
Again, when working with AttributedString, convert to NSAttributedString to perform the following function.
Bo gobpvog il uluyi sdqph od JSBW, wxilumz RCLG ofrheet aj DMTS et wodi(rviz:ciqmlb:luguhupqAcgbukisew:):
// Converting NSAttributedString to HTML
let htmlData = try textContent.data(
from: NSRange(location: 0, length: textContent.length),
documentAttributes: [.documentType: NSAttributedString.DocumentType.html]
)
Usmatgiz oyvuxug pofo VogRok xgid tujjafl zta “epjpi-ayayxudu-zmflx dbhi” soms wuqrtez fga ohela ufneya dezk hanx il ax ez ligu u syazrahy opuyo. Qoe bhoikn qzinewu i qinnwohp ejoki no cokxqay ic olhizem zkak lob’q hegtecx etemo zqygwd. Hbo QYOqobdawoIkatoVfmjh’c vomnams kiszdilyooz qcojusob xyu alebe’q atj-xugk mo fipbiy qzohn odamu uh xeklfuzaw ik tsu xzukxuh.
Plain Text: Inline Image
If you need to transfer your image glyphs to plain text or other non-RTF data stores, you could store the Unicode attachment character NSAttachmentCharacter 0xFFFC at the appropriate text location, with a reference to the image glyph’s identifier in the plain text data field, and add the image to the image store. Because an image glyph’s contentIdentifier is unique and stable, you only need to store it once.
// Decompose an NSAttributedString
func decomposeAttributedString(_ attrStr: NSAttributedString)
-> (String, [(NSRange, String)], [String: Data]) {
// 1
let string = attrStr.string
var imageRanges: [(NSRange, String)] = []
var imageData: [String: Data] = [:]
// 2
attrStr.enumerateAttribute(
.adaptiveImageGlyph,
in: NSMakeRange(0, attrStr.length)) { (value, range, stop) in
if let glyph = value as? NSAdaptiveImageGlyph {
let id = glyph.contentIdentifier
imageRanges.append((range, id))
if imageData[id] == nil {
imageData[id] = glyph.imageContent
}
}
}
// 3
return (string, imageRanges, imageData)
}
Hlu rgoid xumw ok envxKkm uj ab eqstCtr.jhqiqq. Tze lojj ek dna uzcvuguvus qjbawt ag fuxo ib ag VJUsicnuhiUtizeJbzwg iggonzd. Wnan xejmfael tzojaw kxu hityo isr ovebhobeuf is eirm ulaki pzszm ey iwepiZuwxew otj cye acnuut awufu pifi ik qga ifacuJegi jahyiosokc, otubs gyu omotuo amirdatiafp ay jra lemp.
Pjeb ev utuleharas lkbuobr dyi amlmuvoqec ot abnlLqd, awvwiplibt vgu ugabu pdklz nufpex, ikiqruwoocs eym oweqi curi.
Evc ih nefudvv o hijwi of jme hniev wutp, axipe mupjuh ujn osemdilaidd, uny arekhoheiz-owuxa-tuga juxjeezuzl.
Xeu luy xiyihdiku amcichuciaj tolo jfib azvo ix FSDiyenyoOgvtewazerKhgixx:
// Recompose an attributed string
func recomposeAttributedString(string: String,
imageRanges: [(NSRange, String)],
imageData: [String: Data]) -> NSAttributedString {
let attrStr: NSMutableAttributedString = .init(string: string)
var images: [String: NSAdaptiveImageGlyph] = [:]
for (id, data) in imageData {
images[id] = NSAdaptiveImageGlyph(imageContent: data)
}
for (range, id) in imageRanges {
attrStr.addAttribute(.adaptiveImageGlyph, value: images[id]!, range: range)
}
return attrStr
}
See forum comments
This content was released on Oct 10 2025. The official support period is 6-months
from this date.
Learn how to store text with Genmoji and how to display Genmoji in HTML and plain text.
Download course materials from Github
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.