38

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.

8 Answers 8

51

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I have checked the Github Link that you have given as such it looks fine but when I tried testing it in iPhone simulator then it does not seem to work. Simulator does not open. Also the base SDK has been set to Mac OS X 10.5. So will this not work for iPhone? What should be done? Thanks. :)
@PARTH there's a list of files in the general use section of the readme. Copy those into your project and #import "CHCSV.h"
Thanks Dave for answering my silly question :) Also then I suppose we have to just use arrayWithContentsofCSVFile: method. right?
@PARTH that's definitely one of the easiest ways to do it! You can also go the whole parser-with-a-delegate route if you want.
19

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.

Comments

8

Quick way to do this:

NSString *dataStr = [NSString stringWithContentsOfFile:@"example.csv" encoding:NSUTF8StringEncoding error:nil];
NSArray *array = [dataStr componentsSeparatedByString: @","];

2 Comments

This wont handle blocks containing ,'s though which is why you often need a fully fledged library :)
not what I need today, but good to know about that method/message(?)
5

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]);
}

1 Comment

you have to consider that while this might work for simple files, it will not work in many scenarios. There are cases where you can escape the commas, or when you put a value inside quotations. componentsSeparatedByString will not catch any of these. There are also scenarios when a cell value can contain a new-line, so in these scenarios, your content array wouldn't be accurate either. This is why other people are recommending using libraries, such as CHCSV Parser. These are built to handle all these scenarios.
3

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.

Comments

1

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.

Comments

0

I've found ParseKit few weeks ago But IMHO for most cases -[NSString componentsSeparatedByString:] method and NSScanner are more than enough and quite easy to use.

1 Comment

thanks, looks a bit complex for what I'm looking for though.
-2

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];

2 Comments

-1 whatever this is, it's not an answer on how to parse CSV files. Flagged.
I have edited my answer. I was led to this thread and xmr solved my issue. I thought it would be useful to show how the actual csv text file fits into his solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.