davedelong/CHCSVParser

Reading Same File Twice

Closed this issue · 3 comments

Hi,

I'm using the CSV as a lookup table for about 10,000 rows of data. I map at most, two columns to a dictionary, using the first column as a key and then another arbitrary column as the value. Since I have multiple columns, it would be most useful to run the parsing more than once. However, I can't seem to get the second run to work. It never sends any delegate methods for lines/records. I believe this is because the NSInputStream is at the end of the stream. So, I make sure I have no strong pointers to the CHCSVParser object (so it deallocates in ARC), and then create a new CHCSVParser using the same file path. To my surprise, this still doesn't work. Any thoughts on parsing the same file multiple times?

Thanks!

Caylan

Here's the code I'm using in my delegate.

- (void)parser:(CHCSVParser *)parser didReadField:(NSString *)field atIndex:(NSInteger)fieldIndex
{
    // SKIP: Undefined keyCol and valueCol (both are likely 0)
    if(self.keyCol == self.valueCol)
        return;

    // Set the key in temporary keyObject
    if(fieldIndex == self.keyCol)
    {
        self.keyObject = field;
    }

    // Set the key --> value pair
    if(fieldIndex == self.valueCol && self.keyObject && field)
    {
        [self.mapDict setObject:field forKey:self.keyObject];

        // Reset key (value is temporary)
        self.keyObject = nil;
    }
}

And...

-(NSDictionary*)dictionaryWithKeysColumn:(NSInteger)keyColumn valueColumn:(NSInteger)valueColumn
{
    self.mapDict = [[NSMutableDictionary alloc] init];
    self.keyCol = keyColumn;
    self.valueCol = valueColumn;
    [self parse];

    self.keyCol = 0;
    self.valueCol = 0;

    return self.mapDict;
}

-(void)parse
{
    self.csvParser = nil;
    [self.csvParser parse];
}

-(CHCSVParser*)csvParser
{
    if(!_csvPathForResource)
    {
        NSLog(@"%s - error, missing csvPathForResource", __PRETTY_FUNCTION__);
        return nil;
    }

    if(!_csvParser)
    {
        NSString *csvFilePath = [[NSBundle mainBundle] pathForResource:self.csvPathForResource
                                                                ofType:@"csv"
                                                           inDirectory:self.csvDirForResource];

        if(csvFilePath)
            _csvParser = [[CHCSVParser alloc] initWithContentsOfCSVFile:csvFilePath];

        NSLog(@"%s - created _csvParser:%@", __PRETTY_FUNCTION__, _csvParser);
    }

    return _csvParser;
}

DOH. I was on the right track... Deallocating works. However, my code above didn't set the delegate back to self. I added one more line to the lazy loading -csvParser method.

-(CHCSVParser*)csvParser
{
    if(!_csvPathForResource)
    {
        NSLog(@"%s - error, missing csvPathForResource", __PRETTY_FUNCTION__);
        return nil;
    }

    if(!_csvParser)
    {
        NSString *csvFilePath = [[NSBundle mainBundle] pathForResource:self.csvPathForResource
                                                                ofType:@"csv"
                                                           inDirectory:self.csvDirForResource];

        if(csvFilePath)
        {
            _csvParser = [[CHCSVParser alloc] initWithContentsOfCSVFile:csvFilePath];
            _csvParser.delegate = self;
        }           

        NSLog(@"%s - created _csvParser:%@", __PRETTY_FUNCTION__, _csvParser);
    }

    return _csvParser;
}