Сценарии Какао: принять и вернуть NSData - PullRequest
4 голосов
/ 26 апреля 2019

Для поддержки обмена двоичными данными в моем приложении Mac с поддержкой сценариев я хотел бы сделать возможным получение и доставку данных в виде NSData, используя мост AS-ObjC, если это возможно.

Например, мне нравится делать этот код возможным в 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
}

Описание описания:

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

Аналогично, вызов [NSScriptObjectSpecifier _scriptingSpecifierWithDescriptor:descriptor] также возвращает NULL.

Итак, как мне добраться до фактического объекта NSData внутри кода моего приложения?

А как мне вернуть объект NSData в AppleScript?

1 Ответ

1 голос
/ 26 апреля 2019

Шейн Стэнли действительно знал способ , и он даже не требует дополнительного кода в моем приложении - вместо этого все это можно сделать в 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, и я могу изменить свойство на:

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

Возвращение данных как rdat аналогично.Мой -rawData метод:

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

Это работает, только если я объявляю тип свойства как «любой», хотя.Если я использую type="rdat", Script Debugger показывает тип как выделенный необработанный тип данных, но затем я получаю -10000 ошибок при попытке установить или получить свойство в сценарии.

...