Scripting Bridge и com.apple.iWork.Pages - это может работать? - PullRequest
3 голосов
/ 29 августа 2011

Я пытаюсь посчитать слова в документе Pages (формат документа RTF), используя мост сценариев. (Я могу сделать это, используя NSApplescript, но я бы предпочел, чтобы в моем коде не было всей клейкой ленты, поддерживающей appleScript) Когда я выполняю эту задачу с использованием appleScript (и API-интерфейсов NSAppleScript), я могу сделать это очень просто (и успешно):

on wordCount(appName,docName)
local mydoc
local wordcount
tell application appName
    set mydoc to document docName
    set wordcount to count of words of mydoc
    log "wordcount = " & wordcount
    return wordcount
end tell
end wordCount

Однако, когда я пробую эквивалент с использованием скриптового моста, все мои объекты, похоже, будут иметь нулевое содержимое. Мой код выглядит следующим образом:

+ (NSUInteger) wordCountForApp: (SBApplication*) sbApp docNamed: (NSString*) docName
{
    PagesApplication *pages = (PagesApplication*)sbApp; 
    PagesDocument *doc = [[pages documents] objectWithName:docName];
    PagesText *text = [doc bodyText];
    SBElementArray *words = [text words];
    NSUInteger wc = [words count];
    NSLog(@"Pages word count = %ul", (unsigned int) wc);
    return wc; // wc comes back as zero always ... grrrr
}   

Я проверил, что я запускаю этот материал в основном потоке (и этот эквивалентный код работает против TextEdit). Любые идеи относительно того, что происходит / как обойти?

Спасибо, что прочитали это далеко ....

Ответы [ 2 ]

3 голосов
/ 29 августа 2011

Этот код работает для меня. Эквивалент в F-Script:

> pages := SBApplication applicationWithBundleIdentifier: 'com.apple.iWork.Pages'

> (pages documents objectWithName: 'fun') bodyText words count
303

Я бы посоветовал вам пройти через это с помощью отладчика и убедиться, что каждый объект соответствует ожидаемому, то есть pages, [pages documents] и т. Д.

Если вы пишете этот код для внешнего использования, в идеале не следует ссылаться на документы по имени; у пользователя может быть открыто несколько документов с одним и тем же именем.

Другой вариант - objc-appscript , который предоставляет удобную утилиту ASTranslate, которая преобразует AppleScript в Objective-C (или Ruby или Python для других привязок приложения). Например, для вышеупомянутого у вас будет что-то вроде:

#import "PGGlue/PGGlue.h"
PGApplication *pages = [PGApplication applicationWithName: @"Pages"];
PGReference *ref = [[pages documents] byName: @"fun"];
PGCountCommand *cmd = [[ref count] each: [PGConstant word]];
id result = [cmd send];
1 голос
/ 02 сентября 2011

Таким образом, проблема заключалась в том, что я просил документ с именем "thing.rtf ", который я только что открыл в Pages. Но когда Pages открывает файл «что-то», он называет это «что-то». И затем, когда вы запрашиваете документ с именем "thing.rtf ", он не возвращает nil, потому что документ не существует с таким именем . Вместо этого он возвращает PagesDocument с именем «thing.rtf », который не имеет допустимого содержимого: документ NIL. Что я думаю, я просто был слишком глуп, чтобы признать, когда я подал в SO.

С тех пор я проверил другие приложения, и это кажется нормальным поведением яблочного сценария, когда вы запрашиваете документ по имени (чтобы вернуть «действительный объект», содержащий документ NIL).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...