文档目录(NSDocumentDirectory)是什么?

谁能给我解释一下 iOS 应用程序上的文档目录是什么以及什么时候使用它?

以下是我目前的看法:

对我来说,它似乎是一个中央文件夹,用户可以存储应用程序所需的任何文件。

这里和核心数据存储数据的地方不一样?

似乎每个应用程序都有自己的文档目录。

我可以自由地创建文档目录的子目录,如文档目录/图像或文档目录/视频?

147236 次浏览

您的应用程序只能(在非越狱设备上)在“沙箱”环境中运行。这意味着它只能访问自己内容中的文件和目录。例如 文件图书馆

看看 iOS 应用程式编程指南

要访问应用程序沙箱的 文件目录,可以使用以下命令:

IOS8和更新的操作系统,这是推荐的方法

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

如果你需要支持 iOS7或更早的版本

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

文件目录允许您存储应用程序创建或可能需要的文件和子目录。

要访问应用程序沙箱的 图书馆目录中的文件,请使用(代替上面的 paths) :

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

我在文档中找不到这个被接受的答案所建议的代码,但是我在这里找到了更新后的等价代码:

文件系统编程指南: : 访问文件和目录

- (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:

NSSearchPathForDirectoriesInDomain 函数的行为类似于 方法,但返回目录的 位置作为基于字符串的路径 而是 inDomains: method。

下面是一些其他有用的目录常量。毫无疑问,并非所有这些都在 iOS 中得到支持。还可以使用 NSHomeDirectory ()函数:

在 iOS 中,主目录是应用程序的沙箱目录。在 OS X 中,它是应用程序的沙箱目录或当前用户的主目录(如果应用程序不在沙箱中)

来自 NSPathUtilites.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

除了 Documents文件夹,iOS 还允许您将文件保存到 tempLibrary文件夹。

有关使用哪一个的更多信息,请参见文档中的链接:

你可以访问文档目录使用这个代码,它基本上是用来存储文件在 plist 格式:

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

下面是一个有用的小函数,它使得使用/创建 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;
}

使用这个小函数,可以很容易地在应用程序的 Document 目录中创建一个目录(如果它不存在的话) ,并将一个文件写入其中。

下面是我将如何创建目录,并将我的一个图像文件的内容写入其中:

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

希望这个能帮上忙!

这在 iOS8中已经改变了。请参阅以下技术说明: https://developer.apple.com/library/ios/technotes/tn2406/_index.html

苹果批准的方式(从上面的链接)如下:

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

Swift 3和4作为 global var:

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!
}
}

为这种尴尬的调用向 FileManager 添加一个扩展可能更简单,如果没有其他事情的话,也是为了整洁。比如:

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

正如前面提到的,你的应用程序运行在一个沙箱环境中,你可以使用文档目录来存储图片或者其他你的应用程序可能使用的资源,例如下载用户喜欢的离线 -d 文件 -文件系统基础-苹果文档-使用哪个目录,用于存储应用程序特定的文件

更新到迅捷5,您可以使用这些功能之一,根据需要-

func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}


func getCacheDirectory() -> URL {
let paths = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
return paths[0]
}


func getApplicationSupportDirectory() -> URL {
let paths = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
return paths[0]
}

用法:

let urlPath = "https://jumpcloud.com/wp-content/uploads/2017/06/SSH-Keys.png" //Or string path to some URL of valid image, for eg.


if let url = URL(string: urlPath){
let destination = getDocumentsDirectory().appendingPathComponent(url.lastPathComponent)
do {
let data = try Data(contentsOf: url) //Synchronous call, just as an example
try data.write(to: destination)
} catch _ {
//Do something to handle the error
}
}