I have a head scratcher, i have created a UITableView to display recorded data stored in the documents directory which then allows me to select multiple files and send them in an email. This works great, i select the listed files i want to send in my email, click the email button and an email will appear with a list of attached files. The names and extensions are correct.
The problem is, i then send the email and once it is received the attachments have dissapeared and been replaced with txt files with names such as ATT00001.txt, ATT00002.txt and so on.
Can anybody explain to me why this is happening and how it can be fixed? i have listed my code below:
- (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]];
[[tableView indexPathsForSelectedRows] count];
[self updateEmailButtonTitle];
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]];
[self updateEmailButtonTitle];
NSLog(@"deselectedData %@",self.selectedData);
}
}
#pragma mark - Email Selected Data
-(IBAction)emailButton:(id)sender
{
[self showEmail];
}
- (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
NSString *filename = [self.selectedData objectAtIndex:0];
// Read the file using NSData
NSData *fileData = [NSData dataWithContentsOfFile:file];
// Add attachment
[mc addAttachmentData:fileData mimeType:@"text/csv" 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 will be greatly appreciated.
EDIT - here is the finished and working code, thank you to everyone who helped with this:
- (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]];
[[tableView indexPathsForSelectedRows] count];
[self updateEmailButtonTitle];
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]];
[self updateEmailButtonTitle];
NSLog(@"deselectedData %@",self.selectedData);
}
}
-(void)updateEmailButtonTitle
{
NSArray *selectedRows = [self.tableView indexPathsForSelectedRows];
if (selectedRows.count == self.selectedData.count)
{
self.emailButton.enabled = NO;
self.emailButton.title = @"Email";
} else if (selectedRows.count == 0) {
self.emailButton.enabled = YES;
self.emailButton.title = @"Email Selected Data";
}
}
#pragma mark - Email Selected Data
-(IBAction)emailButton:(id)sender
{
[self showEmail];
}
- (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) {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *csvFilePath = [documentsDirectory stringByAppendingPathComponent:file]; // This will check the conents of the string "file" and match it with files located in the documents directory.
NSData *myData = [NSData dataWithContentsOfFile:csvFilePath];
NSLog(@"my nsdata is %@",myData); //check whether your nsdata is nil or not
[mc addAttachmentData:myData
mimeType:@"text/csv"
fileName:file];
}
[self presentViewController:mc animated:YES completion:nil];
}
- (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];
}
This code attached the csv file properly for me:
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *csvFilePath = [documentsDirectory stringByAppendingPathComponent:file]; //This checkes the string "file" for a list of selected files which can then be matched up to the contents of the documents directory.
NSData *myData = [NSData dataWithContentsOfFile:csvFilePath];
NSLog(@"my nsdata is %@",myData); //check whether your nsdata is nil or not
[mc addAttachmentData:myData
mimeType:@"text/csv"
fileName:file];