Что такое каталог документов (NSDocumentDirectory)? - PullRequest
118 голосов
/ 02 августа 2011

Может кто-нибудь объяснить мне, что каталог документов находится в приложении iOS и когда его использовать?

Вот что я верю в настоящее время:

Мне кажется, это центральная папка, в которой пользователь может хранить любые файлы, необходимые для приложения.

Это будет место, отличное от того, где Core Data хранит свои данные?

Кажется, что каждое приложение получает свой собственный каталог документов.

Я могу создать подкаталог каталога документов, например, каталог документов / изображения или каталог документов / видео?

Ответы [ 8 ]

193 голосов
/ 02 августа 2011

Только ваше приложение (на не взломанном устройстве) работает в «изолированной» среде.Это означает, что он может получить доступ только к файлам и каталогам в пределах своего собственного содержимого.Например, Документы и Библиотека .

См. Руководство по программированию приложений iOS .

КомуЗайдя в каталог Documents своей изолированной программной среды приложений, вы можете использовать следующее:

iOS 8 и новее, это рекомендуемый метод

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

, если вам нужноподдержка iOS 7 или более ранних версий

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

Этот каталог Documents позволяет хранить файлы и подкаталоги, которые может создавать ваше приложение или может понадобиться.

Для доступа к файлам в Библиотека каталог использования вашей изолированной программной среды приложений (вместо paths выше):

[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]
41 голосов
/ 12 мая 2015

Это изменилось в iOS 8. См. Следующее техническое примечание: https://developer.apple.com/library/ios/technotes/tn2406/_index.html

Разрешение Apple (по ссылке выше) выглядит следующим образом:

// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
21 голосов
/ 25 октября 2012

Я не смог найти код в документе, предложенный принятым ответом, но нашел обновленный эквивалент здесь:

Руководство по программированию файловой системы :: Доступ к файлам и каталогам »

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

Не рекомендуется использовать NSSearchPathForDirectoriesInDomain:

Функция NSSearchPathForDirectoriesInDomains ведет себя как метод URLsForDirectory: inDomains:, но возвращает расположение каталога в виде строкидорожка.Вместо этого вы должны использовать URLsForDirectory: inDomains: метод.

Вот некоторые другие полезные константы каталога, с которыми можно поиграть.Без сомнения, не все из них поддерживаются в iOS.Также вы можете использовать функцию NSHomeDirectory (), которая:

В iOS домашний каталог - это каталог песочницы приложения.В OS X это каталог песочницы приложения или домашний каталог текущего пользователя (если приложение не находится в песочнице)

Из 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

И, наконец, некоторые удобные методы в категории NSURL http://club15cc.com/code/ios/easy-ios-file-directory-paths-with-this-handy-nsurl-category

8 голосов
/ 02 мая 2017

Swift 3 и 4 как глобальная переменная:

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

Как расширение 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!
    }
}
5 голосов
/ 17 декабря 2017

Может быть проще добавить расширение в FileManager для такого рода неуклюжих вызовов, для аккуратности, если ничего больше. Что-то вроде:

extension FileManager {
    static var documentDir : URL {
        return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    }
}
5 голосов
/ 20 марта 2013

Помимо папки Documents, iOS также позволяет сохранять файлы в папки temp и Library.

Для получения дополнительной информации о том, какой использовать, см. Эту ссылку в документации:

4 голосов
/ 18 июля 2014

Вы можете получить доступ к каталогу документов, используя этот код, он в основном используется для хранения файла в формате plist:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
return documentsDirectory;
1 голос
/ 30 января 2015

Вот небольшая полезная функция, которая немного облегчает использование / создание папок iOS.

Вы передаете ей имя подпапки, она вернет вам полный путь, и убедитесь, чтокаталог существует.

(Лично я вставляю эту статическую функцию в мой класс AppDelete, но, возможно, это не самое умное место для ее размещения.)

Вот как вы бы ее назвали, чтобыполучить «полный путь» подкаталога MySavedImages:

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

И вот полная функция:

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

Используя эту маленькую функцию, легко создать каталог в Documents вашего приложениякаталог (если он еще не существует), и записать в него файл.

Вот как я могу создать каталог и записать в него содержимое одного из моих файлов изображений:

//  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];

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...