ドキュメントディレクトリ(NSDocumentDirectory)とは何ですか?


123

iOSアプリのドキュメントディレクトリとは何ですか?

これが私が現在信じていることです:

私には、それはユーザーがアプリに必要なファイルを保存できる中央フォルダーのようです。

これは、Core Dataがデータを保存する場所とは異なる場所ですか?

各アプリは独自のドキュメントディレクトリを取得しているようです。

ドキュメントディレクトリ/画像、ドキュメントディレクトリ/ビデオなど、ドキュメントディレクトリのサブディレクトリを自由に作成できますか?


つまり、NSDocumentDirectoryはアプリのコアデータと同じパスにあり、各アプリには独自のドキュメントディレクトリがあります。そして、はい、アプリに必要なリソースをここに自由に配置できます。ところで、あなたの質問はまだ完成していないようですが?
Zekareisoujin 2011

私はここであなたの質問に私が関係すると思う何かを掲示stackoverflow.com/questions/5105250/...それはあなたのために働く場合SIEEすることを確認してください。
Wytkkraft、2011

グーグルから来た人のために、これはiOS 8で変更されたことに注意してください。以下の私の答えを見てください。
Livingtech

sqliteファイルが保存されている場所と同じです。
Anurag Bhakuni 2015年

回答:


197

アプリのみ(脱獄されていないデバイス上)は「サンドボックス」環境で実行されます。これは、自身のコンテンツ内のファイルとディレクトリにのみアクセスできることを意味します。たとえば、ドキュメントライブラリ

iOSアプリケーションプログラミングガイドを参照してください。

アプリケーションサンドボックスのドキュメントディレクトリにアクセスするには、以下を使用できます。

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

このドキュメントディレクトリを使用すると、アプリが作成する、またはアプリが必要とする可能性のあるファイルとサブディレクトリを保存できます。

アプリのサンドボックスのライブラリディレクトリにあるファイルにアクセスするには、(paths上記の代わりに)使用します。

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

13
[@ "〜/ Documents" stringByExpandingTildeInPath]が同じことを行うことを発見しました。これが推奨されない理由はありますか?
クトゥツ

35
@ "〜/ Documents"ではこのアプローチを使用しません。パスをハードコーディングすることは決して良い考えではありません。現在は機能する可能性がありますが、AppleがDocumentsディレクトリの名前変更または移動を選択した場合、アプリは破損します。NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);常に正しいディレクトリを提供します!

16
提供されているAPIを使用する必要があります。それがそこにある理由です!あなたは今まで幸運でした。
nielsbot 2013年

20
使用するたびにこれをググる必要がある陽気な方法。私はすべてのモバイルプラットフォームがhome / writableディレクトリのデフォルトのグローバルパラメータを提供する必要があると思います
Ravindranath Akila 14

1
フォルダへの書き込みをアプリの能力についての情報で更新されたリンク:developer.apple.com/library/mac/documentation/FileManagement/...
フィル

43

これは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];
}

7
これはあなたが望む答えです!今年はほぼ2016年です。これは、回答が古くなっている人気のある質問です。
ジェフ

上記の方法を使用してドキュメントディレクトリのパスを取得できますか?url.pathのような?
Abuzar Amin 2016

21

承認された回答で提案されたドキュメントでコードを見つけることができませんでしたが、更新された同等のコードが見つかりました:

ファイルシステムプログラミングガイド::ファイルとディレクトリへのアクセス»

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

グローバル変数としての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!
    }
}

ありがとう。私はいつもこれを忘れています。:) API設計ガイドラインを堅持したい場合は、名前を付けるかdocumentDirectoryURL、単純documentDirectoryに型に依存することができます。FileManager拡張機能の静的プロパティを介して静的にスコープするというアイデアが好きです。
レイフィックス

1
@RayFixに感謝します。私の回答をあなたの提案で更新しました!
アントンプレバノビッチ2018年


6

この種の厄介な呼び出しのためにFileManagerに拡張機能を追加するほうがきれいな場合があります。何かのようなもの:

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

4

このディレクトリを使用してドキュメントディレクトリにアクセスできます。このコードは、基本的にplist形式でファイルを保存するために使用されます。

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

これと同じ答えが3年前にWrightsCSによって与えられました。また、AppleがLivingtechの回答にある方法を推奨していることを考えると、2014年にこの回答を出すのは奇妙です。
ジェフ

私が反対票を投じるのが間違っていると思われる場合は、その理由を説明してください。私の質問の1つに対する復讐反対票は子供じみています。このサイトは、最高の答えを上に押し上げることについてです。
Jeff

@jeffは指摘してくれてありがとう、いくつかの調査を行った、そしてあなたは正しかった。新しいソリューション:-(NSURL *)applicationDocumentsDirectory {return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; }
Sumit Oberoi

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

この小さな関数を使用すると、アプリのドキュメントディレクトリにディレクトリを作成し(まだ存在しない場合)、ファイルをそこに書き込むのは簡単です。

ここに私がディレクトリを作成し、そこに私の画像ファイルの1つの内容を書き込む方法があります:

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

お役に立てれば !


0

他の言及したように、アプリはサンドボックス環境で実行され、ドキュメントディレクトリを使用して、アプリが使用する可能性のある画像やその他のアセットを保存できます。ユーザーが好むようにoffline-dファイルをダウンロードする-ファイルシステムの基本-Appleドキュメント-アプリケーション固有のファイルを保存するために使用するディレクトリ

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
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.