我们如何从OS X JXA中读取/强制CFArray和CFString等值?

时间:2015-11-27 16:19:55

标签: objective-c macos javascript-automation jxa

如果您尝试通过ObjC桥读取/设置OSX输入语言,请编写以下代码段:

(function () {
    'use strict';

    ObjC.import('Carbon');
    ObjC.import('stdio');

    var sourceList = $.TISCreateInputSourceList(null, false);

    var current_source = $.TISCopyCurrentKeyboardInputSource();

    var cfs = $.TISGetInputSourceProperty(current_source, $.kTISPropertyInputSourceID);
    var cfn = $.TISGetInputSourceProperty(current_source, $.kTISPropertyLocalizedName)

    var sourceCount = $.CFArrayGetCount(sourceList)

    return $.CFArrayGetValueAtIndex(sourceList, 0)

})();

我们很快就会获得CF类型的obj引用返回值。在ObjC本身,这些可以被强制为NS值。是否可以在JavaScript for Applications中实现这一目标?

(我正在获取CF对象引用返回值,我从中没有成功提取字符串或其他原始值)

1 个答案:

答案 0 :(得分:3)

您可以通过首先重新绑定CFMakeCollectable函数将CF类型强制转换为NS类型,以便它获取'void *'并返回'id',然后使用该函数执行强制:

ObjC.bindFunction('CFMakeCollectable', [ 'id', [ 'void *' ] ]);

var cfString = $.CFStringCreateWithCString(0, "foo", 0); // => [object Ref]
var nsString = $.CFMakeCollectable(cfString);            // => $("foo")

为了在代码中更容易使用,您可以在Ref原型上定义.toNS()函数:

Ref.prototype.toNS = function () { return $.CFMakeCollectable(this); }

以下是如何将此新功能与TIS *功能结合使用:

ObjC.import('Carbon');

var current_source = $.TISCopyCurrentKeyboardInputSource();
var cfs = $.TISGetInputSourceProperty(current_source, $.kTISPropertyInputSourceID);

cfs.toNS() // => $("com.apple.keylayout.US")