renaming and saving in NSDocumentsDirectory - iphone

Its like this, in my app, I have a UIScrollView on it is a thumbnail view, they are images from my NSCachesDirectory.
I saved them from my picker then named them in my array like: images0.png,images.1.png... etc
So for example I have images in my directory this way : images0.png, images1.png, images2.png, images3.png.
Then I delete images1.png, the remaining images will be like this : images0.png,images2.png, images3.png right?
What I wanted to achieve is get the images in NSDocumentsDirectory then renamed them AGAIN or sort them again like images0.png, images1.png, images2.png...etc again?
is this possible? hope you could help me.

Use this NSFileManger moveItemAtPath: toPath: error: but you should supply the toPath:same_path_but_different_filename. This moves the file to a new path with new file name that you provide. see this
Since it seems you want the whole logic to rename your images file, here is the code you can try provided the files are in the Document directory
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * oldPath =[[NSString alloc]init];
NSString * newPath =[[NSString alloc]init];
int count=0;
for (int i=0; i<=[[fileManager contentsOfDirectoryAtPath:documentsDirectory error:nil]count]; i++) {
oldPath=[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"images%d.png",i]];
if ([fileManager fileExistsAtPath:oldPath]) {
newPath=[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"images%d.png",count]];
[fileManager moveItemAtPath:oldPath toPath:newPath error:nil];
count+=1;
}
}

