문서 디렉토리 (NSDocumentDirectory) 란 무엇입니까?


123

누군가 iOS 앱의 문서 디렉토리가 무엇이며 언제 사용하는지 설명해 줄 수 있습니까?

현재 내가 믿는 것은 다음과 같습니다.

나에게 그것은 사용자가 앱에 필요한 모든 파일을 저장할 수있는 중앙 폴더 인 것 같습니다.

이것은 Core Data가 데이터를 저장하는 위치와 다른 위치입니까?

각 앱이 자체 문서 디렉토리를 얻는 것 같습니다.

문서 디렉토리 / 이미지 또는 문서 디렉토리 / 비디오와 같은 문서 디렉토리의 하위 디렉토리를 자유롭게 만들 수 있습니까?


Iirc, NSDocumentDirectory는 앱 코어 데이터와 동일한 경로에 있으며 각 앱에는 고유 한 문서 디렉터리가 있습니다. 예, 앱에 필요한 모든 리소스를 여기에 자유롭게 넣을 수 있습니다. 그런데 질문이 아직 완료되지 않은 것 같습니다.
Zekareisoujin 2011-08-02

나는 방금 당신의 질문과 관련된 것을 여기에 게시했습니다. stackoverflow.com/questions/5105250/… 그것이 당신을 위해 작동하는지 siee에 확인하십시오.
Wytchkraft 2011 년

Google에서 온 모든 사람은 iOS 8에서 변경되었습니다. 아래 내 대답을 참조하십시오.
livingtech

sqlite 파일이 저장된 위치와 같습니다.
Anurag Bhakuni 2015 년

답변:


197

탈옥되지 않은 기기에서만 앱이 '샌드 박스'환경에서 실행됩니다. 즉, 자체 콘텐츠 내의 파일 및 디렉터리에만 액세스 할 수 있습니다. 예를 들어 문서라이브러리 .

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

문서 디렉토리를 사용하면 앱에서 만들거나 필요할 수있는 파일 및 하위 디렉토리를 저장할 수 있습니다.

앱 샌드 박스 의 Library 디렉토리 에있는 파일에 액세스하려면 위의 위치를 ​​사용합니다 paths.

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

13
나는 [@ "~ / Documents"stringByExpandingTildeInPath]가 같은 일을한다는 것을 발견했습니다. 이것이 낙담해야 할 이유가 있습니까?
Cthutu

35
@ "~ / Documents"와 함께 접근 방식을 사용하지 않을 것입니다. 하드 코딩 경로는 결코 좋은 생각이 아닙니다. 지금은 작동 할 수 있지만 Apple이 문서 디렉토리의 이름을 바꾸거나 이동하도록 선택하면 앱이 중단됩니다. NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);항상 올바른 디렉토리를 제공합니다!

16
제공된 API를 계속 사용해야합니다. 그것이 거기에있는 이유입니다! 당신은 지금까지 운이 좋았습니다.
nielsbot

20
내가 그것을 사용해야 할 때마다 이것을 구글링 해야하는 방법이 재밌습니다. 나는 모든 모바일 플랫폼 홈 / 쓰기 가능한 디렉토리에 대한 기본 전역 매개 변수를 제공해야한다고 생각
Ravindranath Akila

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

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확장의 정적 속성을 통해 정적 으로 범위를 지정하는 아이디어가 마음에 듭니다 .
Ray Fix

1
감사합니다 @RayFix, 귀하의 제안으로 제 답변을 업데이트했습니다!
Anton Plebanovich


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에 의해 주어졌습니다. 또한 애플이 리빙 텍의 답변에서 권장하는 방법을 고려할 때 2014 년에이 답변을 제공하는 것은 이상합니다.
제프

내가 반대표에 틀렸다고 생각한다면 그 이유를 설명해주십시오. 내 질문 중 하나에 대한 복수 반대 투표는 유치합니다. 이 사이트는 최고의 답변을 맨 위로 올립니다.
Jeff

@jeff 지적 해 주셔서 감사합니다. 몇 가지 조사를했고 당신이 옳았습니다. 새로운 솔루션 :-(NSURL *) applicationDocumentsDirectory {return [[[NSFileManager defaultManager] URLsForDirectory : NSDocumentDirectory inDomains : NSUserDomainMask] lastObject]; }
Sumit Oberoi 2015

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

도움이 되었기를 바랍니다 !


0

언급 된 다른 사람들과 마찬가지로 앱은 샌드 박스 환경에서 실행되며 문서 디렉토리를 사용하여 앱에서 사용할 수있는 이미지 또는 기타 자산을 저장할 수 있습니다. 사용자가 선호하는 오프라인 D 파일 다운로드- 파일 시스템 기본 사항-Apple 문서-응용 프로그램 특정 파일을 저장하기 위해 사용할 디렉토리

신속한 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.