1

我能够为我的应用程序支持 AppleScript 的 Make New 命令,但是为核心数据托管对象返回的“指定对象”(一个 NSUniqueIDSpecifier)是无用的。以下 AppleScript 返回错误消息:

错误“SpellAnalysis 出现错误:无效的密钥形式。” 来自级别 ID“x-coredata:///Levels/tC5A49E01-1CE1-4ED6-8F6B-BC0AE90E279A2”的数字 -10002

tell application "SpellAnalysis"
  set thisLevel to make new «class Slev» with properties {«class Saln»:3}
  get properties of thisLevel
end tell

所以新创建的 Levels 对象不能在 AppleScript 中执行。我已经在网上搜索了一个解决方案,我发现最接近的是 Bill Cheeseman 的示例应用程序“WareroomDemo”,它专门处理 Core Data 应用程序的 Cocoa Scriptability(Sketch 示例不使用 Core Data)。不幸的是,这是一个过时的示例,仅在 64 位之前的 XCode 上运行,而我实际上无法运行它——我只能查看代码。据我所知,他的应用程序的 Make Command 可能具有相同的限制。

返回的 'objectSpecifier' 无法引用创建的对象,以防止破坏 Core Data 的组织方案,或者可能是因为返回的对象是未兑现的“故障”。我认为后一种可能性不太可能,因为我可以强制将错误兑现(通过获取托管对象的属性值),但我得到与 AppleScript 相同的错误消息。

这是创建我的类的方法:

- (id)newScriptingObjectOfClass:(Class)class forValueForKey:(NSString *)key withContentsValue:(id)contentsValue properties:(NSDictionary *)properties { // Creates a new Lesson object in response to the AppleScript 'make' command.

 // Documentation for 'newScriptingObject…' states that to create a new class object when using Core Data, you intercede using the following method (or you  can subclass the NSCreateCommand's 'performDefaultImplementation' method and put your NSManagedObject init code there):

if (class == [Levels class]) {
    //NSLog(@"class: %@",class);

   NSEntityDescription *levelsEntity = [NSEntityDescription
                                           entityForName:@"Levels"
                                    inManagedObjectContext:levelsDBase];

    NSManagedObject *levelObject = [[NSManagedObject alloc] initWithEntity:levelsEntity insertIntoManagedObjectContext:levelsDBase];
    SLOG(@"lessonObject: %@", lessonObject);

    NSString *levelNumberString = [[properties objectForKey:@"levelNumber"] stringValue];
    SLOG(@"levelNumberString: %@", levelNumberString);

    [levelObject setValue:levelNumberString forKey:@"levelNumber"];

    return levelObject; // When using Core Data, it seems that you return the newly created object directly

}

return [super newScriptingObjectOfClass:(Class)class forValueForKey:(NSString *)key withContentsValue:(id)contentsValue properties:(NSDictionary *)properties]; 
}

这是我的对象说明符方法:

- (NSScriptObjectSpecifier *)objectSpecifier {
// This NSScriptObjectSpecifiers informal protocol returns a unique ID specifier specifying the absolute string of the URI representation of this managed object.   // AppleScript return value: 'level id <id>'.

// The primary container is the application.
NSScriptObjectSpecifier *containerRef = nil; // I understand that if the application is the container, this is value you use for the container reference

NSString *uniqueID = [[[self objectID] URIRepresentation] absoluteString];

return [[[NSUniqueIDSpecifier alloc] initWithContainerClassDescription:[NSScriptClassDescription classDescriptionForClass:[NSApp class]] containerSpecifier:containerRef key:@"levelsArray" uniqueID:uniqueID] autorelease];
}
4

1 回答 1

1

问题在于说明符方法。Sketch 示例实际上使用了我需要的技术。我忽略了很多次,因为我没有看到它将如何应用于 Core Data 托管对象。与其返回对象 uniqueID,不如使用 'indexOfObjectIdenticalTo:' 方法使其返回 managedObject 索引,如下所示:

- (NSScriptObjectSpecifier *)objectSpecifier {

NSArray *levelsArray = [[NSApp delegate] levelsArray]; // Access your exposed to-many relationship--a mutable array
unsigned index = [levelsArray indexOfObjectIdenticalTo:self]; // Determin the current objects index

if (index != (unsigned)NSNotFound) {
// The primary container is the document containing this object's managed object context.
NSScriptObjectSpecifier *containerRef = nil; // the appliation
   return [[[NSIndexSpecifier allocWithZone:[self zone]] initWithContainerClassDescription:[NSScriptClassDescription classDescriptionForClass:[NSApp class]] containerSpecifier:containerRef key:@"levelsArray" index:index] autorelease];
} else {
    return nil;
}

}

请注意,此方法位于 Core Data managedObject 的子类中——在本例中为“Levels”类。'indexOfObjectIndenticalToSelf:' 方法中的 'self' 是指正在处理的当前 managedObject('Levels')。此外,请务必为您的“sdef”文件提供说明符(访问器)类型,如下所示:

 <element type="level">
    <cocoa key="levelsArray"/>
    <accessor style="index"/>
 </element>
于 2013-09-26T04:05:11.300 回答