Search code examples
javascriptmacosapplescriptjavascript-automation

How can I write UTF-8 files using JavaScript for Mac Automation?


In short - what is the JavaScript for Mac Automation equivalent of AppleScript's as «class utf8» ?

I have a unicode string that I'm trying to write to a text file using JavaScript for Mac Automation.

When writing the string to the file, any unicode characters present become question marks in the file (ASCII char 3F).

If this was an AppleScript script instead of a JavaScript one, I could have solved this by adding the as «class utf8» raw statement as explained on Takashi Yoshida's Blog (https://takashiyoshida.org/blog/applescript-write-text-as-utf8-string-to-file/).

The script, however, is already written in JavaScript so I'm looking for the JavaScript equivalent to this AppleScript statement. Apple's page about raw statements addresses only AppleScript (https://developer.apple.com/library/content/documentation/AppleScript/Conceptual/AppleScriptLangGuide/conceptual/ASLR_raw_data.html).

To write the file, I am using Apple's own writeTextToFile JavaScript function example (https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/ReadandWriteFiles.html#//apple_ref/doc/uid/TP40016239-CH58-SW1). I added an as argument to the following call, according to the StandardAdditions dictionary:

// Write the new content to the file
app.write(text, { to: openedFile, startingAt: app.getEof(openedFile), as: "utf8" })

And tried all of the following strings (as written and also in lowercase form):

  • Unicode text
  • Unicode
  • Class utf8
  • «class utf8»
  • utf8
  • text
  • utf8 text

Apart for "text" (which resulted in the same question marks situation), using all of the above strings yielded a zero-bytes file.

I understand I might be wading into uncharted waters here, but if anyone reading this has dealt with this before and is willing to provide some pointers, I will be quite grateful 😋


Solution

  • If you want to ensure your file gets written with UTF8 encoding, use NSString's writeToFile:atomically:encoding:error function, like so:

    fileStr = $.NSString.alloc.initWithUTF8String( 'your string here' )
    fileStr.writeToFileAtomicallyEncodingError( filePath, true, $.NSUTF8StringEncoding, $() )
    

    You would think that writing an NSString object initialized from a UTF8 string would get written out as UTF8 but I've found from experience that writeToFile:atomically does not honor the encoding of the string being written out. writeToFile:atomically:encoding:error explicitly specifies which encoding to use. On top of that, writeToFile:atomically has been deprecated by Apple since OS X 10.4.