4

私は、StackOverflow やその他の場所にある Scripting Bridge 関連のスレッドをざっと調べてきましたが、Finder への Scripting Bridge 呼び出しを行う Cocoa コードのブロックが正しく機能しなくなった理由を突き止めることはできていないようです。 10.6未満。(同様のバージョンのコードは 10.5 で正常に動作するように見えましたが、動作が変化した原因はわかりません。)

基本的に、Finder ウィンドウの表示オプションのいくつかにアクセスしようとしています。テストケースとして次のコードブロックがあります。アイコンとして表示されているフォルダーを指しています。コードを実行すると、エラーブロックは発生しませんが、最後に無意味な応答 (iconSize = 0) が返されます。

    // Set up the Scripting Bridge
    FinderApplication *finder = [SBApplication applicationWithBundleIdentifier:@"com.apple.finder"];

    // Get an HFS-style reference to a specified folder
    // (folderPath is an NSString * containing a POSIX-style path to a folder)
    NSURL *folderURL = [NSURL fileURLWithPath:folderPath];
    NSString *folderPathHFS = (NSString *)CFURLCopyFileSystemPath((CFURLRef)folderURL, kCFURLHFSPathStyle);

    // Get the Finder-native folder reference
    FinderFolder* folder = [[finder folders] objectAtLocation:folderPathHFS];
    if (folder == nil) {
        NSLog(@"folder error: %@", [[folder lastError] localizedDescription]);
        return;
    }

    // Get the Finder-native container window associated with the folder
    [folder openUsing:finder withProperties:nil];
    FinderFinderWindow *folderWindow = [[folder containerWindow] get];
    if (folderWindow == nil) {
        NSLog(@"folderWindow error: %@", [[folderWindow lastError] localizedDescription]);
        return;
    }

    // Retrieve the view preferences for the folder
    FinderIconViewOptions *ivo = [folderWindow iconViewOptions];
    if (ivo == nil) {
        NSLog(@"ivo error: %@", [[ivo lastError] localizedDescription]);
    }

    // Get the current icon size
    int iconSize = (int)[ivo iconSize];

    // Display the icon size in our label
    if (iconSize > 0) {
        NSLog(@"successfully retrieved icon size: %d", iconSize);
    } else {
        NSLog(@"couldn't retrieve icon size");
    }

このコードの純粋な AppleScript バージョンは、同じフォルダーを指している場合でも正常に動作します。

tell application "Finder"
        set aFolder to the folder "<HFS path to folder in question>"
        set aFolderWindow to the container window of aFolder
        set aIVO to the icon view options of aFolderWindow
        return the icon size of aIVO
end tell

何かが Scripting Bridge を通過するときに何かが変な形でキャストまたは変換されているというのが私の本能ですが、何をチェックすればよいか、他にどこを見ればよいかについてはまったく考えがつきません。[SBObject *get]オブジェクトが Finder から取得され、さまざまな SB 関連の割り当てステートメントの最後に呼び出しをタグ付けするときに、途中でクラス名を出力しようとしましたが、役に立ちませんでした。

何か案は?


アップデート

OK、上記のコードでエラーが生成されている場所を発見しましたが、問題の修正にそれほど近づいているようには感じません. Scripting Bridge の遅延評価が問題を覆い隠していたことが判明しました。FinderWindow への参照を取得した後、次の 2 行のコードを挿入するとします。

NSString *test = [folderWindow name]; NSLog(@"Return value == %@; error message == %@", test, [[folderWindow lastError] localizedDescription]);

次に、Scripting Bridge は実際に名前の取得を実行しようとしますが失敗し、もう少し建設的なエラー メッセージが返されます。

Return value == (null); error message == The operation couldn’t be completed. (OSStatus error -1700.)

これは素晴らしい (進歩?!) ですが、それでも問題の解決に大きく近づくことはできません。このエラー メッセージは、どこかに AEcoercion の問題があることを示しているようですが、解決方法がわかりません。生成された Finder.h ファイル (および Finder の AppleScript 辞書) は、どちらも FinderWindow オブジェクトへの参照を取得する必要があるという事実を明確に示しており、オブジェクトを出力すると、呼び出しfolderWindowまですべてが正常であることを確認できるようです。name

4

2 に答える 2

3

HFS スタイルのパスではなく、次のパスを-objectAtLocation:期待しているようです。NSURL

"ディスカッション

このメソッドはobjectAtIndex:、「インデックス」が単なる整数ではないアプリケーションの一般化です。たとえば、Finder では、NSURL オブジェクトを場所として使用してオブジェクトを指定できます。OSA では、これは Foundation の「インデックス」の概念を一般化した「絶対位置」として知られています。コンテナによっては、1 つのオブジェクトに多数の異なる「絶対位置」値が含まれる場合もあります。」