Apple doesnot allow renameing of file saved. So alternative is to get all contents at document directory like this:
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:yourDocDirPath error:NULL];
Now sort like this:
NSSortDescriptor * descriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending: YES comparator:^NSComparisonResult(id obj1, id obj2){
return [obj1 compare: obj2 options: NSNumericSearch];
}];
NSArray * sortedDirectoryContent = [directoryContent sortedArrayUsingDescriptors:[NSArray arrayWithObject: descriptor]];
We have sorted array rewrite all files with new name:
for(NSString *fileName in sortedDirectoryContent)
{
NSString *filePath = [yourDocDirPath stringByAppendingPathComponent:fileName];
NSData *fileData = [[NSData alloc]initWithContentsOfFile:filePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
if(fileData)
{
NSString *newFilePath = [yourDocDirPath stringByAppendingPathComponent:#"New Name here"];
[fileData writeToFile:newFilePath atomically:YES];
}
}
else
{
if(fileData)
{
NSString *newFilePath = [yourDocDirPath stringByAppendingPathComponent:#"New Name here"];
[fileData writeToFile:newFilePath atomically:YES];
}
}
}

Related

Creating a plist if one doesn't exist

I've got a bit of code that imports settings into my app from an email, but it only works if the plist it imports the settings into already exists.
This is the code I'm using currently to import the settings and write to the plist.
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if (url){
NSDictionary *openedDictionary = [NSDictionary dictionaryWithContentsOfURL:url];
// get paths from root direcory
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
// get documents path
NSString *documentsPath = [paths objectAtIndex:0];
// get the path to our Data/plist file
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"Data.plist"];
NSDictionary *originalDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSMutableDictionary *newDictionary = [originalDictionary mutableCopy];
for (NSString *key in openedDictionary) {
if (!newDictionary[key]) {
newDictionary[key] = openedDictionary[key];
}
}
[newDictionary writeToFile:plistPath atomically:YES];
}
NSError *error = nil;
if (![[NSFileManager defaultManager] removeItemAtURL:url error:&error]) {
NSLog(#"error while deleting: %#", [error localizedDescription]);
}
return YES;
}
But what I need to do is create that Data.plist if it's not there, or alternatively rename the plist that's emailed to Data.plist and store it provided there isn't already a Data.plist.
Here is how I would create the property list through code and retrieve data from it as well.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"plist.plist"]; NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat: #"plist.plist"] ];
}
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableDictionary *data;
if ([fileManager fileExistsAtPath: path])
{
data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
}
else
{
// If the file doesn’t exist, create an empty dictionary
data = [[NSMutableDictionary alloc] init];
}
//To insert the data into the plist
int value = 5;
[data setObject:[NSNumber numberWithInt:value] forKey:#"value"];
[data writeToFile: path atomically:YES];
[data release];
// To retrieve the data from the plist
NSMutableDictionary *savedStock = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
int value1;
value1 = [[savedStock objectForKey:#"value"] intValue];
NSLog(#"%i",value1);
[savedStock release];
NSFileManager *defaultManager = [NSFileManager defaultManager];
if ([defaultManager fileExistsAtPath:plistPath])
{
// rename the file
}
else
{
//create empty file
}
this is how you can create empty plist file
NSDictionary *dict = [NSDictionary dictionary];
//you can create file in any path in app sandbox, for example I'm creating in document dir.
NSString *FilePathWithName = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
FilePathWithName = [FilePathWithName stringByAppendingPathComponent:#"name.plist"];
[dict writeToFile:FilePathWithName atomically:YES];
and for renaming what you can do is, you can load the .plist/.property file (that you want to rename) as dictionary and write that Dictionary with new name (write plist as above) and delete the .plist/.property file.
NSFileManager *defaultManager = [NSFileManager defaultManager];
if ([defaultManager fileExistsAtPath:plistPath]) {
//Do stuff with path
}
else {
//Write a plist to the path
}

Deleting in NSDocumentDirectory

I save in NSDocumentDirectory this way:
NSLog(#"%#", [info objectAtIndex:i]);
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask ,YES );
NSString *documentsDir = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"Images%d.png", i]];
ALAssetRepresentation *rep = [[info objectAtIndex: i] defaultRepresentation];
UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage]];
//----resize the images
image = [self imageByScalingAndCroppingForSize:image toSize:CGSizeMake(256,256*image.size.height/image.size.width)];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:YES];
I know how to delete all the images in NSDocumentDirectory.
But I was wondering on how to delete all of the images with the name of oneSlotImages.
Thanks
Try this ,just copy this code,your images with name oneSlotImages,will be removed from DocumentDirectory ,its just simple :
NSArray *directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] error:NULL];
if([directoryContents count] > 0)
{
for (NSString *path in directoryContents)
{
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:path];
NSRange r =[fullPath rangeOfString:#"oneSlotImages"];
if (r.location != NSNotFound || r.length == [#"oneSlotImages" length])
{
[[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];
}
}
}
Have you looked at NSFileManager's methods? Maybe something like this called in a loop for all of your images.
[[NSFileManager defaultManager] removeItemAtPath:imagePath error:NULL];
Use like,
NSArray *dirFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:strDirectoryPath error:nil];
NSArray *zipFiles = [dirFiles filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self CONTAINS[cd] %#", #"oneSlotImages"]];
The array zipFiles contains the names of all the files we filtered. Thus by appending the filenames with complete path of document directory with in a loop, you can make the full filepath of all the filtered files in the array. Then you can use a loop and call the method of NSFileManager object like below
[fileManager removeItemAtPath: strGeneratedFilePath error: &err];
which removes the itm at path from the directory.
By this way you can filter out the filenames contains oneSlotImages. So you can prefer to delete this ones. Hope this helps you.
As this is an old question now and also above answers shows how to delete by image name.What if I want to delete everything from NSDocumentDirectory at one shot, use the below code.
// Path to the Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] > 0)
{
NSError *error = nil;
NSFileManager *fileManager = [NSFileManager defaultManager];
// Print out the path to verify we are in the right place
NSString *directory = [paths objectAtIndex:0];
NSLog(#"Directory: %#", directory);
// For each file in the directory, create full path and delete the file
for (NSString *file in [fileManager contentsOfDirectoryAtPath:directory error:&error])
{
NSString *filePath = [directory stringByAppendingPathComponent:file];
NSLog(#"File : %#", filePath);
BOOL fileDeleted = [fileManager removeItemAtPath:filePath error:&error];
if (fileDeleted != YES || error != nil)
{
// Deal with the error...
}
}
}

iPhone read/write .plist file

I'm making a application where I need to store some information the user have provided. I try to use a .plist file to store the information, I found this:
NSString *filePath = #"/Users/Denis/Documents/Xcode/iPhone/MLBB/data.plist";
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
[plistDict setValue:#"Man" forKey:#"Gender"];
[plistDict writeToFile:filePath atomically: YES];
The problem is that the application will only work as long as I'm testing it in the iPhone simulator. I've tried this Changing Data in a Plist but without luck. I have also read something about that I need to add it to my bundle, but how?
New code:
- (IBAction)segmentControlChanged{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistLocation = [documentsDirectory stringByAppendingPathComponent:#"data.plist"];
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:plistLocation];
if (Gender.selectedSegmentIndex == 0) {
[plistDict setObject:#"Man" forKey:#"Gender"];
[plistDict writeToFile:plistLocation atomically: YES];
}
else
{
[plistDict setObject:#"Women" forKey:#"Gender"];
[plistDict writeToFile:plistLocation atomically: YES];
}
}
I guess you have added your plist file to your resources folder in Xcode (where we place image, if not then you need to place that first). Resources data goes to [NSBundle mainBundle] by default and iOS does not allow us to change data inside bundle. So first you need to copy that file to Documents Directory.
Here is the code for copying file from NSBundle to the Documents directory.
- (NSString *)copyFileToDocumentDirectory:(NSString *)fileName {
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *documentDirPath = [documentsDir
stringByAppendingPathComponent:fileName];
NSArray *file = [fileName componentsSeparatedByString:#"."];
NSString *filePath = [[NSBundle mainBundle]
pathForResource:[file objectAtIndex:0]
ofType:[file lastObject]];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL success = [fileManager fileExistsAtPath:documentDirPath];
if (!success) {
success = [fileManager copyItemAtPath:filePath
toPath:documentDirPath
error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable txt file file with message \
'%#'.", [error localizedDescription]);
}
}
return documentDirPath;
}
Now you can use the returned documentDirPath to access that file and manipulate (Read/Write) over that.
The plist structure is:
<array>
<dict>key-value data</dict>
<dict>key-value data</dict>
</array>
Here is code to write data into plist file:
/* Code to write into file */
- (void)addToMyPlist {
// set file manager object
NSFileManager *manager = [NSFileManager defaultManager];
// check if file exists
NSString *plistPath = [self copyFileToDocumentDirectory:
#"MyPlistFile.plist"];
BOOL isExist = [manager fileExistsAtPath:plistPath];
// BOOL done = NO;
if (!isExist) {
// NSLog(#"MyPlistFile.plist does not exist");
// done = [manager copyItemAtPath:file toPath:fileName error:&error];
}
// NSLog(#"done: %d",done);
// get data from plist file
NSMutableArray * plistArray = [[NSMutableArray alloc]
initWithContentsOfFile:plistPath];
// create dictionary using array data and bookmarkKeysArray keys
NSArray *keysArray = [[NSArray alloc] initWithObjects:#"StudentNo", nil];
NSArray *valuesArray = [[NSArray alloc] initWithObjects:
[NSString stringWithFormat:#"1234"], nil];
NSDictionary plistDict = [[NSDictionary alloc]
initWithObjects:valuesArray
forKeys:keysArray];
[plistArray insertObject:poDict atIndex:0];
// write data to plist file
//BOOL isWritten = [plistArray writeToFile:plistPath atomically:YES];
[plistArray writeToFile:plistPath atomically:YES];
plistArray = nil;
// check for status
// NSLog(#" \n written == %d",isWritten);
}
Are you using that same path on your device? Apps on a device are sandboxed and can only read/write files in their documents directory. Grab that file path like this and append your plist name. This approach will also work on the simulator.
Try this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistLocation = [documentsDirectory stringByAppendingPathComponent:#"myplist.plist"];

how to append tags in xml in iphone?

i am new developer in iphone application. i would like write a content in xml file for that, i have created xml file and write tags with element, attribute and value with some data in that xml as follows.
-(void)writexmlfile:(NSString *)data toFile:(NSString *)fileName NodeName:(NSString *)Node{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// the path to write file
NSString *fileExtension = [NSString stringWithFormat:#"%#%#",fileName,#".xml"];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileExtension];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:appFile];
if(fileExists) {
NSError *error = nil;
NSString *docStr;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// the path to write file
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:appFile];
if(fileExists)
{
NSLog(#"file exist in document");
NSData *myData1 = [NSData dataWithContentsOfFile:appFile];
if (myData1) {
docStr = [[NSString alloc] initWithData:myData1 encoding:NSASCIIStringEncoding];
XMLString = [[NSMutableString alloc]initWithString:docStr];
[self XMLString];
NSLog(#"data%#",XMLString);
}
}
// [XMLString insertString:data atIndex:index];
[XMLString appendFormat:#"<%#>%#</%#> \n",Node,data,Node];
BOOL success = [XMLString writeToFile:appFile atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (!success) {
NSLog(#"Error: %#", [error userInfo]);
}
else {
NSLog(#"File write is successful");
}
}
}
i want add new tag with new elements,new attributes,etc.,if i enter element at the place of tag it is modifying with previous tag .
here how can i append the new tag to previous appended tags
please any body could help me
Thanks in advance
As a suggestion, you can use APXML to create XML documents it is very simple and easy to use. This post can guide you further.

check if plist exist, if not load from here

I am trying to check whether a plist exists in my doc folder: if yes, load it, if not load from resource folder.
- (void)viewWillAppear:(BOOL)animated
{
//to load downloaded file
NSArray *docpaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [docpaths objectAtIndex:0];
NSString *docpath = [documentsDirectory stringByAppendingPathComponent:#"downloadedfile.plist"];
//if document folder got file
if(docpath != nil)
{
NSDictionary *dict = [[NSDictionary alloc]
initWithContentsOfFile:docpath];
self.allNames = dict;
[dict release];
}
//on error it will try to read from disk
else {
NSString *path = [[NSBundle mainBundle] pathForResource:#"resourcefile"
ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc]
initWithContentsOfFile:path];
self.allNames = dict;
[dict release];
}
[table reloadData];
Where did I go wrong? The plist is not loading from resource folder.
I think if you create an instance of NSFileManager you can then use the file exists method
BOOL exists;
NSFileManager *fileManager = [NSFileManager defaultManager];
exists = [fileManager fileExistsAtPath:docPath];
if(exists == NO)
{
// do your thing
}
You need to check wether the file exists in your Documents folder (with NSFileManager or something like this). stringByAppendingPathComponent: doesn’t care wether the path it returns exists or is valid.
I have used a similar approach in one of the applications and it was working fine for me. Where at the launch of the application, I check for the plist file inside the document directory and if it does not exists there, then it is copied from the resource folder.
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString * plistName = #"FlowerList";
NSString * finalPath = [basePath stringByAppendingPathComponent:
[NSString stringWithFormat: #"%#.plist", plistName]];
NSFileManager * fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:finalPath])
{
NSError *error;
NSString * sourcePath = [[NSBundle mainBundle] pathForResource:#"FlowerList" ofType:#"plist"];
[fileManager copyItemAtPath:sourcePath toPath:finalPath error:&error];
}
Here is the Swift version of Chris's Answer:
if (NSFileManager.defaultManager().fileExistsAtPath(path)) {
// ...
}