How to Parse data from CSV File & populate UITableview in Objective-C?

792 Views Asked by At

I Have a CSV File that contain 6000 rows.

I would like to Populate those 6000 rows in a TableView Then Use a SearchBar to fetch a single row

I used CSVParser but it needs 10 minutes to load the UITableview:

-(void)ViewDidLoad{

CSVParser *parser = [CSVParser sharedInstance];
    NSDictionary *dictionary = [parser parseCSVFile: @"ports"];
    NSArray* rows = [dictionary allKeys];


}

Then to Populate the tableview:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return 25;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{


    PortListCell *cell = (PortListCell *)[tableView dequeueReusableCellWithIdentifier:@"Cell"];



    cell.Codeport.text = [[rows objectAtIndex:indexPath.row]valueForKey:@"ident"];
    cell.Nameport.text = [[rows objectAtIndex:indexPath.row]valueForKey:@"name"];

    NSString*CodeCountry = [[[rows objectAtIndex:indexPath.row]valueForKey:@"iso_country"]lowercaseString];

    cell.ImageCountry.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png",CodeCountry]];



    return cell;
}

What is the best way to populate a UITableView with these rows ?

2

There are 2 best solutions below

0
On

Loading large amounts of data into table views, which will never show the whole amount of data anyway, is commonly done asynchronously, with periodic updates. If you can get into the CSV parser, perhaps it could add rows to the array and call tableview reloadData every 10 rows or something. That way your slow parsing and tableview update would happen in the background, as the table view was already appearing active to the user.

0
On

You can use SQLite to import all the data into DB, and use it for more efficiency. I am showing you using FMDB.

The way you are parsing your data, using CSVParser you read the CSV, and insert into DB dynamically.

You can create your insert sql query dynamically using the function below

-(NSDictionary *)createInsertSQLWithValue:(NSDictionary *)value forTable:(NSString *)tableName{

    NSString *cols=@"";
    NSMutableArray *vals=[[NSMutableArray alloc] init];
    NSString *placeHolders=@"";

    NSArray *keys=[value allKeys];

    for(NSString *key in keys){
         [vals addObject:[value objectForKey:key]];

         placeHolders=[placeHolders stringByAppendingFormat:@"?,"];

    }

    //Remove extra ","
    if(cols.length>0){
        cols=[cols substringToIndex:cols.length-1];
        placeHolders=[placeHolders substringToIndex:placeHolders.length-1];
    }

    NSString *sql=[NSString stringWithFormat:@"insert into %@ (%@) values (%@)",tableName,cols,placeHolders];

    return @{@"sql":sql,@"args":vals};
}  

You just need to do

-(void)populateData{
   CSVParser *parser = [CSVParser sharedInstance];
   NSArray *ports = [parser parseCSVFile: @"ports"];

   for(NSDictionary *value in ports){
       [self addPort:value];
   }

}

-(void)addPort:(NSDictionary*)value{
   //say you created a table ports
    NSDictionary *sql=[self createInsertSQLWithValue:value forTable:@"ports"];

    BOOL inserted=[self.db executeUpdate:[sql objectForKey:@"sql"] withArgumentsInArray:[sql objectForKey:@"args"]];
    if(inserted){
        NSLog(@"Port Inserted");
    }
}

Note: Make sure you do this when you need to populate the data, if required once, do it once. And too you need to create table with the exact column name as keys in the dictionary too.

Cheers.