NSURL を使用するコードを試したところ、問題なく動作しました。たとえば、次のコード

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    MDFinderApplication *finder = [SBApplication 
            applicationWithBundleIdentifier:@"com.apple.finder"];

    NSURL *URL = [NSURL fileURLWithPath:[@"~/Desktop" stringByStandardizingPath]];
    if (URL) {
         MDFinderFolder *folder = [[finder folders] objectAtLocation:URL];
         NSLog(@"folder == %@", folder);
    }
}

次の出力が生成されました。

folder == <FinderFolder @0x482b00: FinderFolder 'furl'("file://localhost/Users/mdouma46/Desktop/") of application "Finder" (78829)>

(注: Finder.h ファイルを作成するときに ( のような紛らわしい名前を避けるためにFinderFinderWindow) 別のパラメーターを使用したため、クラス名は少し異なります)。

したがって、次のように変更されていれば、コードはおそらく機能するはずです。

// Set up the Scripting Bridge
FinderApplication *finder = [SBApplication 
      applicationWithBundleIdentifier:@"com.apple.finder"];

// (folderPath is an NSString * containing a POSIX-style path to a folder)
NSURL *folderURL = [NSURL fileURLWithPath:folderPath];

// Get the Finder-native folder reference
FinderFolder* folder = [[finder folders] objectAtLocation:folderURL];
if (folder == nil) {
    NSLog(@"folder error: %@", [[folder lastError] localizedDescription]);
    return;
}

// Get the Finder-native container window associated with the folder
[folder reveal];
FinderFinderWindow *folderWindow = [folder containerWindow];
if (folderWindow == nil) {
    NSLog(@"folderWindow error: %@", [[folderWindow lastError] localizedDescription]);
    return;
}

// Retrieve the view preferences for the folder
// UPDATED: THE FOLLOWING WILL CAUSE AN "unrecognized selector":
FinderIconViewOptions *ivo = [folderWindow iconViewOptions];
if (ivo == nil) {
    NSLog(@"ivo error: %@", [[ivo lastError] localizedDescription]);
}

// Get the current icon size
int iconSize = (int)[ivo iconSize];

// Display the icon size in our label
if (iconSize > 0) {
    NSLog(@"successfully retrieved icon size: %d", iconSize);
} else {
    NSLog(@"couldn't retrieve icon size");
}

-get更新: 追加の呼び出しは必要ありません。get通常の AppleScript と同じように、暗黙的/オプション/不要です。

unrecognized selectorを取得しようとすると、エラー メッセージが表示されます[folderWindow iconViewOptions]

-[SBObject iconViewOptions]: unrecognized selector sent to instance 0x10018e270

ただし、FinderWindow のプロパティを印刷できます。

NSLog(@"properties == %@", [finderWindow properties]);

次のようなものを生成します。

properties == {
bounds = "NSRect: {{173, 289}, {1241, 663}}";
closeable = 1;
collapsed = 0;
columnViewOptions = "<SBObject @0x1fc5d010: columnViewOptions of
     FinderFinderWindow id 5696 of application \"Finder\" (78829)>";
currentView = "<NSAppleEventDescriptor: 'clvw'>";
floating = 0;
iconViewOptions = "<SBObject @0x1fc5d550: iconViewOptions of
    FinderFinderWindow id 5696 of application \"Finder\" (78829)>";
id = 5696;
index = 2;
listViewOptions = "<SBObject @0x1fc5cca0: listViewOptions of 
    FinderFinderWindow id 5696 of application \"Finder\" (78829)>";
modal = 0;
name = Applications;
objectClass = "<NSAppleEventDescriptor: 'brow'>";
position = "NSPoint: {173, 289}";
resizable = 1;
sidebarWidth = 0;
statusbarVisible = 1;
target = "<FinderFolder @0x1fc5db10: FinderFolder \"Applications\"
     of startupDisk of application \"Finder\" (78829)>";
titled = 1;
toolbarVisible = 1;
visible = 1;
zoomable = 1;
zoomed = 0;
}
于 2011-04-07T03:06:54.167 に答える
1

、、、およびがすべて有効finderであることを確認するために、いくつかのチェックを追加します。スクリプトブリッジは、nilではなく「novalue」を表すオブジェクトを返す可能性があり、そのオブジェクトは別の「no value」オブジェクトを返す可能性があるため、nilではないため、チェックはトリガーされません。プリミティブ型の場合、0を返します。folderURLfolderPathHFS

于 2011-04-07T00:54:32.123 に答える