I have created some PDF files programatically, which i am storing into the devices memory using the following code >>>>
NSString *fileName = [NSString stringWithFormat:#"SampleTextFile.pdf",strFinalString];
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *saveDirectory = [path objectAtIndex:0];
NSString *saveFileName = fileName;
NSString *documentPath = [saveDirectory stringByAppendingPathComponent:saveFileName];
I can see the file in the Devices Document folder.
I want to hide these files so that the user can not see or delete it.
Can anyone help me out to do this.
A good place to store private data is in ~/Library/Application Support/, which is the folder used on the Mac for this purpose.
You can generate a path to this folder using:
NSString *appSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject];
You'll have to create the folder yourself the first time you use it, which you can do with:
if (![[NSFileManager defaultManager] fileExistsAtPath:appSupportDir])
{
[[NSFileManager defaultManager] createDirectoryAtPath:appSupportDir withIntermediateDirectories:YES attributes:nil error:NULL];
}
I wrote a simple library that makes this and all other useful iOS folders available as methods on NSFileManager: https://github.com/nicklockwood/StandardPaths
Just prefix the filename with a dot, as in .SampleTextFile.pdf.
But the real solution is to not store the document in the NSDocumentDirectory in the first place. You should create subdirectory in the NSLibraryDirectory and store this stuff there. It also gets backed up and will not get purged like Caches and tmp, but the user cannot access it with iTunes.
Related
I have created a custom property list file. The file is stored in the application document.
While user login is successful the login information is stored in the plist, and it is working fine.
The plist content are cleared while log out, this also works fine.
When i am still login i killed the application. When the app opens the plist data i cleared.
code used to save to file:
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"xxxxPlist.plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
plistPath = [[NSBundle mainBundle] pathForResource:#"xxxxPlist" ofType:#"plist"];
}
dict=[[self cleanDictionary:[dict mutableCopy]] mutableCopy];
NSDictionary *plistDict=[[NSDictionary alloc] initWithObjectsAndKeys:dict,#"login_data", nil];
NSError *error = nil;
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList:plistDict format:NSPropertyListXMLFormat_v1_0 options:NSPropertyListImmutable error:&error];
if(plistData)
{
[plistData writeToFile:plistPath atomically:YES];
}
else
{
//error here
NSLog(#"%# ",error);
}
code used to fetch data
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"xxxx.plist"];
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
plistPath = [[NSBundle mainBundle] pathForResource:#"xxxxPlist" ofType:#"plist"];
}
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
return [dict objectForKey:#"login_data"];
I there any way out to persist the data?
There are several things that may be causing problems
When saving to file
1) My understanding is that you specifically want to save to /Documents folder specifically to ensure your file persists
2) So you correctly build following path
"/Documents/xxxxPlist.plist"
3) But then why do you check if a file already exists at that location?
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath])
{
plistPath = [[NSBundle mainBundle] pathForResource:#"xxxxPlist" ofType:#"plist"];
}
You just have to write to the path when you are ready.
If there is an old file at this location it will be overwritten.
And my understanding is this is the wanted behaviour, because you've already read that file and the data is in that dictionary "dict".
4) Also, by asking NSBundle to give you path for your file name
"xxxxPlist.plist"
there is a risk that it will just give you back some other path with file named the same (not in /Documents) if such file happens to exist. For example if you happened to write to say, /Cache folder earlier (with different code), your app will keep getting the /Cache path and keep reading/writong there (not in /Documents). And with the existing code you would have gotten nil here for path on the very first run, so not sure how he file got created in the first place.
5) Then I am not sure what exactly does this line
dict=[[self cleanDictionary:[dict mutableCopy]] mutableCopy];
Why first make a mutable copy, then presumably get immutable copy back and get a mutable one of it. Can't -cleanDictionary: just return the same mutable copy it was passed?
When reading from file
1) Not sure why you're searching for a different file first?
"/Documents/xxxx.plist" not "/Documents/xxxxPlist.plist"
Also what happens if "xxxx.plist" exists, then you'll never get to "xxxxPlist.plist" that you are writing in the other section.
2) Then, yes, you have to check if a file exists at certain path before you try to read it. But, in your case, if it does not exist, you don't ask NSBundle for another location, because you need your specific file in /Documents, and you don't know what you'll get from NSBundle, if your file is not where it should be.
So if there is no "xxxxPlist.plist" file, it's just your first run of the app and you will be creating your initial dict.
I want to retrieve all the pdf documents from my iPhone, including all the pdf files that are stored in other apps like Adobe Acrobat.
What I have now is:
NSString *path = [NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
for (NSString *fileName in directoryContent) {
if ([fileName hasSuffix:#"pdf"]) {
//add files to an array
}
}
Which only points to one directory.
Firstly you are only getting the first path to the first directory, so you're only searching that one. Secondly, apple suggests to use the NSFileManager to search. Thirdly, be aware that developers of other apps can save their documents in different places, that you can't access or are not returned by these functions (Just so you are aware of this).
If you want to get array of all pdf files in Document directory, then use below code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSArray *arrPdfs = [[NSBundle bundleWithPath:[paths objectAtIndex:0]] pathsForResourcesOfType:#"pdf" inDirectory:nil];
arrPdfs will contain all pdfs in Document directory.
My app stored downloaded audios and videos in document directory.Some users of app facing the problem that the content downloaded on their device getting disappeared with out any specific reason i.e app update. To save a file my path is as follows.
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
docsDir = dirPaths[0];
NSString *filepath = [NSString stringWithFormat:#"%#/%#_%#_%#", docsDir,username,audioId,fileName];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
The username , audioID and fileName in my app never change. So only option left is that somehow the path of my document directory is changing at the time when app try to search for the saved files, as described in Apple Doc. So i just want to know if i am thinking in the write direction or there is some other reason behind disappearing of content?
create your docs dir as below:
NSString * docsDir = [[dirPaths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:#"%#_%#_%#", username, audioId, fileName]];
I have a folder called PhotoSet in my Xcode iOS App. I want to convert the UIImage to a jpg and put it into the folder. Here is what I have so far (by the way, if it is at all relevant, the UIImage is taken from a photo that the user takes):
NSData * imageData = UIImageJPEGRepresentation(chosenImage, 1.0);
if (imageData != nil) {
[imageData writeToFile:#"/Users/Toly/Desktop/PhotoMap/PhotoMap/PhotoSet/test.jpg" atomically:YES];
}
I get no errors or warnings. However, no picture gets saved to any folder. What should I do?
You need to write to a directory that is actually on the iPhone. Most of the time you'll want to write to the documents directory. You can get the path to it like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
This gives you the base documents directory, if you want to place the folder in a sub directory you'll need to create that folder before you do like so.
NSString *folderPath = [documentsDirectory stringByAddingPathComponent:#"myFolder/images"];
NSError *error = nil;
NSFileManager *fm = [[NSFileManager alloc] init]
[fm createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:&error];
Then to save your image data to that folder you'll do something like this
NSString *imageDataPath = [folderPath stringByAppendingPathComponent:#"myImage"];
BOOL success = [imageData writeToFile:imageDataPath];
Also, you can NSLog the imageDataPath it'll give you the exact location that file is saved so you can navigate to the actual file in finder if you're using the iOS simulator.
Your phone does not contain a data structure of files mirroring "/Users/Toly/Desktop/PhotoMap/PhotoMap/PhotoSet/test.jpg"
If you want the image to persist in memory, try using nsuserdefaults, or xcassets or Coredata. If you are absolutely intent on writing to a file, check out the NSCoding and NSFileManager tutorial below:
http://www.raywenderlich.com/1914/nscoding-tutorial-for-ios-how-to-save-your-app-data
I have an app that stores images from the user in the app/documents folder, I'm doing the following code determine the path to save it:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *imageFilename = [[[[NSNumber alloc] initWithInteger:self.nextID] stringValue] stringByAppendingFormat:#".jpg"];
NSString *dirPath = [docs stringByAppendingFormat:#"/Photos/"];
imagePath = [dirPath stringByAppendingString:imageFilename];
it gives me a path similar to (in simulator):
/var/mobile/Applications/C9C43CFD-6A5F-40CF-8BAE-20496B5A544A/Documents/Photos/1.jpg
I save this path to show this image when I need.
My problem is, when I sent an update in the app store, after update the app it cant show the images anymore.
My understand is the Documents folder cant change when update the app in AppStore.
My probably reason for that it the name between Applications folder and Documentar has changed, is it true when update a app version from AppStore?
Does anyone has any idea? is there any way to test this app update local?
Thanks
You need to save the relative path after the Documents directory, not the absolute path. The app's directory can change during an update but the structure inside the app's sandbox won't change.
Also, there is a slightly better way to build your path:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *imageFilename = [NSString stringWithFormat:#"%d.jpg", self.nextID];
NSString *dirPath = [docs stringByAppendingPathComponent:#"Photos"];
imagePath = [dirPath stringByAppendingPathComponent:imageFilename];
When the app is updated from the App Store, the contents of the Documents directory are unchanged. The app bundle and all its contents are replaced with the new version, but the Documents folder is a safe place to store content between app versions.