दस्तावेज़ निर्देशिका (NSDocumentDirectory) क्या है?


123

क्या कोई मुझे समझा सकता है कि एक iOS ऐप पर दस्तावेज़ निर्देशिका क्या है और इसका उपयोग कब करना है?

यहाँ वर्तमान में मेरा मानना ​​है:

मेरे लिए, यह एक केंद्रीय फ़ोल्डर लगता है जहां उपयोगकर्ता ऐप के लिए आवश्यक किसी भी फ़ाइल को संग्रहीत कर सकता है।

यह एक अलग स्थान होगा जहां कोर डेटा अपना डेटा संग्रहीत करता है?

ऐसा लगता है जैसे प्रत्येक ऐप को अपने स्वयं के दस्तावेज़ निर्देशिका मिलती है।

मैं दस्तावेज़ निर्देशिका, चित्र निर्देशिका, या दस्तावेज़ निर्देशिका / वीडियो जैसे दस्तावेज़ निर्देशिका की उपनिर्देशिका बनाने के लिए स्वतंत्र हूं?


Iirc, NSDocumentDirectory ऐप कोर डेटा के समान पथ में निहित है, और प्रत्येक ऐप की अपनी दस्तावेज़ निर्देशिका है। और हां, आप अपने ऐप के लिए जो भी संसाधन की आवश्यकता है, उसे स्वतंत्र रूप से रख सकते हैं। वैसे, ऐसा लगता है कि आपका प्रश्न अभी तक पूरा नहीं हुआ है?
ज़ेकेरीसौजिन

मैंने अभी कुछ पोस्ट किया है जो मुझे लगता है कि आपके प्रश्न से संबंधित है यहां stackoverflow.com/questions/5105250/… यह जाँच करें कि क्या यह आपके लिए काम करता है।
विट्च्क्राफ्ट

Google से आने वाले किसी व्यक्ति के लिए, ध्यान दें कि यह iOS 8 में बदल गया है। नीचे मेरा जवाब देखें।
जीवित रहते हुए '20

यह वही स्थान है जहाँ आपकी sqlite फ़ाइल सहेजी गई है।
अनुराग भाकुनी

जवाबों:


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
मुझे पता चला है कि [@ "~ / दस्तावेज़" stringByExpandingTildeInPath] यही काम करता है। क्या कोई कारण है कि इसे हतोत्साहित किया जाना चाहिए?
चेट्टू

35
मैं @ "~ / दस्तावेज़" के साथ दृष्टिकोण का उपयोग नहीं करूंगा। कठिन मार्ग कभी भी अच्छा विचार नहीं है। यह अब काम कर सकता है, लेकिन यदि Apple कभी दस्तावेज़ निर्देशिका का नाम बदलने या स्थानांतरित करने का विकल्प चुनता है, तो आपका ऐप टूट जाएगा। NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);हमेशा आपको सही निर्देशिका देगा!

16
आपको अभी भी दिए गए API का उपयोग करना चाहिए। इसलिए यह वहाँ है! आप अब तक भाग्यशाली रहे हैं।
नील्सबॉट

20
प्रफुल्लित करने वाला कि मुझे हर बार इसका उपयोग करने की आवश्यकता है। मुझे लगता है कि सभी मोबाइल प्लेटफ़ॉर्म को घर / लेखन योग्य निर्देशिका के लिए डिफ़ॉल्ट वैश्विक पैरामीटर प्रदान करना चाहिए
रवींद्रनाथ अकीला

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 की तरह?
अबूझार अमीन

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 में, होम डायरेक्टरी एप्लिकेशन के सैंडबॉक्स डायरेक्टरी है। ओएस एक्स में, यह एप्लिकेशन का सैंडबॉक्स निर्देशिका या वर्तमान उपयोगकर्ता की होम निर्देशिका है (यदि एप्लिकेशन सैंडबॉक्स में नहीं है)

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-thy-nsurl-category


8

वैश्विक संस्करण के रूप में स्विफ्ट 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!
    }
}

धन्यवाद। मैं हमेशा यह भूल जाता हूं। :) यदि आप एपीआई डिजाइन दिशानिर्देशों पर तेजी से पकड़ बनाना चाहते हैं, तो आप इसे documentDirectoryURLया बस नाम दे सकते हैं documentDirectoryऔर प्रकार पर भरोसा कर सकते हैं। मैं इसे FileManagerविस्तार से एक स्थिर संपत्ति के लिए सांख्यिकीय रूप से डांटने के विचार को पसंद करता हूं ।
रे फिक्स

1
धन्यवाद @RayFix, आपके सुझाव से मेरे उत्तर को अपडेट किया गया!
एंटोन प्लीबानोविच

6

Documentsफ़ोल्डर के अलावा , iOS आपको फ़ाइलों tempऔर Libraryफ़ोल्डरों को सहेजने की सुविधा भी देता है ।

अधिक जानकारी के लिए जिस पर एक का उपयोग करना है, इस लिंक को प्रलेखन से देखें:


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 साल पहले दिया गया था। इसके अलावा, 2014 में यह जवाब देना अजीब है, यह देखते हुए कि Apple लिविंगटेक के उत्तर में विधि की सिफारिश करता है।
जेफ

अगर आपको लगता है कि मुझे वोट देना गलत है, तो कृपया मुझे समझाएं। मेरे एक सवाल पर वोट का बदला लेना बचकाना है। यह इस साइट को शीर्ष पर सर्वश्रेष्ठ उत्तरों को आगे बढ़ाने के बारे में बताता है।
जेफ

@ जफ आपको इशारा करने के लिए धन्यवाद, कुछ शोध किया और आप सही थे। नया समाधान: - (NSURL *) applicationDocumentsDirectory {वापसी [[[NSFileManager defaultManager] URLsForDirectory: NSDocumentDirectory inDomains: NSUserDomodMask] lastObject]; }
सुमित ओबेरॉय

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

इस छोटे से फ़ंक्शन का उपयोग करना, आपके ऐप के दस्तावेज़ निर्देशिका में निर्देशिका बनाना आसान है (यदि यह पहले से मौजूद नहीं है), और उस पर एक फ़ाइल लिखना है।

यहां बताया गया है कि मैं निर्देशिका कैसे बनाऊंगा, और उसमें अपनी एक छवि फ़ाइल की सामग्री लिखूंगा:

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

अन्य लोगों की तरह, आपका ऐप सैंडबॉक्स वाले वातावरण में चलता है और आप दस्तावेज़ निर्देशिका का उपयोग उन छवियों या अन्य संपत्तियों को संग्रहीत करने के लिए कर सकते हैं जो आपके ऐप का उपयोग कर सकते हैं, जैसे। उपयोगकर्ता की पसंद के रूप में ऑफ़लाइन-डी फ़ाइलों को डाउनलोड करना - फ़ाइल सिस्टम मूल बातें - 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
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.