web-dev-qa-db-fra.com

Quel est le répertoire de documents (NSDocumentDirectory)?

Quelqu'un peut-il m'expliquer quel est le répertoire de documents sur une application iOS et quand l'utiliser?

Voici ce que je crois à présent:

Pour moi, cela semble être un dossier central où l'utilisateur peut stocker tous les fichiers nécessaires à l'application.

Ce serait un emplacement différent de celui où Core Data stocke ses données?

Il semble que chaque application ait son propre répertoire de documents.

Je suis libre de créer un sous-répertoire du répertoire de documents, tel que répertoire/images, ou répertoire de documents/vidéos?

118
user798719

Votre application uniquement (sur un appareil non jailbreaké) s'exécute dans un environnement "en sandbox". Cela signifie qu'il ne peut accéder qu'aux fichiers et aux répertoires contenus dans son propre contenu. Par exemple Documents et Bibliothèque .

Voir le Guide de programmation d'applications iOS .

Pour accéder au répertoire Documents de votre sandbox d'applications, vous pouvez utiliser les éléments suivants:

iOS 8 et plus récent, c'est la méthode recommandée

+ (NSURL *)applicationDocumentsDirectory
{
     return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

si vous devez prendre en charge iOS 7 ou une version antérieure

+ (NSString *) applicationDocumentsDirectory 
{    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = paths.firstObject;
    return basePath;
}

Ce répertoire Documents vous permet de stocker des fichiers et des sous-répertoires créés ou nécessaires par votre application.

Pour accéder aux fichiers du répertoire Library du sandbox de vos applications, utilisez (à la place de paths ci-dessus):

[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]
193
WrightsCS

Cela a changé dans iOS 8. Consultez la note technique suivante: https://developer.Apple.com/library/ios/technotes/tn2406/_index.html

La manière Apple sanctionnée (à partir du lien ci-dessus) est la suivante:

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
41
livingtech

Je n'ai pas trouvé le code suggéré dans la documentation par la réponse acceptée, mais j'ai trouvé l'équivalent mis à jour ici:

Guide de programmation du système de fichiers :: Accès aux fichiers et aux répertoires "

- (NSURL*)applicationDataDirectory {
    NSFileManager* sharedFM = [NSFileManager defaultManager];
    NSArray* possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory
                                 inDomains:NSUserDomainMask];
    NSURL* appSupportDir = nil;
    NSURL* appDirectory = nil;

    if ([possibleURLs count] >= 1) {
        // Use the first directory (if multiple are returned)
        appSupportDir = [possibleURLs objectAtIndex:0];
    }

    // If a valid app support directory exists, add the
    // app's bundle ID to it to specify the final directory.
    if (appSupportDir) {
        NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier];
        appDirectory = [appSupportDir URLByAppendingPathComponent:appBundleID];
    }

    return appDirectory;
}

Cela décourage l'utilisation de NSSearchPathForDirectoriesInDomain:

La fonction NSSearchPathForDirectoriesInDomains se comporte comme la méthode URLsForDirectory: inDomains:, mais renvoie l’emplacement du répertoire sous la forme d’un chemin basé sur des chaînes. Vous devriez plutôt utiliser la méthode URLsForDirectory: inDomains:.

Voici quelques autres constantes de répertoire utiles pour jouer. Tous ces éléments ne sont sans doute pas pris en charge par iOS. Vous pouvez également utiliser la fonction NSHomeDirectory () qui:

Sous iOS, le répertoire de base est le répertoire de sandbox de l’application. Sous OS X, il s’agit du répertoire de sandbox de l’application ou du répertoire de base de l’utilisateur actuel (si l’application ne se trouve pas dans un sandbox).

De NSPathUtilities.h

NSApplicationDirectory = 1,             // supported applications (Applications)
    NSDemoApplicationDirectory,             // unsupported applications, demonstration versions (Demos)
    NSDeveloperApplicationDirectory,        // developer applications (Developer/Applications). DEPRECATED - there is no one single Developer directory.
    NSAdminApplicationDirectory,            // system and network administration applications (Administration)
    NSLibraryDirectory,                     // various documentation, support, and configuration files, resources (Library)
    NSDeveloperDirectory,                   // developer resources (Developer) DEPRECATED - there is no one single Developer directory.
    NSUserDirectory,                        // user home directories (Users)
    NSDocumentationDirectory,               // documentation (Documentation)
    NSDocumentDirectory,                    // documents (Documents)
    NSCoreServiceDirectory,                 // location of CoreServices directory (System/Library/CoreServices)
    NSAutosavedInformationDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 11,   // location of autosaved documents (Documents/Autosaved)
    NSDesktopDirectory = 12,                // location of user's desktop
    NSCachesDirectory = 13,                 // location of discardable cache files (Library/Caches)
    NSApplicationSupportDirectory = 14,     // location of application support files (plug-ins, etc) (Library/Application Support)
    NSDownloadsDirectory NS_ENUM_AVAILABLE(10_5, 2_0) = 15,              // location of the user's "Downloads" directory
    NSInputMethodsDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 16,           // input methods (Library/Input Methods)
    NSMoviesDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 17,                 // location of user's Movies directory (~/Movies)
    NSMusicDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 18,                  // location of user's Music directory (~/Music)
    NSPicturesDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 19,               // location of user's Pictures directory (~/Pictures)
    NSPrinterDescriptionDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 20,     // location of system's PPDs directory (Library/Printers/PPDs)
    NSSharedPublicDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 21,           // location of user's Public sharing directory (~/Public)
    NSPreferencePanesDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 22,        // location of the PreferencePanes directory for use with System Preferences (Library/PreferencePanes)
    NSApplicationScriptsDirectory NS_ENUM_AVAILABLE(10_8, NA) = 23,      // location of the user scripts folder for the calling application (~/Library/Application Scripts/code-signing-id)
    NSItemReplacementDirectory NS_ENUM_AVAILABLE(10_6, 4_0) = 99,       // For use with NSFileManager's URLForDirectory:inDomain:appropriateForURL:create:error:
    NSAllApplicationsDirectory = 100,       // all directories where applications can occur
    NSAllLibrariesDirectory = 101,          // all directories where resources can occur
    NSTrashDirectory NS_ENUM_AVAILABLE(10_8, NA) = 102                   // location of Trash directory

