使Cocoa NSDocument软件包的配方与SVN一起运行良好吗?
-
01-10-2019 - |
题
我有一个写包装式文档的工具。它是使用NSDocument实施的,并覆盖了以下NSDocument方法:
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName
error:(NSError **)outError;
- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper
ofType:(NSString *)typeName
error:(NSError **)outError;
这一切都很可爱,除非我保存版本控制的文档。 (.svn目录未保留,等等)
是否有一个很好的食谱可以使我的文档在SVN上运行良好?
解决方案
我猜想您的代码每次都可以创建新的文件包装器来工作 -fileWrapperOfType:error:
叫做。这很方便,但无视软件包内部磁盘上可能存在的任何其他文件。
因此,相反,如果您从创建/使用文件包装器开始,该文件涉及磁盘上的现有内容。修改该包装器以匹配文档的当前状态,然后返回结果。当将包装器写入磁盘时,应正确维护SVN文件。
其他提示
这是我基于迈克的答案的解决方案!
我的文档包是捆绑包,具有通常的层次结构……因此,我在保存过程中有四个目录:
- 保存创建了一个新的顶级(my.bundle)
- 内容目录已更改(my.bundle/contents)
- 资源目录已更改(my.bundle/contents/Resources)
- 本地资源已更新(my.bundle/coptents/resources/en.lproj)
食谱首先在文档类中添加一个可变的词典插槽,以保留每个目录的内容。
@interface LMDocument : NSDocument {
@private
// All this is for preserving SCM artifacts across saves…
NSMutableDictionary * bundleWrappers;
NSMutableDictionary * contentsWrappers;
NSMutableDictionary * resourcesWrappers;
NSMutableDictionary * localizedWrappers;
}
创建新文档时,这些开始是作为空词典开始的。
- (id)init;
{
if ((self = [super init]) != nil) {
bundleWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
contentsWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
resourcesWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
localizedWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
}
return self;
}
在现有文档中读取时,将其替换为相关文件处理器内容的可变副本。
- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper
ofType:(NSString *)typeName
error:(NSError **)outError;
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
bundleWrappers = [[fileWrapper fileWrappers] mutableCopy];
contentsWrappers = [[[bundleWrappers objectForKey:@"Contents"] fileWrappers] mutableCopy];
resourcesWrappers = [[[contentsWrappers objectForKey:@"Resources"] fileWrappers] mutableCopy];
localizedWrappers = [[[resourcesWrappers objectForKey:@"en.lproj"] fileWrappers] mutableCopy];
NSFileWrapper * infoPlistWrapper = [contentsWrappers objectForKey:@"Info.plist"];
[contentsWrappers removeObjectForKey:@"Info.plist"]; // Replaced during save…
// …
NSMutableDictionary * localizedWrappersCopy = [localizedWrappers mutableCopy];
[localizedWrappers enumerateKeysAndObjectsUsingBlock:^(id key,
id obj,
BOOL * stop)
{
if (mumble) { // If it's a file that will be replaced during save…
[localizedWrappersCopy removeObjectForKey:key]; // Replaced during save…
// …
}
}];
localizedWrappers = localizedWrappersCopy;
[pool drain];
return YES;
}
和 最后, ,保存文档时,请使用词典进行精心准备。
- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName
error:(NSError **)outError;
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSFileWrapper * localizedWrapper =
[[NSFileWrapper alloc] initDirectoryWithFileWrappers:localizedWrappers];
[resourcesWrappers setObject:localizedWrapper
forKey:@"en.lproj"];
NSFileWrapper * resourcesWrapper =
[[NSFileWrapper alloc] initDirectoryWithFileWrappers:resourcesWrappers];
[contentsWrappers setObject:resourcesWrapper
forKey:@"Resources"];
NSFileWrapper * contentsWrapper =
[[NSFileWrapper alloc] initDirectoryWithFileWrappers:contentsWrappers];
// …
for (id item in mumble) {
NSString * filename = [item filename];
NSData * data = [item data];
[localizedWrapper addRegularFileWithContents:data
preferredFilename:filename];
}
[contentsWrapper addRegularFileWithContents:[self infoPlistData]
preferredFilename:@"Info.plist"];
[pool drain];
[bundleWrappers setObject:contentsWrapper
forKey:@"Contents"];
NSFileWrapper * bundleWrapper =
[[[NSFileWrapper alloc] initDirectoryWithFileWrappers:bundleWrappers] autorelease];
return bundleWrapper;
}
现在,在编辑软件包文档时,该应用程序保留了没有添加到捆绑包中的任何文件,包括SCM工件和“其他”本地化!
不隶属于 StackOverflow