我一直在StackOverflow和其他地方浏览大量与Scripting Bridge相关的线程,并且似乎无法弄清楚为什么一块Cocoa代码使得Scripting Bridge调用Finder no更长时间在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相关的赋值语句的末尾,但无济于事。
有什么想法吗?
更新
好的,所以我发现在哪里在上面的代码中生成错误,虽然我不觉得我更接近解决问题。事实证明,Scripting Bridge的懒惰评估掩盖了这个问题。如果在检索对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.)
这很棒(进步?!),但仍然没有让我更接近解决问题。该错误消息似乎表明在某个地方存在AE强制问题,但我不确定如何继续解决它。生成的Finder.h文件(以及Finder的AppleScript字典)都非常清楚我应该返回对FinderWindow对象的引用,打印folderWindow
对象似乎验证一切正常直到name
来电。
答案 0 :(得分:3)
看起来-objectAtLocation:
期待NSURL
而不是HFS风格的路径:
“的讨论强>
这个方法是一个
objectAtIndex:
的推广 “索引”不适用的应用程序 只是一个整数。例如,Finder 可以使用NSURL
指定对象 对象作为位置。在OSA中这是 被称为“绝对位置”,a 概念的概括 在基金会的“索引” - 它可能是一个 整数,但不一定是。一个 单个对象甚至可能有一个数字 不同的“绝对位置” 价值取决于容器。“
我刚试过使用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;
}
答案 1 :(得分:1)
添加一些检查以确保finder
,folderURL
和folderPathHFS
都有效。脚本桥可能会返回一个表示“无值”而不是nil的对象,并且该对象可以返回另一个“无值”对象,因此没有任何一个检查会触发,因为它们都不是nil,而是当你要求某个东西时原始类型,它返回0。