可可脚本:接受并返回NSData

时间:2019-04-26 11:42:47

标签: macos applescript-objc cocoa-scripting

为了支持可编写脚本的Mac应用程序中的二进制数据交换,我希望尽可能使用AS-ObjC桥接器以NSData的形式接收和传递数据。

例如,我想在AppleScript中使此代码成为可能:

use framework "Foundation"

set theData to current application's NSData's dataWithContentsOfFile:"/some/binary/file"

tell application "MyApp"
    set raw value to theData
end tell

sdef包含一个值类型和属性:

<suite name="My Suite" code="Demo">
    <value-type name="ObjCNSData" code="NSDa">
        <cocoa class="NSData"/>
    </value-type>
    <class name="application" code="capp">
        <property name="raw data" code="rawD" type="ObjCNSData">
            <cocoa key="rawData"/>
        </property>

然后,我将转换处理程序实现为NSData的扩展,类似于Sketch示例将NSColor转换为值类型“ RGB颜色”的方式:

@implementation NSData(DemoScripting)
+ (NSData *)scriptingObjCNSDataWithDescriptor:(NSAppleEventDescriptor *)desc {
    id res = [desc coerceToDescriptorType:'NSDa'];
    // -> res is NULL, which is not getting me any further
}

desc的描述是:

<NSAppleEventDescriptor: 'obj '{
  'form':'ID  ',
  'want':'ocid',
  'seld':'optr'($E0A8430080600000$),
  'from':null()
}>

类似地,调用[NSScriptObjectSpecifier _scriptingSpecifierWithDescriptor:descriptor]也会返回NULL。

那么,如何在我的应用代码中找到实际的NSData对象?

如何将NSData对象返回给AppleScript?

1 个答案:

答案 0 :(得分:1)

Shane Stanley did indeed know a way,它甚至不需要我的应用程序中的多余代码-而是可以使用以下两个转换功能在AppleScript中完成所有操作:

use framework "Foundation"

set nsData1 to current application's NSData's dataWithContentsOfFile:"/etc/hosts"
set asData to my ASDataFromNSData(nsData1)
set nsData2 to my NSDataFromASData(asData)

on ASDataFromNSData(theData)
    set theCode to current application's NSHFSTypeCodeFromFileType("'rdat'")
    return (current application's NSAppleEventDescriptor's descriptorWithDescriptorType:theCode |data|:theData) as data
end ASDataFromNSData

on NSDataFromASData(asData)
    return (current application's NSArray's arrayWithObject:asData)'s firstObject()'s |data|()
end NSDataFromASData

看来rdat是用于此目的的特殊AppleScript类型,该框架使用NSData自动处理转换。我找不到在AE.framework标头中声明的类型。

尽管如此,我仍然必须在我的应用程序代码中显式处理此rdat类型。但是我不需要sdef中的value-type,并且可以将属性更改为:

<property name="raw data" code="rawD" type="any">
    <cocoa key="rawData"/>
</property>

将数据返回为rdat是相似的。我的-rawData方法:

return [NSAppleEventDescriptor descriptorWithDescriptorType:'rdat' data:myNSData];

这仅在我将属性类型声明为“ any”时有效。如果我使用type="rdat",则脚本调试器会将该类型显示为专用的原始数据类型,但是尝试在脚本中设置或获取属性时会出现-10000错误。