Convert NSAttributedString into Data for storage

后端 未结 2 1023
既然无缘
既然无缘 2020-12-03 22:42

I have a UITextView with attributed text and allowsEditingTextAttributes set to true.

I\'m trying to convert the attributed st

2条回答
  •  误落风尘
    2020-12-03 23:31

    You need to specify what kind of document data you would like to convert your attributed string to:


    .txt    // Plain Text Document Type (Simple Text)
    .html   // HTML  Text Document Type (Hypertext Markup Language) 
    .rtf    // RTF   Text Document Type (Rich text format document)
    .rtfd   // RTFD  Text Document Type (Rich text format document with attachment)
    

    update Xcode 10.2 • Swift 5 or later

    let textView = UITextView()
    textView.attributedText = .init(string: "abc",
                                    attributes: [.font: UIFont(name: "Helvetica", size: 16)!])
    if let attributedText = textView.attributedText {
        do {
            let htmlData = try attributedText.data(from: .init(location: 0, length: attributedText.length),
                                                   documentAttributes: [.documentType: NSAttributedString.DocumentType.html])
            let htmlString = String(data: htmlData, encoding: .utf8) ?? ""
            print(htmlString)
        } catch {
            print(error)
        }
    }
    

    Expanding on that:

    extension NSAttributedString {
    
        convenience init(data: Data, documentType: DocumentType, encoding: String.Encoding = .utf8) throws {
            try self.init(attributedString: .init(data: data, options: [.documentType: documentType, .characterEncoding: encoding.rawValue], documentAttributes: nil))
        }
    
        func data(_ documentType: DocumentType) -> Data {
            // Discussion
            // Raises an rangeException if any part of range lies beyond the end of the receiver’s characters.
            // Therefore passing a valid range allow us to force unwrap the result
            try! data(from: .init(location: 0, length: length),
                      documentAttributes: [.documentType: documentType])
        }
    
        var text: Data { data(.plain) }
        var html: Data { data(.html)  }
        var rtf:  Data { data(.rtf)   }
        var rtfd: Data { data(.rtfd)  }
    }
    

    Usage:

    let textView = UITextView()
    textView.attributedText = .init(string: "abc", attributes: [.font: UIFont(name: "Helvetica", size: 16)!])
    if let textData = textView.attributedText?.text {
        let text = String(data: textData, encoding: .utf8) ?? ""
        print(text)  // abc
    }
    if let htmlData = textView.attributedText?.html {
        let html = String(data: htmlData, encoding: .utf8) ?? ""
        print(html)  // /* 

    This will print

    abc
    /* 
    
    
    
    
    
    
    
    
    
    

    abc

    */

提交回复
热议问题