Objective c OBJ-C脚本桥-创建具有属性的脚本对象时遇到问题(Microsoft Word)

Objective c OBJ-C脚本桥-创建具有属性的脚本对象时遇到问题(Microsoft Word),objective-c,cocoa,scripting,applescript,scripting-bridge,Objective C,Cocoa,Scripting,Applescript,Scripting Bridge,我一直用这个把头撞在墙上。我正在尝试使用脚本桥在MS Word中创建一个新的自动图文集条目 以下是我尝试使用的代码: wordApplication *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"]; wordTemplate *theWordTemplate = [[theWordApp activeDocument] attachedTemplate]; wordAutoTe

我一直用这个把头撞在墙上。我正在尝试使用脚本桥在MS Word中创建一个新的自动图文集条目

以下是我尝试使用的代码:

wordApplication *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"];
wordTemplate *theWordTemplate = [[theWordApp activeDocument] attachedTemplate];
wordAutoTextEntry *theNewAutoTextEntry = [[[theWordApp classForScriptingClass:@"auto text entry"] alloc] init];
[[theWordTemplate autoTextEntries] addObject:theNewAutoTextEntry];
[theNewAutoTextEntry setName:@"test name"];
NSLog(@"%@", [theNewAutoTextEntry name]);
使用此选项,我得到以下错误:

*** -[SBProxyByClass setName:]: object has not been added to a container yet; selector not recognized [self = 0x6d9fbd0]
我也尝试过:

wordApplication *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"];
wordTemplate *theWordTemplate = [[theWordApp activeDocument] attachedTemplate];
wordAutoTextEntry *theNewAutoTextEntry = [[[theWordApp classForScriptingClass:@"auto text entry"] alloc] initWithProperties:[NSDictionary dictionaryWithObjectsAndKeys:@"testname", @"test", nil]];
NSLog(@"%@", [theNewAutoTextEntry name]);
这样我也会犯同样的错误

有趣的是,当我运行以下程序时:

wordApplication *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"];
wordTemplate *theWordTemplate = [[theWordApp activeDocument] attachedTemplate];
wordAutoTextEntry *theNewAutoTextEntry = [[[theWordApp classForScriptingClass:@"auto text entry"] alloc] init];
NSLog(@"%@", theNewAutoTextEntry);
我得到这个输出:

<future MicrosoftWordAutoTextEntry with properties (null)>


其中,自动文本输入指示为“未来”。有什么想法吗?提前谢谢

某人工作不正常;从来没有,将来也不会。它特别容易与基于碳的应用程序(如Word)发生兼容性问题,因为Word在构造引用和命令的方式上具有更大的可变性,尽管即使是Cocoa应用程序也会给它提供gyp

以下是如何在AppleScript中实现这一点,它可以完美地工作:

tell application "Microsoft Word"
    make new auto text entry at attached template of active document ¬
        with properties {name:"test name", auto text value:"test value"}
end tell
但是,将其转换为SB代码只会在以下行产生“选择器未识别”错误,因为SB无法构造所需的引用形式:

[theWordTemplate addObject:theNewAutoTextEntry];
假设您的目标是10.6或更高版本,请忘记SB,改用AppleScript ObjC桥。AppleScript是唯一仍然支持的解决方案,它知道如何正确地谈论Apple事件。ASOC使AppleScript脚本对象在应用程序的其余部分显示为普通的Cocoa类和实例,允许您的ObjC代码直接与AppleScript通信,反之亦然,从而避免了SB缺陷和NSAppleScript繁琐的工作

有关更多信息,请参见这些帖子:

我得到这个输出:[…]其中自动文本条目被指示为“future”。有什么想法吗


那只是某人的假货泄露出去了。忽视它;它只是让人困惑,而且与您的问题无关。

