Search code examples
iosemailcsvmfmailcomposeviewcontroller

Email attachment has no content


I'm trying to email a CSV copy of the user data in my app and I've tried a couple of different methods. It shows up in the mailer view controller as "Backup.csv" but when I email it there is no content when I receive the email. What could be causing this?

-(void)backupDatabase {
    NSString *CSVstring = [NSString string];
    for (SELVendor *vendor in [[SELVendorStore store] allVendors]) {
        [CSVstring stringByAppendingString:[NSString stringWithFormat:@"\"vendor\",\"%@\",\"%@\",\"%@\",\"%@\",%i\n",vendor.name, vendor.phone, vendor.email, vendor.vendorID, vendor.placeOrderByEmail]];
    }

    // Create CSV file
    NSArray *directory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *filePath = [directory[0] stringByAppendingPathComponent:@"databaseBackup"];
    NSError *error;
    [CSVstring writeToFile:filePath atomically:false encoding:NSStringEncodingConversionAllowLossy error:&error];
//    [[NSFileManager defaultManager]createFileAtPath:filePath contents:nil attributes:nil];
//    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
//    [fileHandle seekToEndOfFile];
//    [fileHandle writeData:[CSVstring dataUsingEncoding:NSUTF8StringEncoding]];

    // Setup email and attach CSV file
    MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
    mailer.mailComposeDelegate = self;
    [mailer setSubject:@"Inventory App CSV Backup"];
    [mailer addAttachmentData:[NSData dataWithContentsOfFile:filePath] mimeType:@"text/csv"  fileName:@"Backup.csv"];
    [self presentViewController:mailer animated:true completion:nil];
}

Solution

  • NSStringEncodingConversionAllowLossy is not a valid string encoding.
    You are basically using NSASCIIStringEncoding because you use the wrong enum. So if your string is not strict ASCII it can't be converted to NSData, and won't be written to disk.

    Start by checking if the file could be written to disk. i.e.

    if (![CSVstring writeToFile:filePath atomically:false encoding:NSUTF8StringEncoding error:&error]) {
        NSLog(@"Could not write file %@", error);
    } 
    else {
        MFMailComposeViewController ...
    }
    

    Edit: And you don't add the CSV lines to your string. So you will create an empty string.

    [CSVstring stringByAppendingString:...]; creates a new string. But you don't assign that string to anything.

    So change that part to:

    NSString *CSVstring = [NSString string];
    for (SELVendor *vendor in [[SELVendorStore store] allVendors]) {
        CSVstring = [CSVstring stringByAppendingString:[NSString stringWithFormat:@"\"vendor\",\"%@\",\"%@\",\"%@\",\"%@\",%i\n",vendor.name, vendor.phone, vendor.email, vendor.vendorID, vendor.placeOrderByEmail]];
    }
    

    or to

    NSMutableString *CSVstring = [NSMutableString string];
    for (SELVendor *vendor in [[SELVendorStore store] allVendors]) {
        [CSVstring appendString:[NSString stringWithFormat:@"\"vendor\",\"%@\",\"%@\",\"%@\",\"%@\",%i\n",vendor.name, vendor.phone, vendor.email, vendor.vendorID, vendor.placeOrderByEmail]];
    }