2010-08-24 27 views
0

J'ai un outil qui écrit des documents de style paquet. Il est mis en œuvre à l'aide NSDocument et remplace les méthodes NSDocument suivantes:Recette pour faire des paquets Cocoa NSDocument bien jouer avec svn?

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName 
           error:(NSError **)outError; 

- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper 
        ofType:(NSString *)typeName 
        error:(NSError **)outError; 

C'est tout beau, sauf quand je sauverai un document qui est sous contrôle de version. (Les répertoires .svn ne sont pas conservés, etc.)

Existe-t-il une bonne recette pour que mes documents soient bien lus avec svn?

Répondre

3

Je suppose que votre code fonctionne en créant une nouvelle enveloppe de fichier chaque fois que -fileWrapperOfType:error: est appelée. C'est pratique, mais ne tient pas compte des fichiers supplémentaires qui peuvent exister sur le disque à l'intérieur du paquet. Par conséquent, que se passe-t-il si vous commencez par créer/utiliser un gestionnaire de fichiers qui fait référence au contenu existant sur le disque. Modifiez ce wrapper pour qu'il corresponde à l'état actuel du document et renvoyez le résultat. Lorsque ce wrapper est écrit sur le disque, les fichiers svn doivent être correctement gérés.

+0

Bien, merci! Oui, c'était un peu compliqué de tout refactoriser pour que ça marche ... Mais une fois que tu connais l'exigence, c'est vraiment un morceau de gâteau! –

1

Voici ma solution basée sur la réponse de Mike!

Mes paquets de documents sont des faisceaux, avec la structure hiérarchique habituelle ... Donc, il y a quatre répertoires que je muter au cours Saves:

  1. La sauvegarde crée un nouveau haut niveau (My.bundle)
  2. Le répertoire des matières est modifiée (My.bundle/contenu)
  3. Le répertoire des ressources est modifié (My.bundle/Contents/resources)
  4. Les ressources localisées sont mis à jour (My.bundle/Contents/resources/en.lproj)

La recette commence par l'ajout d'un emplacement de dictionnaire modifiable à votre classe de document afin de préserver le contenu de chacun de ces répertoires. Lors de la création d'un nouveau document, ceux-ci commencent comme des dictionnaires vides. Lors de la lecture dans un document existant, remplacez-les par des copies modifiables du contenu approprié de la classe fileWrapper lors de la lecture dans un document existant.

- (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; 
} 

Et enfin , lors de l'enregistrement d'un document, utilisez les dictionnaires si laborieusement préparé.

- (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; 
} 

Maintenant, lorsqu'un document de package est modifié, l'application conserve tous les fichiers qu'il n'a pas été ajouté au paquet, y compris les artefacts SCM et « autres » Localisations!