Saturday 22 October 2011

Commercial cogs start turning

Taken a slight break from the game prototyping to look at a commercial opportunity that has thrown up a few challenges. These include attachments to email that aren't just images as well as a CSV file generation.

To start with the attachment piece of emails is pretty easy. First add whatever file you want into your resource folder of you iphone/ipod/ipad app within Xcode. Then to reference the file just use the following code but making sure you have the correct mime type.

if ([MFMailComposeViewController canSendMail]) {
        
        MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
        mailViewController.mailComposeDelegate = self;
        NSArray *toRecipients = [NSArray arrayWithObject:@"anemailaddress@domain.com"];
        [mailViewController setToRecipients:toRecipients];
        [mailViewController setSubject:@"Test Attachment"];
        [mailViewController setMessageBody:@"This is a test message." isHTML:NO];
        
   
        NSString *filePath = [[NSBundle mainBundle] pathForResource: @"MyPDF" ofType: @"pdf"];
        NSData *pdfData = [NSData dataWithContentsOfFile: filePath];
        [mailViewController addAttachmentData: pdfData mimeType:@"application/pdf" fileName:@"MyPDF.pdf"];
      
        [self presentModalViewController:mailViewController animated:YES];
        [mailViewController release];
        
    }

Good job done.

I then looked to extend this further by being able to take inherent data within the device and then output this into the email.

Not wanting to make work for myself I looked around the internet for a decent CSV parser and everyone pointed me to the CHCSVParser by Dave Delong. This proved to be reasonably self explanatory and was able to export an NSArray and attach to an email with the following example:

NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                                                             NSUserDomainMask, YES); 
        NSString* documentsDirectory = [paths objectAtIndex:0];     
        NSString* leafname = [@"Sample" stringByAppendingFormat: @".csv" ]; 
        NSString* filenameStr = [documentsDirectory
                                 stringByAppendingPathComponent:leafname];

        CHCSVWriter *csvWriter = [[CHCSVWriter alloc] initWithCSVFile:filenameStr atomic:NO];
        
        NSArray * expectedFields = [self expectedFields];
        
        NSUInteger expectedCount = [expectedFields count];
        
        for (int i = 0; i < expectedCount; ++i) {
            NSArray * currentLine = [expectedFields objectAtIndex:i];
            NSUInteger fieldCount = [currentLine count];
            
            NSString * value;
            for (int x = 0; x < fieldCount; ++x) {
                value = [currentLine objectAtIndex:x];
                [csvWriter writeField:value];
            }
            [csvWriter writeLine];
        }
        
        [csvWriter closeFile];
        [csvWriter release];

        
        NSFileManager *man = [[NSFileManager alloc] init];
        NSDictionary *attrs = [man attributesOfItemAtPath: filenameStr error: NULL];
        int result = [attrs fileSize];
        NSLog(@"File size: %i", result);        
        
        NSData * csvData = [NSData dataWithContentsOfFile: filenameStr];
        [mailViewController addAttachmentData: csvData mimeType:@"text/csv" fileName:@"Sample.csv"];
This works really well for me and will be looking to extend after I have completed the excellent Core Data tutorials over at Ray Wenderlich site. Really worth checking out for iPhone tutorials. The big gotcha that took me ages to figure out was the first four lines of code:
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                                                             NSUserDomainMask, YES); 
        NSString* documentsDirectory = [paths objectAtIndex:0];     
        NSString* leafname = [@"Sample" stringByAppendingFormat: @".csv" ]; 
        NSString* filenameStr = [documentsDirectory
                                 stringByAppendingPathComponent:leafname];
I was previously trying to create a file via NSBundle and gave me misleading errors where the file would appear on the email composition but would not turn up in the inbox. It now works.

Hope this is useful to somebody

0 comments:

Post a Comment

 
;