我想我应该发布一些关于 Cocoa Scriptability 对 Core-data 应用程序的支持的附加信息,因为那里的信息太少了。我花了至少一个月的时间试图了解如何接受这种机制。
尽管我能够使用索引说明符为我的核心数据应用程序提供 AppleScript 支持,但我发现使用“uniqueID”说明符提供了更好的匹配。更好,因为核心数据对多的关系由无序集支持,而不是数组。核心数据为您提供了一种通过对象 ID 指定托管对象的方法,该对象 ID 可以由 Cocoa Scriptability 方法评估。然而,为了使用 uniqueID 说明符实现对“太多”关系的支持,需要额外的代码元素。
1) 在“sdef”中为您将支持的每个实体提供一个属性元素。例如,为了支持我的“级别”实体,我在“级别”类标签中发布了以下内容:
<property name="id" code="ID " type="text" access="r" description="The level's unique id. This may be a temporary id for newly- created level objects, until they are saved.">
<cocoa key="uniqueID"/>
</property>
请注意,该类型被指定为“文本”而不是“说明符”。AppleEvent 机制和 Cocoa AppleScript 支持之间的“uniqueID”交换将是一个字符串值。另请注意,“可可键”值是“唯一 ID”。AppleScript 脚本支持使用这个键('sdef' 中的典型键)来识别应用程序中符合 KVC 模式的方法名称。
2) 在包含目标对象的类中发布一个“valueInWithUniqueID”方法。正是在此方法中,您提供了一种方法来提取与传递给该方法的任何“uniqueID”相对应的托管对象。这是我在容器类“Levels”中发布的“levelsArray”KVO 方法。
- (id)valueInLevelsArrayWithUniqueID:(NSString *)uniqueID;
{
NSManagedObject *managedObject= [[[NSApp delegate] myManagedObjectContext] objectWithID:[[[NSApp delegate] lessonsManager] managedObjectIDForURIRepresentation:[NSURL URLWithString:uniqueID]]];
return managedObject;
}
这是包含的“单元”类的“sdef”属性声明:
<property name="id" code="ID " type="text" access="r" description="The unit's unique id. This may be a temporary id for newly-created unit objects, until they are saved.">
<cocoa key="uniqueID"/>
</property>
我的“单位”类也唤起了价值方法。请注意基本的 KVC 名称模式:
- (id)valueInUnitsArrayWithUniqueID:(NSString *)uniqueID;
{
NSManagedObject *managedObject= [[[NSApp delegate] lessonsDBase] objectWithID:[[[NSApp delegate] lessonsManager] managedObjectIDForURIRepresentation:[NSURL URLWithString:uniqueID]]];
return managedObject;
}
有了这些,如果我的 AppleScript 需要从其“uniqueID”中指定一个“级别”对象,它将得到回答。当你有实体类的层次结构并且你编写一个 AppleScript 1)调用一个返回其结果的引用的命令,并且 2)使用另一个命令对该返回的结果进行操作时,这似乎开始发挥作用:
count (make new section at unit 1 of level 1)
奇怪的是,以下内容并没有唤起 value 方法:
count (unit 1 of level 1)
请注意,它缺少条件 1——缺少主要命令(例如“make”)。在这种情况下,会调用隐含的 AppleScript 'get' 命令,但 Cocoa 可脚本性似乎通过另一种方式确定实体层次结构的值。
3) 为从您支持的命令返回的所有对象提供“uniqueID”对象说明符,并为支持其隐含“get”命令的每个实体子类明确命名为“objectSpecifier”。例如,我在其“performDefaultImplementation”中发布的“克隆”命令提供以下方法:
NSUniqueIDSpecifier *uniqueIDSpecifier = [[[NSUniqueIDSpecifier allocWithZone:[self zone]] initWithContainerClassDescription:[NSScriptClassDescription classDescriptionForClass:[NSApp class]] containerSpecifier:sourceContainerSpecifier key:sourceKey uniqueID:uniqueID] autorelease];
根据您是使用命令操作单个对象还是一系列对象,您可以直接返回“uniqueIDSpecifier”或将其添加到最后一次添加后返回的连续此类说明符的数组中。为了支持隐含的“get”命令,您在每个托管对象实体子类中发布一个“uniqueID”对象说明符。以下说明符支持我的“单元”类子类:
- (NSScriptObjectSpecifier *)objectSpecifier {
NSScriptObjectSpecifier *containerRef = [[NSApp delegate]levelsSpecifier];
NSString *uniqueID = [[[self objectID] URIRepresentation] absoluteString]; // This is the key method for determining the object's 'uniqueID'
if (uniqueID) {
NSScriptObjectSpecifier *uniqueIDSpecifier = [[[NSUniqueIDSpecifier allocWithZone: [self zone]] initWithContainerClassDescription:[containerRef keyClassDescription] containerSpecifier:containerRef key:@"unitsArray" uniqueID:uniqueID] autorelease];
[[NSApp delegate] setUnitsSpecifier:uniqueIDSpecifier]; // Post specifier so Units class specifier can access it
return uniqueIDSpecifier;
} else {
return nil;
}
请注意,第二条注释行表明我将此说明符的结果发布在全局变量中,以便包含类的对象说明符可以使用此说明符结果作为其容器说明符。应用程序委托是所有实体子类都可以访问应用程序范围的访问器和方法(例如此对象说明符结果)的地方。
我确实希望这可以帮助像我这样的人,上个月。