我能够为我的应用程序支持AppleScript的Make New命令,但是为核心数据管理对象返回的“指定对象”(NSUniqueIDSpecifier)是无用的。以下AppleScript返回错误消息:
错误“SpellAnalysis收到错误:密钥表单无效。”编号-10002,来自级别ID“x-coredata:/// Levels / tC5A49E01-1CE1-4ED6-8F6B-BC0AE90E279A2”
tell application "SpellAnalysis"
set thisLevel to make new «class Slev» with properties {«class Saln»:3}
get properties of thisLevel
end tell
因此,AppleScript中无法对新创建的Levels对象执行操作。我已经梳理了Web以获得解决方案,我发现最接近的是Bill Cheeseman的示例应用程序,“WareroomDemo”,它专门处理Cocoa Scriptability for Core Data应用程序(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];
}
答案 0 :(得分:1)
问题在于说明符方法。 Sketch示例实际上使用了我需要的技术。我多次忽略它,因为我没有看到它如何应用于Core Data托管对象。您可以使用'indexOfObjectIdenticalTo:'方法返回managedObject索引,而不是返回对象uniqueID,如下所示:
- (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>