10

If I write a textfile using the standardadditions, I obviously can configure the encoding in a parameter bag. In AppleScript I would write «class utf8» but which value to use in JXA? I tried the Strings "UTF8", "utf8", "class utf8" without success. The Error is always: "Error: Can't convert types. (-1700)". If I use "text" the file is written in MACROMAN.

Standalone example below:

var exportFileWriter = fileWriter('/Users/norman/mini.txt');
exportFileWriter.write('äöü');
exportFileWriter.close();


function fileWriter(pathAsString) {
    'use strict';

    var app = Application.currentApplication();
    app.includeStandardAdditions = true;

    var path = Path(pathAsString);
    var file = app.openForAccess(path, {writePermission: true});

    /* reset file length */
    app.setEof(file, {to: 0});

    return {
        write: function(content) {
            /* How can I write UTF-8? */
            app.write(content, {to: file, as: 'text'});
        },
        close: function() {
            app.closeAccess(file);
        }
    };
}

Addition after foo's answer:

I read the relevant paragraphs in the documentation https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/index.html#//apple_ref/doc/uid/TP40014508-CH109-SW17

and

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/index.html#//apple_ref/occ/instm/NSString/writeToFile:atomically:encoding:error:

to use the ObjectiveC bridge instead. This example works

str = $.NSString.alloc.initWithUTF8String('foo')
str.writeToFileAtomically('/tmp/foo', true)

If I understand correctly, the following example should work, because of the convention how ObjectiveC Methods are named within the bridge (remove colon, add camelcase), but it doesn't. No file has been written and the returnvalue is false.

str = $.NSString.alloc.initWithUTF8String('foo')
str.writeToFileAtomicallyEncodingError('/tmp/foo', true, 'UTF-8', null);

What did I wrong? I do not even know how to pass in a proper Errorhandler as 4th parameter and if the 3rd param has the proper value.

nwehrle
  • 103
  • 6

2 Answers2

10

please try

str = $.NSString.alloc.initWithUTF8String('foo');
str.writeToFileAtomicallyEncodingError('/tmp/foo', true, $.NSUTF8StringEncoding, null);

Worked here! The available encodings are listed inside the NSString documentation (see your link)!
Enjoy, Michael / Hamburg

ShooTerKo
  • 2,242
  • 1
  • 13
  • 18
  • Beat me to it! I was just posting that same answer, which also worked for me. – Justin Putney Mar 18 '15 at 22:35
  • Thank you. It works well. I would upvote your and foo's answer if I had enough reputation. My workaround till foo came up with ObjC Bridge was to use node.js and require 'encoding': encoding.convert(data, 'UTF-8', 'MACROMAN'); Grüsse aus Zürich nach Hamburg. – nwehrle Mar 19 '15 at 07:53
4

JXA's Apple event bridge is flawed with many crippled and missing features (e.g. the ability to use raw AE codes). Use its ObjC bridge instead; see -[NSString writeToFile:atomically:encoding:error:].

foo
  • 3,171
  • 17
  • 18
  • Thank you for your input. I read some documentation, edited my question and added some minimal examples. – nwehrle Mar 18 '15 at 11:47