2016-04-03 14 views
0

私のアプリには、AppleScriptに提供したいと思っている生データコンテンツがあります。それをサポートする他のオブジェクトに設定します。Cocoa Scripting:生データのような特別な文字列型を使用する

ここでは、これを達成するためにどのデータ型が使用されているのか分かりません。

たとえば、スクリプトエディタからこの出力を参照してください:

tell application "Script Editor" 
    the clipboard as record 
    --> {Unicode text:"text", 
     «class BBLM»:«data BBLM6C6C756E», 
     string:"text"} 
end tell 

私は、«...データ»これらを返す明らかに4 - 文字コードと、六角はstring-の組み合わせであるにはどうすればよいです実際のデータの符号化されたバイト。

スクリプト可能なプロパティからrawバイトデータを含むNSDataオブジェクトを返そうとしましたが、動作しません。

更新

scripting<type>Descriptorscripting<type>WithDescriptorの実施に関係しています表示されます。 Sketchサンプルコードで使用されている以外のドキュメントは見つかりません。私は私のSdefでそのようなカスタムタイプを定義した場合、これらのタイプのために呼び出されると仮定します。

ただし、私は事前に送信したいタイプがわからないので、Sdefで事前定義することはできません。私はthe clipboardに似た状況にあります:返すクリップボードのようなデータがあるので、実行時に4文字の型しか知りません。つまり、私はこれらのハンドラーを通して聞かれることはありません。クリップボードの実装と同じように、これらの型を一般的に作成して受け取るには、別の方法が必要です。

+0

'NSData'オブジェクトはAppleScriptのサポートが基本クラスで表現することはできませんNSCoding''に準拠したカスタム '値-types'のために使用されています。例えば、基本的なAppleScriptの型 'point'と' rectangle'は 'NSData'で包まれたC型です。カスタムの 'value-type'を定義するには、sdefファイルにターゲットクラスを用意し、' scripting ... 'メソッドをターゲットクラスのカテゴリに実装する必要があります。 – vadian

+0

私の他の質問(http://stackoverflow.com/questions/36363705/)であなたのコメントに基づいてもう少し掘り下げた後、私は最終的にあなたが意味していたことを理解していませんでした。すべてNSAppleEventDescriptorを使用するようになります。NSAppleEventDescriptorは、実行中のApplescriptに値を返す前に、最終的にすべてのCocoaタイプが割り当てられるタイプです。 –

+1

まさに、Cocoa Scriptingはすばらしいことですが、文書化されておらず、間違いやすいです。ここスイスでは、「s'isch en saich」(「お尻の痛み」に似ています) – vadian

答えて

1

RE:「しかし:私は種類を知ることができません私は事前に送っておきたいので、Sdefで事前に定義することはできません」

この問題を解決する方法があります。ユーザーフィールドレコード(typeUserField)という特殊なリスト構造を返すことができます。このレコードには、Key記述子とValue記述子が交互に含まれています。SDEFには何も定義する必要はありません。

は、ここで私は昨年ASOCのメーリングリストに投稿さ項目です: http://lists.apple.com/archives/applescriptobjc-dev/2015/Jan/msg00036.html

そしてここNSDictionaryのからtypeUserFieldレコードを構築する(AppleScriptの-ObjectiveCコードを使用して)コードです。

# ASOC implementation of - (NSAppleEventDescriptor *)scriptingRecordDescriptor for an NSDictionary 
# Creates an empty record descriptor and an empty list descriptor, then 
# Iterates over the dictionary and inserts descriptors for each key and each value into the list descriptor 
# Finally, populates the record descriptor with the type 'usrf' and the list descriptor 

on makeUserRecordDescriptor(aDict) 

log aDict 

set recordDescriptor to aedClass's recordDescriptor() 
set listDescriptor to aedClass's listDescriptor() 

set typeUserField to 1970500198 -- 'usrf' 

set itemIndex to 1 -- AS records are 1-based 

repeat with aKey in aDict's allKeys() 

    set aVal to aDict's valueForKey_(aKey) 

    -- The values can be several different types. This code DOES NOT handle them all. 

    set isStringValue to aVal's isKindOfClass_(nssClass's |class|) = 1 
    set isNumericValue to aVal's isKindOfClass_(nsnClass's |class|) = 1 
    set isBooleanValue to aVal's className()'s containsString_("Boolean") = 1 

    -- Insert a descriptor for the key into the list descriptor 

    set anItem to aedClass's descriptorWithString_(aKey) 
    listDescriptor's insertDescriptor_atIndex_(anItem, itemIndex) 
    set itemIndex to itemIndex + 1 

    -- Insert a descriptor (of the correct type for the value) into the list descriptor 

    if isStringValue 
     set anItem to aedClass's descriptorWithString_(aVal) 
    else if isBooleanValue 
     set anItem to aedClass's descriptorWithBoolean_(aVal's boolValue()) 
    else if isNumericValue 
     set intValue to aVal's intValue() 
     set fpValue to aVal's doubleValue() 

     if intValue = fpValue 
      set anItem to aedClass's descriptorWithInt32_(aVal's intValue()) 
     else 
      set anItem to aedClass's descriptorWithString_(aVal's stringValue) # TODO: 'doub' 
     end 
    else 
     set anItem to aedClass's descriptorWithString_("Unhandled Data Type") 
    end 

    listDescriptor's insertDescriptor_atIndex_(anItem, itemIndex) 
    set itemIndex to itemIndex + 1 

