首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用脚本桥调用10.6以下的Finder返回值(但无错误抛出)

使用脚本桥调用10.6以下的Finder返回值(但无错误抛出)
EN

Stack Overflow用户
提问于 2011-03-31 23:43:36
回答 2查看 949关注 0票数 4

我已经在StackOverflow和其他地方浏览了很多与脚本桥相关的线程,并且似乎无法理解为什么一个Cocoa代码块对Finder的脚本桥调用不再在10.6下正确工作。(类似版本的代码在10.5下似乎正常工作,我不知道是什么导致了行为的改变。)

基本上,我正在尝试访问Finder窗口的一些显示选项。下面的代码块作为我的测试用例。我把它指向一个显示为图标的文件夹,当我运行代码时,没有一个错误阻塞行程,但我总是在最后得到一个无意义的响应(iconSize = 0)。

代码语言:javascript
复制
    // 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版本运行良好,即使指向同一个文件夹:

代码语言:javascript
复制
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

我的直觉是,当某些东西通过脚本桥时,它被抛出或转换得很奇怪,但是我完全不知道该检查什么或者在哪里查看。在此过程中,我尝试打印类名,从查找器检索对象,并将[SBObject *get]调用标记到与SB相关的各种赋值语句的末尾,但都没有效果。

有什么想法吗?

更新

好的,所以我已经发现在上面的代码中错误是在哪里生成的,尽管我并不觉得我离解决这个问题更近了。事实证明,脚本桥的懒惰评估掩盖了这个问题。如果在检索到FinderWindow的引用后,插入以下两行代码:

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调用之前一切正常。

EN

回答 2

Stack Overflow用户

发布于 2011-04-07 03:06:54

看起来,-objectAtLocation:期望的是NSURL,而不是HFS样式的路径:

"Discussion

此方法是对“索引”不仅仅是整数的应用程序的objectAtIndex:的推广。例如,Finder可以使用NSURL对象指定对象作为位置。在OSA中,这被称为“绝对位置”,是基金会中“index”概念的推广--它可以是一个整数,但不必是整数。根据容器的不同,单个对象甚至可能有许多不同的“绝对位置”值。

我刚刚尝试了使用NSURL的代码,它运行得很好。例如,下面的代码

代码语言:javascript
复制
- (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这样的混淆名称),所以类名略有不同。

因此,如果代码更改为以下内容,您的代码可能会正常工作:

代码语言:javascript
复制
// 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的属性:

代码语言:javascript
复制
NSLog(@"properties == %@", [finderWindow properties]);

产生类似于:

代码语言:javascript
复制
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;
}
票数 3
EN

Stack Overflow用户

发布于 2011-04-07 00:54:32

添加一些检查以确保finderfolderURLfolderPathHFS都是有效的。脚本桥可能返回一个表示“无值”而不是“零”的对象,而该对象可能返回另一个“无值”对象,因此您的任何检查都不会触发,因为它们都不是零,但是当您请求具有原始类型的东西时,它将返回0。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5507711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档