我已经在StackOverflow和其他地方浏览了很多与脚本桥相关的线程,并且似乎无法理解为什么一个Cocoa代码块对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我的直觉是,当某些东西通过脚本桥时,它被抛出或转换得很奇怪,但是我完全不知道该检查什么或者在哪里查看。在此过程中,我尝试打印类名,从查找器检索对象,并将[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调用之前一切正常。
发布于 2011-04-07 03:06:54
看起来,-objectAtLocation:期望的是NSURL,而不是HFS样式的路径:
"Discussion“
此方法是对“索引”不仅仅是整数的应用程序的objectAtIndex:的推广。例如,Finder可以使用NSURL对象指定对象作为位置。在OSA中,这被称为“绝对位置”,是基金会中“index”概念的推广--它可以是一个整数,但不必是整数。根据容器的不同,单个对象甚至可能有许多不同的“绝对位置”值。
我刚刚尝试了使用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-07 00:54:32
添加一些检查以确保finder、folderURL和folderPathHFS都是有效的。脚本桥可能返回一个表示“无值”而不是“零”的对象,而该对象可能返回另一个“无值”对象,因此您的任何检查都不会触发,因为它们都不是零,但是当您请求具有原始类型的东西时,它将返回0。
https://stackoverflow.com/questions/5507711
复制相似问题