Creating an attributed string from a local HTML file

I am trying to show an attributed string from an HTML file and a CSS file inside a temporary directory in a Mac app. I used the code from the following article to create the temporary directory:

A helper for working with temporary files in Swift

I call the FileManager method createFile to create the HTML file.

func createHTMLFile(text: String, url: URL) {
    let fileManager = FileManager.default
    
    if let data = text.data(using: .utf8) {
        fileManager.createFile(atPath: url.path, contents: data)
    }
    
}

The call to createFile returns true. The HTML string is what I expect it to be.

I call the NSAttributedString init that takes a URL as an argument.

do {
	let attributedString = try NSAttributedString(url: previewURL.fileURL, 
		options: [.documentType:html], documentAttributes: nil)
} catch {
  	print(error)
}

The URL I pass to the init is what I expect. When I create the attributed string, the following error message appears in Xcode’s console:

Error Domain=NSCocoaErrorDomain Code=65806 "(null)"

A Google search for error code 65806 returns zero results.

I tried using the String struct’s write method to write the text to the URL.

func createHTMLFile(text: String, url: URL) {
    do {
        try text.write(to: url, atomically: false, encoding: .utf8)
    } catch {
        print(error)
    }
}

But I get the same 65806 error code.

I tried calling the NSAttributedString class method loadFromHTML to create the attributed string. According to the documentation, the loadFromHTML method creates an attributed string. But the method returns Void instead of an attributed string so I don’t see how I can create an attributed string using loadFromHTML.

What do I have to do to create an attributed string from a local HTML file?

The site https://osstatus.com/ is very useful for finding descriptions for error codes in Apple frameworks.

This is the result for 65806:

  • Framework: AppKit, AppKitErrors.h
  • Error Name: NSTextReadInapplicableDocumentTypeError
  • Error Code: 65806
  • Description: n/a
1 Like

Thanks for the information. Now I have an idea of where the problem is.

1 Like

Do you need a file? This works for me:

let string = #"<!DOCTYPE html><html><body><h1>Hello</h1><p>World</p></body></html>"#
let data = string.data(using: .utf8)!
let attrString = NSAttributedString(html: data, options: [.documentType : NSAttributedString.DocumentType.html], documentAttributes: nil)
print(attrString) // ✅

I need a file. I can create the attributed string by converting the HTML string to a Data object.

After doing some more digging, the problem is there's some invalid HTML. It's not a problem when converting to Data. But when it's in a file, the attributed string init is saying the file isn't a valid HTML file and generates an error.

I found a solution. My mistake was how I set the document type in the options argument when creating the attributed string.

Replace the following:

options: [.documentType:html]

With the following:

options: [.documentType:NSAttributedString.DocumentType.html]

I guess html was a variable of your own :sweat_smile: