Рецепт для создания пакетов какао 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 / Content)
- Каталог ресурсов изменен (my.bundle / содержимое / ресурсы)
- Локализованные ресурсы обновлены (My.Bundle / Contents / 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 и «другие» локализации!