Cocoa 脚本:接受和 return NSData
Cocoa Scripting: Accept and return NSData
为了在我的可编写脚本的 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 Color":
@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]
returns NULL。
那么,如何在我的应用程序代码中获取实际的 NSData 对象?
我如何 return 一个 NSData 对象到 AppleScript?
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 的 headers 中声明的类型。
不过,我仍然必须在我的应用程序代码中显式处理此 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 错误。
为了在我的可编写脚本的 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 Color":
@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]
returns NULL。
那么,如何在我的应用程序代码中获取实际的 NSData 对象?
我如何 return 一个 NSData 对象到 AppleScript?
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 的 headers 中声明的类型。
不过,我仍然必须在我的应用程序代码中显式处理此 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 错误。