objective-c – 在10.6下使用Scripting Bridge调用Finder时返回值不正确(但是没有错误)

前端之家收集整理的这篇文章主要介绍了objective-c – 在10.6下使用Scripting Bridge调用Finder时返回值不正确(但是没有错误)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我一直在浏览StackOverflow和其他地方的大量与Scripting Bridge相关的线程,并且似乎无法弄清楚为什么一个 Cocoa代码块使得对Scripting Bridge调用Finder不再正常工作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

我的直觉是,当它通过脚本桥时,某些东西正在被投射或转换得很奇怪,但我完全没有关于要检查什么或在哪里看的想法.我一直尝试打印出类名,因为从Finder中检索对象并将[SBObject * get]调用标记到各种与SB相关的赋值语句的末尾,但无济于事.

有任何想法吗?

UPDATE

好的,所以我已经发现上面的代码生成错误的位置,虽然我不觉得我更接近解决问题.事实证明,Scripting Bridge的懒惰评估掩盖了这个问题.如果在检索对FinderWindow的引用后,您插入以下两行代码

NSString * test = [folderWindow name];
NSLog(@“返回值==%@;错误消息==%@”,test,[[folderWindow lastError] localizedDescription]);

然后,Scripting Bridge尝试实际执行名称检索,失败,并返回一个稍微更具建设性的错误消息:

返回值==(null);错误消息==操作无法完成. (OSStatus错误-1700.)

这很棒(进步?!),但仍然没有让我更接近解决问题.该错误消息似乎表明在某个地方存在AE强制问题,但我不确定如何继续解决它.生成的Finder.h文件(以及Finder的AppleScript字典)都非常清楚我应该返回对FinderWindow对象的引用这一事实,并且打开folderWindow对象似乎验证一切正常,直到名称呼叫.

解决方法

看起来 -objectAtLocation:期待NSURL而不是HFS风格的路径:

Discussion

This method is a
generalization of objectAtIndex: for
applications where the “index” is not
simply an integer. For example,Finder
can specify objects using a NSURL
object as a location. In OSA this is
known as “absolute position,” a
generalization of the notion of
“index” in Foundation—it could be an
integer,but it doesn’t have to be. A
single object may even have a number
of different “absolute position”
values depending on the container.”

我只是尝试使用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
应用程序“Finder”的“furl”(“file:// localhost / Users / mdouma46 / Desktop /”)(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一样暗示/可选/多余.

尝试获取[folderWindow iconViewOptions]时,我收到一条无法识别的选择器错误消息:

– [SBObject iconViewOptions]:无法识别的选择器发送到实例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;
}

猜你在找的cocoa相关文章