Et enfin, quelques méthodes pratiques dans une catégorie NSURL http: //club15cc.com/code/ios/easy-ios-file-directory-paths-with-this-handy-nsurl-category

21
Hari Karam Singh

Swift 3 et 4 en tant que variable globale:

var documentsDirectory: URL {
    return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!
}

En tant qu'extension FileManager:

extension FileManager {
    static var documentsDirectory: URL {
        return `default`.urls(for: .documentDirectory, in: .userDomainMask).last!
    }

    var documentsDirectory: URL {
        return urls(for: .documentDirectory, in: .userDomainMask).last!
    }
}
8

Il peut être plus propre d’ajouter une extension à FileManager pour ce type d’appel peu commode, pour un rangement si rien d’autre. Quelque chose comme:

extension FileManager {
    static var documentDir : URL {
        return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    }
}
5
Paul Robinson

Outre le dossier Documents, iOS vous permet également de sauvegarder des fichiers dans les dossiers temp et Library.

Pour plus d'informations sur celui à utiliser, voir ce lien dans la documentation:

5
Eric

Vous pouvez accéder au répertoire de documents en utilisant ce code, il est essentiellement utilisé pour stocker un fichier au format plist:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
return documentsDirectory;
4
Sumit Oberoi

Voici une petite fonction utile, qui facilite un peu l’utilisation/la création de dossiers iOS.

Vous lui transmettez le nom d'un sous-dossier, il vous renverra le chemin complet et vous assurera que le répertoire existe.

(Personnellement, je colle cette fonction statique dans ma classe AppDelete, mais ce n'est peut-être pas l'endroit le plus intelligent pour le dire.)

Voici comment vous l'appeleriez, pour obtenir le "chemin complet" d'un sous-répertoire MySavedImages:

NSString* fullPath = [AppDelegate getFullPath:@"MySavedImages"];

Et voici la fonction complète:

+(NSString*)getFullPath:(NSString*)folderName
{
    //  Check whether a subdirectory exists in our sandboxed Documents directory.
    //  Returns the full path of the directory.
    //
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    if (paths.count < 1)
        return nil;

    NSString *rootFolder = [paths firstObject];
    NSString* fullFolderPath = [rootFolder stringByAppendingPathComponent:folderName];

    BOOL isDirectory;
    NSFileManager* manager = [NSFileManager defaultManager];

    if (![manager fileExistsAtPath:fullFolderPath isDirectory:&isDirectory] || !isDirectory) {
        NSError *error = nil;
        NSDictionary *attr = [NSDictionary dictionaryWithObject:NSFileProtectionComplete
                                                         forKey:NSFileProtectionKey];
        [manager createDirectoryAtPath:fullFolderPath
           withIntermediateDirectories:YES
                            attributes:attr
                                 error:&error];
        if (error) {
            NSLog(@"Error creating directory path: %@", [error localizedDescription]);
            return nil;
        }
    }
    return fullFolderPath;
}

En utilisant cette petite fonction, il est facile de créer un répertoire dans le répertoire Documents de votre application (s'il n'existe pas déjà) et d'y écrire un fichier.

Voici comment créer le répertoire et y écrire le contenu de l'un de mes fichiers image:

//  Let's create a "MySavedImages" subdirectory (if it doesn't already exist)
NSString* fullPath = [AppDelegate getFullPath:@"MySavedImages"];

//  As an example, let's load the data in one of my images files
NSString* imageFilename = @"icnCross.png";

UIImage* image = [UIImage imageNamed:imageFilename];
NSData *imageData = UIImagePNGRepresentation(image);

//  Obtain the full path+filename where we can write this .png to, in our new MySavedImages directory
NSString* imageFilePathname = [fullPath stringByAppendingPathComponent:imageFilename];

//  Write the data
[imageData writeToFile:imageFilePathname atomically:YES];

J'espère que cela t'aides !

1
Mike Gledhill