I'm looking for an easy to use CSV parser for Objective-C to use on the iPhone. Where can I find one?
I'm also looking for other parsers such as JSON, so maybe there is a conversion library somewhere.
I'm looking for an easy to use CSV parser for Objective-C to use on the iPhone. Where can I find one?
I'm also looking for other parsers such as JSON, so maybe there is a conversion library somewhere.
I finally got around to cleaning up a parser I've had in my code folder and posted it on Github: http://github.com/davedelong/CHCSVParser
It's quite thorough. It handles all sorts of escaping schemes, newlines in fields, comments, etc. It also uses intelligent file loading, which means you can safely parse huge files in constrained memory conditions.
Here's a simple category on NSString to parse a CSV string that has commas embedded inside quote blocks.
#import "NSString+CSV.h"
@implementation NSString (CSV)
- (NSArray *)componentsSeparatedByComma
{
BOOL insideQuote = NO;
NSMutableArray *results = [[NSMutableArray alloc] init];
NSMutableArray *tmp = [[NSMutableArray alloc] init];
for (NSString *s in [self componentsSeparatedByString:@","]) {
if ([s rangeOfString:@"\""].location == NSNotFound) {
if (insideQuote) {
[tmp addObject:s];
} else {
[results addObject:s];
}
} else {
if (insideQuote) {
insideQuote = NO;
[tmp addObject:s];
[results addObject:[tmp componentsJoinedByString:@","]];
tmp = nil;
tmp = [[NSMutableArray alloc] init];
} else {
insideQuote = YES;
[tmp addObject:s];
}
}
}
return results;
}
@end
This assumes you've read your CSV file into an array already:
myArray = [myData componentsSeparatedByString:@"\n"];
The code doesn't account for escaped quotes, but it could easily be extended to.
Quick way to do this:
NSString *dataStr = [NSString stringWithContentsOfFile:@"example.csv" encoding:NSUTF8StringEncoding error:nil];
NSArray *array = [dataStr componentsSeparatedByString: @","];
Well, above simple solutions doesn't take into account multiple records. Use the following code reading a default excel CSV using ASCI 13 as line end marker:
NSString *content = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:nil];
NSArray *contentArray = [content componentsSeparatedByString:@"\r"]; // CSV ends with ACSI 13 CR (if stored on a Mac Excel 2008)
for (NSString *item in contentArray) {
NSArray *itemArray = [item componentsSeparatedByString:@";"];
// log first item
NSLog(@"%@",[itemArray objectAtIndex:0]);
}
I wrote a dead-simple (although not fully-featured) CSV parser for a project I was working on: CSVFile.h
and CSVFile.m
. Feel free to grab it -- the code is available under the GPLv3 (unfortunately, it was a requirement for the project I was working on) but I'd be happy to license it to you under an MIT license or another license.
This seems to be the most comprehensive that I've found so far.
http://www.macresearch.org/cocoa-scientists-part-xxvi-parsing-csv-data
As a side note, you'd think most major languages (Delphi, C#, Objective-c, php etc) would have a library available with a full implementation of this basic data interchange format.
I know json is cool and XML is reliable but neither are available as a save option from most applications saving table data. CSV still is.
As xmr said above: It's possible in Objective C to convert an NSString csv into 'components separated by string' array.
NSArray* items;
items=[bufferString componentsSeparatedByString:@","];
In case you are interested in csv export having arrived at this thread - as I did - here is an extract of how I exported a csv file.
NSString* fileName = @"Level";
fileName = [fileName stringByAppendingString:levelNumberBeingEdited];
fileName = [fileName stringByAppendingString:@".txt"];
NSString* bufferString=@"";
Buffer String is populated by looping through each data item (not shown) and inserting a comma between each. Finally it's exported.
NSString* homeDir = NSHomeDirectory();
NSString* fullPath = [homeDir stringByAppendingPathComponent:fileName];
NSError* error = nil;
[bufferString writeToFile:fullPath atomically:NO encoding:NSASCIIStringEncoding error:&error];