Неправильное (но не выбрасывающее ошибку) возвращаемое значение при вызове Scripting Bridge в Finder до 10.6 - PullRequest
4 голосов
/ 01 апреля 2011

Я просматривал множество потоков, связанных со скриптовым мостом, в StackOverflow и в других местах, и, похоже, не смог добиться успеха в выяснении, почему блок кода Какао, который делает вызов скриптового моста в 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 операторов присваивания, но безрезультатно.

Есть идеи?

ОБНОВЛЕНИЕ

ОК, поэтому я обнаружил , где ошибка генерируется в коде выше, хотя я не чувствую, что явсе это намного ближе к решению проблемы.Оказывается, ленивая оценка 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.)

Это круто (прогресс ?!), но все же не приближает меня к решению проблемы.,Это сообщение об ошибке указывает на то, что где-то есть проблема с AEcoercion, но я не уверен, как ее решить.Сгенерированный файл Finder.h (и AppleScript-словарь Finder) достаточно ясно понимают тот факт, что я должен получить ссылку на объект FinderWindow, и вывод объекта folderWindow, кажется, подтверждает, что все в порядке вплоть доname вызов.

Ответы [ 2 ]

3 голосов
/ 07 апреля 2011

Похоже, что -objectAtLocation: ожидает NSURL в отличие от пути в стиле HFS:

" Обсуждение

Этот метод обобщение objectAtIndex: для приложения, где «индекс» не просто целое число Например, гостиницы можно указать объекты, используя NSURL объект как местоположение. В OSA это известный как "абсолютная позиция", обобщение понятия «Индекс» в фундаменте - это может быть целое число, но это не должно быть. один объект может даже иметь номер разной "абсолютной позиции" значения в зависимости от контейнера. "

Я только что попробовал код, который использовал 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 голос
/ 07 апреля 2011

Добавьте несколько проверок, чтобы убедиться, что finder, folderURL и folderPathHFS действительны. Мост сценариев может вернуть объект, представляющий «нет значения» вместо nil, и этот объект может вернуть другой объект «нет значения», поэтому ни одна из ваших проверок не сработает, потому что ни одна из них не равна nil, но когда вы запрашиваете что-то с примитивный тип, возвращает 0.

...