Adding multiple attachments to email using selection from UITableView - ios

I want to attach csv files created in my app to an email by selecting the files listed in UITableView.
I have all the files listed in my UITableView and am able to attach single selected files to an email without any issue however for the life of me i cannot figure out how to attach multiple files i have selected within the UITableView.
I am storing the selected files in an NSMutableArray called selectedData.
How would i go about doing this? I have been searching for an answer for a while now but have found nothing directly related to what i am trying to do.
here is my code so far:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [filePathsArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *fileList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:nil];
NSPredicate *fltr = [NSPredicate predicateWithFormat:#"self ENDSWITH '.csv'"];
NSArray *csvFiles = [fileList filteredArrayUsingPredicate:fltr];
NSLog(#"Contents of directory: %#", csvFiles);
filePathsArray = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:documentsDirectory error:nil];
cell.textLabel.text = [csvFiles objectAtIndex:indexPath.row];
return cell;
}
# pragma mark - Deleting data from Row.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
{
NSString *fileName = [filePathsArray objectAtIndex:indexPath.row];
NSString *path;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path = [paths objectAtIndex:0];
path = [path stringByAppendingPathComponent:fileName];
NSError *error;
[filePathsArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadData];
if ([[NSFileManager defaultManager]fileExistsAtPath:path]) {
if(![[NSFileManager defaultManager] removeItemAtPath:path error:&error])
{
NSLog(#"Delete file error:%#", error);
}
NSLog(#"Deleting file named: %#", path);
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.selectedData addObject:[filePathsArray objectAtIndex:indexPath.row]];
NSLog(#"selectedData %#",self.selectedData);
}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
[self.selectedData removeObject:[filePathsArray objectAtIndex:indexPath.row]];
NSLog(#"deselectedData %#",self.selectedData);
}
}
#pragma mark - Email Selected Data
-(IBAction)emailButton:(id)sender
{
}
- (void)showEmail:(NSString*)file {
NSString *emailTitle = #"Your Data";
NSString *messageBody = #"Attached is your recorded data.";
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
// Determine the file name and extension
NSArray *filepart = [file componentsSeparatedByString:#"."];
NSString *filename = [filepart objectAtIndex:0];
NSString *extension = [filepart objectAtIndex:1];
// Get the resource path and read the file using NSData
NSString *filePath = [[NSBundle mainBundle] pathForResource:filename ofType:extension];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
// Determine the MIME type
NSString *mimeType;
if ([extension isEqualToString:#"csv"]) {
mimeType = #"text/csv";
}
// Add attachment
[mc addAttachmentData:fileData mimeType:mimeType fileName:filename];
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:NULL];
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[self dismissViewControllerAnimated:YES completion:NULL];
}
Any and all help would be greatly appreciated.

Try something like this.
Assuming all files are of the same mime-type csv.
And assuming that all file names in self.selectedData have a structure like "myfile.csv".
- (void)showEmail {
NSString *emailTitle = #"Your Data";
NSString *messageBody = #"Attached is your recorded data.";
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
for (NSString *file in self.selectedData) {
// Determine the file name and extension
NSArray *filepart = [file componentsSeparatedByString:#"."];
NSString *filename = [filepart objectAtIndex:0];
NSString *extension = [filepart objectAtIndex:1];
// Get the resource path and read the file using NSData
NSString *filePath = [[NSBundle mainBundle] pathForResource:filename ofType:extension];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
// Determine the MIME type
NSString *mimeType;
if ([extension isEqualToString:#"csv"]) {
mimeType = #"text/csv";
}
// Add attachment
[mc addAttachmentData:fileData mimeType:mimeType fileName:filename];
}
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:NULL];
}

Related

UITableView - How to delete file while deleting cell?

I'm trying to delete a csv file while deleting a cell, But I'm getting the next error when I pressed delete:
Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 ..
2]'
* First throw call stack:
Code:
//
/
/ CameraViewController.m
// oFiOSstoryboard
//
// Created by Dorald on 24/05/15.
//
//
#import "CameraViewController.h"
#import "resultsDetailView.h"
#interface CameraViewController ()
#property (strong, nonatomic) IBOutlet UITableView *data;
#property (retain, nonatomic) IBOutlet UILabel *timeStamp;
#property (strong,nonatomic) NSMutableArray *dirList;
#property (nonatomic, assign) NSString *csvRow;
#property (nonatomic, strong) NSMutableArray *dataArray;
- (IBAction)didTapDeleteBtn:(id)sender;
#end
////////////////////////csv readder
NSMutableArray *tableDataArray;
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *manager = [NSFileManager defaultManager];
NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:bundleRoot];
NSString *filename;
NSMutableArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *strPath = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"csv"];
NSString *strFile = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];
NSMutableArray *timeStampb = [[NSMutableArray alloc] init]; ;
NSMutableArray *arrayToDelete = [[NSMutableArray alloc] init]; ;
NSMutableArray *filePathsArray ;
//NSMutableArray *dirList= [[NSMutableArray alloc] init]; ;
NSString *currentcsvfile;
NSString *csvfilenameSave;
#implementation CameraViewController
#synthesize data;
- (void)viewDidLoad {
[super viewDidLoad];
// ////lista de documentos
self.data.scrollEnabled = YES;
self.data.delegate = self;
self.data.dataSource = self;
//filePathsArray =[[NSMutableArray alloc] init]; ;
self.data.allowsMultipleSelectionDuringEditing = YES;
self.dataArray = [[NSMutableArray alloc]init];
NSInteger count = 100;
for (NSInteger i = count; i>=0; i--) {
NSString *title = [NSString stringWithFormat:#"cell %ld",i];
[self.dataArray addObject:title];
}
NSMutableArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSMutableArray* fileList = [manager contentsOfDirectoryAtPath:documentsDirectory error:nil];
//--- Listing file by name sort
NSLog(#"\n File list %#",fileList);
//---- Sorting files by extension
NSMutableArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF EndsWith '.csv'"];
filePathsArray = [filePathsArray filteredArrayUsingPredicate:predicate];
NSLog(#"\n\n Sorted files by extension %#",filePathsArray);
self.dirList = [filePathsArray mutableCopy];
NSString *docPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
if (!strFile) {
NSLog(#"Error reading file.");
}
[timeStampb release];
timeStampb = [[NSMutableArray alloc] initWithArray:[strFile componentsSeparatedByString:#"\,"]];
// this .csv file is seperated with new line character
// if .csv is seperated by comma use "," instesd of "\n"
for(NSString *countryname in timeStampb) {
NSLog(#"%#", timeStampb);
}
}
////////////////////////////////////////////////////////////////Delete csv files
//- (IBAction)delet:(id)sender {
// NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
//
// NSString *filePath = [docPath stringByAppendingPathComponent:#"jorge.csv"];
// NSError *error = nil;
// [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
//}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
# pragma – mark table view DataSource Methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dirList count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier ];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
UIColor* color = [UIColor colorWithRed:(254.0/255.0) green:(251.0/255.0) blue:(248.0/255.0) alpha:1];
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor colorWithRed:(253.0/255.0) green:(0.0/255.0) blue:(237.0/255.0) alpha:1];
[cell setSelectedBackgroundView:bgColorView];
cell.backgroundColor = color;
}
cell.textLabel.text = [timeStampb objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [self.dirList objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor colorWithRed:(0.0/255.0) green:(0.0/255.0) blue:(0.0/255.0) alpha:1];
cell.textLabel.font=[UIFont systemFontOfSize:8.0];
cell.detailTextLabel.font=[UIFont systemFontOfSize:15.0];
cell.detailTextLabel.textColor = [UIColor colorWithRed:(235.0/255.0) green:(120.0/255.0) blue:(33.0/255.0) alpha:1];
return cell;
}
-(UITableViewCell *)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%d", indexPath.row);
currentcsvfile = [self.dirList objectAtIndex:indexPath.row ];;
csvfilenameSave = [NSString stringWithFormat:currentcsvfile];
NSArray *paths3 = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory3 = [paths3 objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/currentcsvnamefile.txt",
documentsDirectory3];
//create content - four lines of text
NSString *content =csvfilenameSave;
//save content to the documents directory
[content writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy error:nil];
[_dirList addObject:_dirList[indexPath.row]];
NSLog(#"\n current csv csvfilenameSave % ",csvfilenameSave);
//[self performSegueWithIdentifier:#"detailsegue" sender:self];
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Update the delete button's title based on how many items are selected.
[_dirList removeObject:_dirList[indexPath.row]];
}
-(UITableViewCellEditingStyle)data:(UITableView *)data editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( editingStyle== UITableViewCellEditingStyleDelete) {
[self.data deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[data setEditing:NO animated:YES];
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *filePath = [docPath stringByAppendingPathComponent:[self.dirList objectAtIndex:indexPath.row ]];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
[_dirList removeObjectAtIndex:indexPath.row];
}
}
#pragma mark - UITableView Delegate Methods
//- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
//{
// return UITableViewCellEditingStyleDelete;
//}
#pragma mark - Delete Button Action
#pragma mark – TableView delegate
- (void)dealloc {
[_timeStamp release];
[self.dirList release];
self.data.delegate = nil;
self.data.dataSource = nil;
[super dealloc];
}
#end
Actually what you are doing you are removing the value from array at the top. You have to remove the value from array at the end of this function. As i have done in below code, please check my answer and use this code and then tell me if you face any issue. I Update my answer Please check it again.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( editingStyle== UITableViewCellEditingStyleDelete) {
currentcsvfile = [self.dirList objectAtIndex:indexPath.row];
csvfilenameSave = [NSString stringWithFormat:currentcsvfile];
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *filePath = [docPath stringByAppendingPathComponent:csvfilenameSave];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
[_dirList removeObjectAtIndex:indexPath.row];
[self.data beginUpdates];
[self.data deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.data endUpdates];
[data setEditing:NO animated:YES];
}
}
Call to method [self.data deleteRowsAtIndexPaths:withRowAnimation:]; sends a message to the table view to adjust its presentation and thus tableview throws an NSInternalInconsistencyException because _dirList count is not equal to tableviews row count.
For details look at this article Inserting and Deleting Rows and Sections
You can handle this by removing the item corresponding to
the row from _dirList array at first and then sending deleteRowsAtIndexPaths:withRowAnimation: to the table view.
Try to replace below lines of code inside - (void)tableView:(UITableView *)tableView commitEditingStyle method:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( editingStyle== UITableViewCellEditingStyleDelete) {
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *filePath = [docPath stringByAppendingPathComponent:[self.dirList objectAtIndex:indexPath.row ]];
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
[_dirList removeObjectAtIndex:indexPath.row];
[self.data deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Hope it will work!

in UITableView first entry and last entry switching record data when loading from server

I am developing an app that will display data from server in a parallax type UITableView, and here is my code. Everything is loading great, but cell data(image, etc) keep switching from one cell to another.
- (void)viewDidLoad
{
[self hasInternet];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self loadData];
self.edgesForExtendedLayout=UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars=NO;
self.automaticallyAdjustsScrollViewInsets=NO;
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated
{
[self scrollViewDidScroll:nil];
[super viewWillAppear:animated];
[self loadData];
self.tableView.dataSource = self;
self.tableView.delegate = self;
}
- (void) loadData{
name = #"name";
email = #"email";
thumbnail = #"thumbnail";
myObject = [[NSMutableArray alloc] init];
NSData *jsonSource = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://URL.php"]];
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonSource options:NSJSONReadingMutableContainers error:nil];
for (NSDictionary *dataDict in jsonObjects) {
NSString *title_data = [dataDict objectForKey:#"fname"];
NSString *title_data2 = [dataDict objectForKey:#"lname"];
NSString *fulname = [NSString stringWithFormat:#"%# %#", title_data, title_data2];
NSString *emAil = [dataDict objectForKey:#"email"];
NSString *thumbnail_data = [dataDict objectForKey:#"img"];
thumbnail_data = [NSString stringWithFormat:#"http://URL/upload/%#",thumbnail_data];
dictionary = [NSDictionary dictionaryWithObjectsAndKeys: fulname, name, emAil, email, thumbnail_data, thumbnail, nil];
[myObject addObject:dictionary];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return myObject.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"parallaxCell";
JBParallaxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell=[[JBParallaxCell alloc]initWithStyle:
UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *tmpDict = [myObject objectAtIndex:indexPath.row];
NSMutableString *text;
text = [NSMutableString stringWithFormat:#"%#",[tmpDict objectForKeyedSubscript:name]];
NSMutableString *mail;
mail = [NSMutableString stringWithFormat:#"%#",[tmpDict objectForKeyedSubscript:email]];
NSMutableString *images;
images = [NSMutableString stringWithFormat:#"%# ",[tmpDict objectForKey:thumbnail]];
NSURL *url = [NSURL URLWithString:[tmpDict objectForKey:thumbnail]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:[tmpDict objectForKey:thumbnail]];
NSData *data = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
cell.parallaxImage.image = [[UIImage alloc]initWithData:data];
});
});
cell.titleLabel.text = [NSString stringWithFormat:#"%#",text];
cell.subtitleLabel.text = [NSString stringWithFormat:#"%#",mail];
return cell;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSArray *visibleCells = [self.tableView visibleCells];
for (JBParallaxCell *cell in visibleCells) {
[cell cellOnTableView:self.tableView didScrollOnView:self.view];
}
}
When I compile it, it shows all my data but then keep switching from one cell to another. Any help will be appreciated. Thanks
Because UITableView reuse the cell so when you scroll down or up the previous cell which is gone from your tableview bound is reuse. but it's image view has an image when it use last time so you have to clear first the imageview.
so put this line
cell.parallaxImage.image = nil;
Before the dispatch queue
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You can use this code it will save the images in document directry and then show it.
please change the variable name.
NSString *imageURL = [[matcheListArr objectAtIndex:indexPath.row] valueForKey:#"thumbnail_image"];
NSURL *url = [NSURL URLWithString:imageURL];
NSArray *seperate = [[[matcheListArr objectAtIndex:indexPath.row] valueForKey:#"thumbnail_image"] componentsSeparatedByString:#"/"];
NSString *fileName = [NSString stringWithFormat:#"%#.png",[seperate objectAtIndex:seperate.count-1]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/MyFolder"];
NSError *error;
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
NSString *getImagePath = [dataPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",fileName]];
UIImage *img = [UIImage imageWithContentsOfFile:getImagePath];
if ([img isKindOfClass:[UIImage class]]) {
//Set Downloaded Image
[cell.matchUserImageView setImage:img];
}
else {
if ([[ValidationString sharedManager] isNullString:[[matcheListArr objectAtIndex:indexPath.row] valueForKey:#"thumbnail_image"]] == YES) {
//Set Default Image
[cell.matchUserImageView setImage:[UIImage imageNamed:#"photo_icon.png"]];
}
else{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:url];
NSArray *seperate = [[[matcheListArr objectAtIndex:indexPath.row] valueForKey:#"thumbnail_image"] componentsSeparatedByString:#"/"];
NSString *fileName = [NSString stringWithFormat:#"%#.png",[seperate objectAtIndex:seperate.count-1]];
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
[cell.matchUserImageView setImage:[UIImage imageWithData:imageData]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/MyFolder"];
NSString *savedImagePath = [dataPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",fileName]];
[imageData writeToFile:savedImagePath atomically:NO];
});
});
}
}

Replaceing a string on a plist

I am making some confing settings using a tableView using a plist File to fill the data I am working around this code about 2 weeks and this appears to work.
This is my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if ([[[week objectAtIndex:indexPath.row] objectForKey:#"checkmark"] isEqual:#"0"]) {
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
[[week objectAtIndex:indexPath.row] setObject:#"1" forKey:#"checkmark"];
}
else {
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
[[week objectAtIndex:indexPath.row] setObject:#"0" forKey:#"checkmark"];
}
[[week objectAtIndex:indexPath.row] writeToFile:#"week.plist" atomically:YES];
NSLog(#"%#, %#", selectedCell.textLabel.text,[[week objectAtIndex:indexPath.row] objectForKey:#"checkmark"]);
NSLog(#"Array de week seleccionando %#", week);
}
Everything seems to work fine on the debbug area (that's why I use the nslogs), and my problem is That can't save the changes on the plist file, it seem it saving in some kind of cache or something like that.
Update
I've also tried with this code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *plistPath = [rootPath stringByAppendingPathComponent:#"week.plist"];
NSDictionary *plistDict = [NSDictionary dictionaryWithObjects:week forKeys:week];
NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict
format:NSPropertyListXMLFormat_v1_0
errorDescription:nil];
if ([[[week objectAtIndex:indexPath.row] objectForKey:#"checkmark"] isEqual:#"0"]) {
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
NSString *uno = #"1";
[[week objectAtIndex:indexPath.row] setObject:uno forKey:#"checkmark"];
}
else if ([[[week objectAtIndex:indexPath.row] objectForKey:#"checkmark"] isEqual:#"1"]) {
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
NSString *cero = #"0";
[plistData writeToFile:plistPath atomically:YES];
}
[[week objectAtIndex:indexPath.row] setObject:cero forKey:#"checkmarck"];
NSLog(#"%#, %#", selectedCell.textLabel.text,[[week objectAtIndex:indexPath.row] objectForKey:#"checkmark"]);
NSLog(#"Array de checkmarks %#", week);
}
And I have had the same result on the Debug Area:
2014-07-07 22:11:21.384 experiment table view[2264:60b] Thursday, 0
2014-07-07 22:11:21.385 experiment table view[2264:60b] Array de week seleccionando (
{
Name = Sunday;
checkmarck = 0;
},
{
Name = Monday;
checkmarck = 1;
},
{
Name = Tuesday;
checkmarck = 0;
},
{
Name = Wednesday;
checkmarck = 0;
},
{
Name = Thursday;
checkmarck = 0;
},
{
Name = Friday;
checkmarck = 1;
},
{
Name = Saturday;
checkmarck = 0;
}
)
Which is the same result that I get
If the Plist is in the bundle, you cannot write into it. 'In the bundle' means that you create the Plist by adding a new file in XCODE manually.
You can only write into a Plist that you create programmatically. Such a Plist is not in the bundle, but in your app's document directory. The path of the Plist is
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = #"week.plist";
NSString *path = [NSString stringWithFormat:#"%#/%#", documentsDirectory, fileName];
Thanks to Sen I resolve this, his answer lead me to correct my code.
First I had to programmatically make the pList:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"week.plist"];
NSMutableArray *week = [[NSMutableArray alloc]init];
//Here I add all the objects inside the Mutable Array
[week writeToFile:path atomically:YES];
Then to write on the Plist by selecting it on the picker:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"week.plist"];
NSMutableArray *array = [[NSMutableArray alloc]initWithContentsOfFile:path];
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if ([[[array objectAtIndex:indexPath.row] objectForKey:#"checkmark"] isEqual:#"0"]) {
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
[[array objectAtIndex:indexPath.row] setObject:#"1" forKey:#"checkmark"];
} else {
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
[[array objectAtIndex:indexPath.row] setObject:#"0" forKey:#"checkmark"];
}
[array writeToFile:path atomically:YES];
[tableView reloadData];
[self.navigationController pushViewController:self animated:YES];
}
Thanks, and I hope this code help someone.

Cannot delete picture

I am saving my pictures into the collection view but I cannot delete the picture that I have took. I am using tap delete in the collection view. This is my code for that.However after I tap and delete the picture it looks like the picture is not deleted, and cannot find where is wrong, I am suspecting that it has something to do with the array but I am not sure.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
allImagesArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *locations = [[NSArray alloc]initWithObjects:#"Bottoms", #"Dress", #"Coats", #"Others", #"hats", #"Tops",nil ];
NSString *fPath = documentsDirectory;
NSMutableArray *trashCan = [NSMutableArray array];
NSArray *directoryContent;
for(NSString *component in locations){
NSString *TrashBin = [fPath stringByAppendingPathComponent:component];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: TrashBin];
collectionTrash.delegate =self;
collectionTrash.dataSource=self;
for(NSString *str in directoryContent){
NSLog(#"str:%#", str);
NSString *finalFilePath = [TrashBin stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
[trashCan addObject:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
NSLog(#"array:%#",[allImagesArray description]);
}}}
Trash = trashCan;
for(NSString *folder in locations) {
for(NSString *file in directoryContent) {
// load the image
}
}}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
NSLog(#"j");
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [allImagesArray count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseID = #"ReuseID";
TrashCell *mycell = (TrashCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseID forIndexPath:indexPath];
UIImageView *imageInCell = (UIImageView*)[mycell viewWithTag:1];
imageInCell.image = [allImagesArray objectAtIndex:indexPath.row];
NSLog(#"a");
return mycell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"s:%d", [Trash count]);
NSString *trashBin = [Trash objectAtIndex:indexPath.row];
NSLog(#"k%#l",trashBin);
[allImagesArray removeObjectAtIndex:indexPath.row];
[self.collectionTrash reloadData];
[self deleteMyFiles:trashBin];
}
NSString *myFileName;
-(void) deleteMyFiles:(NSString*)filePath {
NSError *error;
if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:&error];
}
}
Be sure you delete the image in local memory also. When you delete image from collectionView not delete. Then stop the app and run it again see the deleted image is removed or not?. I think this is your problem. Then store all the image in single array and store it in plist. When you remove any image replace the array after removing the image in the array.
Use
[collectionView reloadData]
after calling deleteMyFiles.

Deleting files from local app Documents folder

So far I have managed to delete rows from my table view but it won't update in the given Documents folder. How would I achieve this? Below is the code I'm using.
I tried to implement the code from here How to delete files from a folder which is placed in documents folder.
My goal is to have the ability to delete any file, not just a desired file.
Thanks in advance.
#import "Documents.h"
#interface DocumentsViewController ()
#end
#implementation DocumentsViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
NSString *temp = [[NSBundle mainBundle] resourcePath];
self.directoryPath = [temp stringByAppendingPathComponent:#"Documents"];
[self.tableView setEditing:NO animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [directoryContents count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.text = [directoryContents objectAtIndex:indexPath.row];
return cell;
}
-(NSString*)directoryPath{
return directoryPath;
}
-(void)setDirectoryPath:(NSString*)a{
[a retain];
[directoryPath release];
directoryPath = a;
[self loadDirectoryContents];
[table reloadData];
}
-(void)loadDirectoryContents{
[directoryContents release];
directoryContents = [[NSFileManager defaultManager] directoryContentsAtPath: directoryPath];
[directoryContents retain];
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { //implement the delegate method
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Update data source array here, something like [array removeObjectAtIndex:indexPath.row];
[directoryContents removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadData];
NSString *extension = #"png";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *contents = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:NULL];
NSEnumerator *e = [contents objectEnumerator];
NSString *filename;
while ((filename = [e nextObject])) {
if ([[filename pathExtension] isEqualToString:extension]) {
[fileManager removeItemAtPath:[documentsDirectory stringByAppendingPathComponent:filename] error:NULL];
}
}
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
-(void)dealloc{
[super dealloc];
[directoryContents release];
directoryContents = nil;
self.directoryPath = nil;
[table release];
table = nil;
}
#end
WORKING CODE FOR ME:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete){
NSString *fileName = [directoryContents objectAtIndex:indexPath.row];
NSString *path;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"downloads"];
path = [path stringByAppendingPathComponent:fileName];
NSError *error;
//Remove cell
[directoryContents removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[tableView reloadData];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) //Does file exist?
{
if (![[NSFileManager defaultManager] removeItemAtPath:path error:&error]) //Delete it
{
NSLog(#"Delete file error: %#", error);
}
}
}
}
NSFileManager is very useful in removing files:
[[NSFileManager defaultManager] removeItemAtPath: pathToFile error: &error];
Also take a look at this article it has some useful codes. Although a bit old but the codes works just fine.
http://iphonedevsdk.com/forum/iphone-sdk-development/3576-how-do-i-delete-a-file-in-my-documents-directory.html
Here is some more code example
// Get the Documents directory path
NSString *temPath = [NSString stringWithFormat:#"%#%d",#"Documents/Media_", Key_mediaID];
//This temPath look line ../../../Documents/Media_1
NSString *documentsDirectoryPath = [NSHomeDirectory() stringByAppendingPathComponent:temPath];
// Delete the file using NSFileManager
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:[documentsDirectoryPath stringByAppendingPathComponent:Your File Name] error:nil];
Here is another link with some more helpful code
http://ios.biomsoft.com/2012/01/17/delete-all-files-in-documents-directory/
Hope this helps you out.
Edit:
To remove a files with specific extension say for example jpg you can try the following
NSString *extension = #"jpg";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *contents = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:NULL];
NSEnumerator *e = [contents objectEnumerator];
NSString *filename;
while ((filename = [e nextObject])) {
if ([[filename pathExtension] isEqualToString:extension]) {
[fileManager removeItemAtPath:[documentsDirectory stringByAppendingPathComponent:filename] error:NULL];
}
}
In addition to the above if you know the path to the file you want to delete the following is a useful code:
// Get the Documents directory path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
// Delete the file using NSFileManager
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:[documentsDirectoryPath stringByAppendingPathComponent:yourFile.txt] error:nil];
Edit 2:
To delete the document in a specific folder:
NSError *error;
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documents= [documentsDirectory stringByAppendingPathComponent:#"YourFolder"];
NSString *filePath = [documents stringByAppendingPathComponent:#"file2.txt"];
[fileMgr removeItemAtPath:filePath error:&error]

Resources