end 

recordDescriptor's setDescriptor_forKeyword_(listDescriptor, typeUserField) 

return recordDescriptor 

エンド

0

魔法はNSAppleEventDescriptorを使用しています。それは多くのイニシャライザを提供します。これは最終的に呼び出し元のAppleScript(またはJXAなど、スクリプトエンジンを使用するもの)に返される値を保持します。

NSStringやNSNumberなどの文字列など、Cocoa Scriptingレイヤーに返される値は、最終的にNSAppleEventDescriptorオブジェクトに割り当てられ、そのステップでAppleEvent内部形式に変換されます。

したがって、文字列を返す場合は、 NSDataオブジェクトに格納し、私がしなければならないすべては私の財産メソッドからこのです:

-(id)returnSomeBytes { 
    return [NSAppleEventDescriptor descriptorWithDescriptorType:'Raw ', myNSDataObject]; 
} 

これは«data Raw ...»としてのAppleScriptになってしまいます。

スクリプトエンジンがNSDataを自動的に変換しない理由も理解しました。NSDataが継承しないタイプコードが必要です。

逆も同様です。このような生データはNSAppleEventDescriptorとしてコードに渡されます。これを適切にデコードすることができます。

1

RE:「...実装するスクリプト<キー>記述やスクリプト<キー> WithDescriptor私はこの上の任意のドキュメントを見つけることができない...」

開始する最初の場所は、「キー値コーディングで、 Cocoa Scripting Guide(2008)の「Cocoa Scripting」のセクションを参照してください。メソッド名に型を埋め込む、これらのメソッドの全面的なスルーがあります。多くは、財団のNSScriptKeyValueCoding Protocol Referenceページにも記載されていますが、それらを見つけるには、「ディスカッション」セクションを読んでおく必要があります。例えば、中:

- (id)valueWithUniqueID:(id)uniqueID inPropertyWithKey:(NSString *)key 

議論は言う: "メソッドvalueIn <キー> WithUniqueID:。それが存在する場合に呼び出されます"

だから、ウィジェットクラスでは、あなたはvalueInWidgetsWithUniqueIDを実装します:

スクリプト<キー>記述やスクリプト<キー> WithDescriptorをしている、あなたはあなたのアプリケーションの.sdefで要素を使用するときに使用されている特殊な変換ハンドラです彼らがなぜ3つの整数のリストであるtypeRGBColorデータ型を扱うためにSketchに登場するのでしょうか?私はこれらのいずれかのスケッチ、コードの外に文書を見つけることはできませんが、私は

scriptingRGBColorDescriptor 

は内のメソッドによって呼び出されたことを確認することができます

NSObject(NSScriptAppleEventConversion) 
NSAppleEventDescriptor(NSScriptConversion) 
+0

私のテストでは、 'script WithDescriptor'関数を実装しなくても、' valueWithUniqueID: 'ハンドラを通して元の' NSAppleEventDescriptor'を取得し、 'data'と' descriptorType'を抽出することができます。 –

+0

Sdef内のプロパティの特定の型を指定すると、スクリプト記述 Descriptorが必要になります。タイプに "any"を使用する場合、これは必要ありません。 –

+1

これは、それらが記述子強制変換プロセスの一部として呼び出されていることを確認しているようです。 「任意の」タイプを指定すると、結果を強制しないようにエンジンに指示します。 –

関連する問題