JXA: Set UTF-8 encoding when writing files
Asked Answered
S

2

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.

Salivate answered 16/3, 2015 at 12:34 Comment(0)
C
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

Coexecutor answered 18/3, 2015 at 22:22 Comment(2)
Beat me to it! I was just posting that same answer, which also worked for me.Superorder
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.Salivate
M
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:].

Metabolism answered 16/3, 2015 at 22:38 Comment(1)
Thank you for your input. I read some documentation, edited my question and added some minimal examples.Salivate

© 2022 - 2024 — McMap. All rights reserved.