您的思路是正确的,但似乎没有从其数组中获取对象,这是处理该对象所必需的。最好使用name属性初始化对象,以确保轻松检索。也就是说

    word011 *theWordApp = [SBApplication applicationWithBundleIdentifier:@"com.microsoft.Word"];
    word2011Template *theWordTemplate = [[theWordApp activeDocument] attachedTemplate];

    // create the object with them name property to grab it later
    NSString *testName = @"test name";
    word2011AutoTextEntry *theNewAutoTextEntry = [[[theWordApp classForScriptingClass:@"auto text entry"] alloc] initWithProperties:[NSDictionary dictionaryWithObjectsAndKeys:testName, @"name", nil]];
    [[theWordTemplate autoTextEntries] addObject:theNewAutoTextEntry];

    // you created the object, but now you have to actually *get* the object
    // check for existence first other EXC_BAD_ACCESS will happen
    if ( [[[theWordTemplate autoTextEntries] objectWithName:testName] exists] {
        theNewAutoTextEntry = [[theWordTemplate autoTextEntries] objectWithName:testName];
    }

    // name already set, so you can move with working with the object
    //[theNewAutoTextEntry setName:@"test name"];

@Philp Regan:我测试了你的代码,但出乎意料的是,它不起作用:所需的“自动文本输入”对象是未创建的。如果没有包含隐藏元素创建中任何失败的
if
块,您自己可能已经注意到了这一点

下面是我从原始ObjC代码翻译成Python的测试-不幸的是,我无法使用您的ObjC代码,因为
sdp
在尝试为Word 2011创建粘合头时呕吐(
sdp
也有问题,在InDesign和其他应用程序上也有问题)

如您所见,
自动文本输入
元素是未创建的;此外,SB无声地失败了,让你不知道为什么操作不起作用

(如果您愿意,我很乐意使用自己创建的Word.h文件重试您的原始ObjC代码,但结果将完全相同。)

为了证明这是SB的错,而不是其他任何人的错,这里是Python appscript中的等效代码,经过调整只是为了为
make
命令的
at
参数提供正确的参考形式:

#!/usr/local/bin/python3

from appscript import *

theWordApp = app(id="com.microsoft.Word")

theWordTemplate = theWordApp.active_document.attached_template

testName = "test name 101"

theNewAutoTextEntry = theWordApp.make(new=k.auto_text_entry, at=theWordTemplate, with_properties={k.name: testName})

print (theWordTemplate.auto_text_entries[testName].exists()) # prints: True

再一次:脚本桥和sdp不能正常工作;从来没有,永远不会。除了常见的bug和遗漏之外,SB的设计还有根本性的缺陷:作为一个ORM,它试图将Cocoa狭隘的OO语义强加于Apple events广泛的RPC+关系查询语义,从而在两者之间造成严重的阻抗不匹配。(这是80/20/80的问题:80%的时间它工作,但20%的时间它不工作,80%的时间你不知道为什么。)有很多例子表明,由于对应用程序脚本实际工作方式的所有有缺陷或不正确的假设,SB在AppleScript和appscript中无法完美工作的命令上失败

某些引用和命令甚至根本无法构造-例如,尝试将以下内容转换为SB:

tell application "Finder"
    get name of every file of entire contents of desktop
end tell

tell application "TextEdit"
    tell document 1
       duplicate paragraph 1 to after paragraph 2
    end tell
end tell
第一个示例将无法编译,因为SB无法构造包含全部内容的
每个文件
部分,因为它只能引用具体对象(文件、文件夹、磁盘等)的属性和元素,
全部内容
属性包含引用(对象说明符),而不是具体对象

第二个将失败,因为它无法构建第2段之后的
部分:负责SB的Apple开发人员只是忘记了在
/
开始之后实现构建插入位置引用所需的相应
方法

OP的Word示例尤其具有讽刺意味,因为基本问题在SB发布后的几天内就被报告给了苹果:SB的
-[NSElementArray addObject:][/code>只知道如何构造
make
形式的事件
在…
末尾新建。然而,在Apple events世界中,以下形式也是完全合法的:
在…
创建新的,
在…
创建新的,
在…
创建新的,
在…
结尾创建新的,可能还有一些其他形式

特定应用程序将理解哪些表单,哪些不理解,这由应用程序自己决定。脚本接口构建在Cocoa脚本上的应用程序都理解
在…末尾进行新创建
表单;然而,其脚本接口直接构建在Carbon Apple Event Manager API或各种定制或第三方C/CC+框架上的应用程序通常差别很大

例如,Finder、iTunes、Illustrator和Word等基于碳元素的应用程序通常要求您在…
上说“新建”,但SB不允许您构建这些表单。如果您试图使用SB的
-[NSElementArray addObject:
,应用程序会抛出一个错误,因为它不理解末尾的
make new
tell application "Finder"
    get name of every file of entire contents of desktop
end tell

tell application "TextEdit"
    tell document 1
       duplicate paragraph 1 to after paragraph 2
    end tell
end tell