有人可以向我解释一下iOS应用程序上的文档目录以及何时使用它?
以下是我目前的看法:
对我而言,它似乎是一个中央文件夹,用户可以在其中存储应用程序所需的任何文件。
这与Core Data存储数据的位置不同?
似乎每个应用都有自己的文档目录。
我可以自由创建文档目录的子目录,如文档目录/图像,或文档目录/视频?
答案 0 :(得分:192)
您的应用程序(在非越狱设备上)在“沙盒”环境中运行。这意味着它只能访问自己内容中的文件和目录。例如文档和库。
请参阅iOS Application Programming Guide。
要访问应用程序沙箱的文档目录,您可以使用以下命令:
+ (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
+ (NSString *) applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = paths.firstObject;
return basePath;
}
此文档目录允许您存储应用创建或可能需要的文件和子目录。
要访问应用沙箱使用的库目录中的文件(代替上面的paths
):
[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]
答案 1 :(得分:41)
在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];
}
答案 2 :(得分:21)
我找不到接受答案建议的文档中的代码,但我在此处找到了更新的等效文件:
<强> File System Programming Guide :: Accessing Files and Directories » 强>
- (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函数的行为类似于 URLForDirectory:inDomains:方法但返回目录 位置作为基于字符串的路径。你应该使用 URLForDirectory: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
答案 3 :(得分:8)
Swift 3和4作为全局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!
}
}
答案 4 :(得分:5)
除Documents
文件夹外,iOS还允许您将文件保存到temp
和Library
文件夹。
有关使用哪一个的更多信息,请参阅文档中的此链接:
答案 5 :(得分:5)
为这种笨拙的调用添加一个扩展到FileManager可能更干净,如果没有别的话,整洁。类似的东西:
extension FileManager {
static var documentDir : URL {
return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
}
}
答案 6 :(得分:4)
您可以使用此代码访问文档目录,它基本上用于以plist格式存储文件:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
return documentsDirectory;
答案 7 :(得分:1)
这是一个有用的小功能,可以更轻松地使用/创建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];
希望这有帮助!
答案 8 :(得分:0)
与其他提到的一样,您的应用程序在沙盒环境中运行,您可以使用documents目录存储图像或应用程序可能使用的其他资产。根据用户的喜好下载脱机d文件-File System Basics - Apple Documentation - Which directory to use, for storing application specific files
已更新为Swift 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
}
}