2012-12-19 2 views
4

J'ai une application de base Cocoa qui permet à l'utilisateur de gérer une liste de fichiers. Les fichiers sont ajoutés via glisser & et je conserve les autorisations d'accès dans un signet sécurisé à travers les redémarrages d'applications.Application Sandbox: renommer un fichier ne fonctionne pas

Jusqu'ici tout va bien. L'application est autorisée à lire et à écrire dans les fichiers de l'utilisateur, mais le renommage échoue avec une erreur d'autorisation, affirmant que mon application n'est pas autorisée à accéder au dossier parent.

code:

[[NSFileManager defaultManager] moveItemAtPath:currentPath 
             toPath:newPath error:&error] 

Erreur:

Error Domain=NSCocoaErrorDomain Code=513 "“Some image.jpg” couldn’t 
be moved because you don’t have permission to access “some folder” 

Je jure que cette habitude de travailler plus tard qu'hier, rien n'a changé ... Quoi qu'il en soit. Je suppose que si un utilisateur autorise l'accès à un fichier via une boîte de dialogue Ouvrir ou faites glisser &, supprimez qu'une application en mode bac à sable doit être autorisée à renommer le fichier.

+0

Êtes-vous résoudre définitivement le signet sécurisé avant de tenter d'accéder à ce chemin? – Dov

+0

Oui, je résolve définitivement le signet et commence l'accès sécurisé. – Mark

+0

Pourriez-vous donner plus de code? Peut-être assez pour que quelqu'un puisse reproduire votre problème? À l'heure actuelle, il n'y a pas grand chose à faire. De plus, obtenez-vous accès au chemin d'accès et au chemin de destination? – Dov

Répondre

3

Le problème que vous rencontrez est pas persistant quoi que ce soit, il est à peu près comment fonctionne bac à sable:

La règle est ...

Pour renommer un fichier (en fait effectuer une opération de déplacement),
vous devez avoir un accès en écriture au répertoire parent du fichier.

Notre problème est ...

Si vous faites glisser fichiers, Sandbox ne étendre l'accès à ces fichiers, et non pas leur répertoire parent, d'où cette erreur en disant qu'il a besoin d'une autorisation

Maintenant, essayez de faire glisser le dossier contenant ces fichiers, et vous verrez que tout fonctionne juste :)

Alors, que faisons-nous?

Une solution simple serait de demander à l'utilisateur de choisir via NSOpenPanel un « travail » répertoire, de sorte que l'accès sans bac à sable a aliénant l'utilisateur à chaque fois qu'il souhaite renommer
Mais nous tracasse maintenant l'utilisateur merde il ne devrait même pas savoir au sujet de la première place!
Donc, pour moi, c'est une mauvaise conception/UX

Maintenant, j'ai lu la documentation sur bac à sable et je remarqué NSFileCoordinator avait une méthode appelée itemAtURL:willMoveToURL:

Wich m'a conduit à ce petit snippet (que je réécris ici parce qu'il lui manquait la fonction WillMove)
ce que nous voulons faire ici est de demander une extension de bac à sable pour le bien de changement de nom:

NSURL *sourceURL = document.fileURL; 
NSURL *destinationURL = [[sourceURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:fileName isDirectory:NO]; 

NSError *writeError = nil; 
__block NSError *moveError = nil; 
__block BOOL success = NO; 

NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 

[coordinator coordinateWritingItemAtURL:sourceURL 
           options:NSFileCoordinatorWritingForMoving 
         writingItemAtURL:destinationURL 
           options:NSFileCoordinatorWritingForReplacing 
            error:&writeError 
          byAccessor:^(NSURL *newURL1, NSURL *newURL2) 
{ 
    NSFileManager *fileManager = [NSFileManager new]; 

    [coordinator itemAtURL:sourceURL willMoveToURL:destinationURL]; 

    success = [fileManager moveItemAtURL:newURL1 toURL:newURL2 error:&moveError]; 

    if (success) 
    { 
     [coordinator itemAtURL:newURL1 didMoveToURL:newURL2]; 
    } 
}]; 

Malheureusement, il semble que cette méthode ne vise à changer l'extension du fichier plutôt que de renommer, d'où cette erreur dans le journal:

NSFileSandboxingRequestRelatedItemExtension: an error was received from pboxd instead of a token. Domain: NSPOSIXErrorDomain, code: 1 

Yay, pomme, yay

+0

On dirait que nous avons besoin d'une API pour renommer sur place au lieu de se déplacer .... Dans mon cas, le dossier parent reste le même, l'utilisateur ne fait que changer le nom du fichier. – Mark

2

Les œuvres suivantes pour moi aussi longtemps que-je ajouter myext en tant que type de document d'élément associé dans mon Info.plist. Ceci est noté dans Apple's Documentation.
Voici un extrait:

In both scenarios, you must make a small change to the application’s Info.plist file. Your app should already declare a Document Types (CFBundleDocumentTypes) array that declares the file types your app can open.

For each file type dictionary in that array, if that file type should be treated as a potentially related type for open and save purposes, add the key NSIsRelatedItemType with a boolean value of YES.

Code modifié de la réponse de BenRhayader:

NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 
    NSURL *sourceURL = chosenFile; 
    NSURL *destinationURL = [chosenFile URLByAppendingPathExtension: @"myext"]; 

    [coordinator coordinateWritingItemAtURL:sourceURL 
            options:NSFileCoordinatorWritingForMoving 
          writingItemAtURL:destinationURL 
            options:NSFileCoordinatorWritingForReplacing 
             error:NULL 
           byAccessor:^(NSURL *newURL1, NSURL *newURL2) 
    { 
     NSFileManager *fileManager = [NSFileManager new]; 

     [coordinator itemAtURL:sourceURL willMoveToURL:destinationURL]; 
     NSError *moveError; 
     BOOL success = [fileManager moveItemAtURL:newURL1 toURL:newURL2 error:&moveError]; 

     if (success) 
     { 
      [coordinator itemAtURL:newURL1 didMoveToURL:newURL2]; 
     } 
    }]; 
+0

Malheureusement, cela ne fonctionnera pas pour tous les types de fichiers ... – Mark

+0

Droit .. basé sur la documentation d'Apple, il semble que vous ne pouvez pas demander ce type de permission "en gros" et devez plutôt déclarer les types de fichiers que vous ' re application utilisera. –

+0

Cela ne fonctionne pas pour les dossiers/packages. (Au moins cela n'a pas fonctionné pour moi). Merci quand même :-) – codingFriend1

Questions connexes