Por que salvar arquivos em um NSDocument cria versões do mesmo arquivo com caracteres estranhos no nome?

StackOverflow https://stackoverflow.com//questions/22046035

Pergunta

Estou trabalhando em um aplicativo baseado em NSDocument cujo tipo de documento é um pacote que contém vários arquivos.Estou salvando assim:

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
{
    if (!self.documentFileWrapper) {
        NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
        [self setDocumentFileWrapper:documentFileWrapper];
    }

    NSFileWrapper *defaultWrapper = [self.documentFileWrapper.fileWrappers objectForKey:@"default"];
    if (!defaultWrapper) {
        defaultWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
        [defaultWrapper setPreferredFilename:@"someFile.ext"];
        [self.documentFileWrapper addFileWrapper:defaultWrapper];
    }

    [defaultWrapper addRegularFileWithContents: ... some computed content for the file ... preferredFilename:@"someFile.ext"];

    return self.documentFileWrapper;
}

Em outras palavras, no pacote, crie uma pasta “default” e salve “someFile.ext” nela com algum conteúdo.

Agora, o problema.Quando vejo o que realmente está salvo no disco, vejo o seguinte:

screenshot

Cada vez que salvo o arquivo, o wrapper NSDocument parece criar alguma cópia versionada do recurso.Não quero os clones versionados, quero apenas o arquivo vanilla com o conteúdo mais recente.

De onde vêm os recursos versionados?O que está acontecendo aqui?Existe um documento que devo ler?

Foi útil?

Solução

Ok, acho que descobri.Acontece que não era realmente um problema de versão.Parece que você estava simplesmente adicionando um novo arquivo a cada vez.Primeiro, algumas notas.

  1. Parece que você não está criando um arquivo em um pacote, mas um 'diretório contendo um arquivo', em um pacote.É isso que você pretendia fazer?
  2. Parece que se o diretório "default" não existir, você cria e usa um diretório "someFile.ext", o que significa que da próxima vez ele criará um novo diretório com um prefixo estranho.No entanto, vejo pela sua captura de tela que você já possui um diretório "padrão", o que significa que isso não é problema seu.

Agora, seu problema real:de acordo com esta documentação, addRegularFileWithContents cria um novo arquivo com seu nome de arquivo preferido, a menos que o diretório (defaultWrapper) já contém um arquivo com esse nome (basicamente).Se já existir, cria um novo arquivo com um prefixo. addRegularFileWithContents retorna uma string identificadora referente ao NSFileWrapper criado (acho que é o nome do arquivo).

Então, o que acontece é que cada vez que você vai salvar o arquivo, ele vê que já existe um arquivo com aquele nome, e cria um novo prefixado.Uma maneira de resolver isso é manter o NSString retornado por addRegularFileWithContents, então quando você for salvar você verifica o defaultWrapper e remova o NSFileWrapper associado ao NSString armazenado, se houver, e adicione o arquivo normalmente.Modifiquei seu código da seguinte maneira:

@interface TestDocument () // Relevant part of my test class.  Note `wrapperFileName`.

@property (nonatomic, strong) NSFileWrapper *documentFileWrapper;
@property (nonatomic, strong) NSString *wrapperFileName;

@end



- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError **)outError
{
    if (!self.documentFileWrapper) {
        NSFileWrapper *documentFileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
        [self setDocumentFileWrapper:documentFileWrapper];
    }

    NSFileWrapper *defaultWrapper = [self.documentFileWrapper.fileWrappers objectForKey:@"default"];
    if (!defaultWrapper) {
        defaultWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
        [defaultWrapper setPreferredFilename:@"default"];
        [self.documentFileWrapper addFileWrapper:defaultWrapper];
    } else if (self.wrapperFileName) {
        [defaultWrapper removeFileWrapper:[[defaultWrapper fileWrappers] objectForKey:self.wrapperFileName]];
    }

    self.wrapperFileName = [defaultWrapper addRegularFileWithContents:[@"blah blah" dataUsingEncoding:NSUTF8StringEncoding] preferredFilename:@"someFile.txt"];
    return self.documentFileWrapper;
}
  1. Eu mudei o defaultWrapperO nome de arquivo preferido é "padrão", como suspeito que você pretendia.
  2. Eu adicionei um if bloco que remove o arquivo salvo anteriormente, se existir.
  3. Eu fiz com que ele armazenasse o nome do arquivo do novo NSFileWrapper, para usar na próxima vez no item 2.

Após essas mudanças, o programa demonstrou o que considero ser o comportamento que você espera:um diretório contendo um arquivo, mesmo depois de salvar várias vezes.Observe que isso era verdade mesmo quando preservesVersions devolvida YES.Não tenho certeza de onde ele armazena suas versões, mas não as vi.

Outras dicas

Você pode implementar -writeSafely... para que ele chame diretamente para -writeToURL:... Implementar -writeToURL:... para que ele chame -fileWrapperOfType:... e, em seguida, escreve isso na URL atomicamente

ou sejavocê assumiria a responsabilidade pelos salvamentos atômicos fazendo com que o NSFileWrapper fizesse isso.Dessa forma, o wrapper deve rastrear perfeitamente onde os arquivos realmente vão parar.

Fonte

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top