Hi guys I am new to Objective C. I want to make an app where it can read a csv file locally and display the data in a specific column in the tableview.
1)Read csv locally
2)Display csv data (let's say fifth column "ItemName") in the tableview
Thanks for any advice.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *strPath = [[NSBundle mainBundle] pathForResource:#"issues" ofType:#"csv"];
NSString *strFile = [NSString stringWithContentsOfFile:strPath encoding:NSUTF8StringEncoding error:nil];
if (!strFile) {
NSLog(#"Error reading file.");
}
issues = [[NSArray alloc] init];
issues = [strFile componentsSeparatedByString:#","];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return[issues count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [issues objectAtIndex:indexPath.row];
return cell;
}
The way you do the parsing is only making columns of the whole file. First you need to separate by line-breaks (probably '\n'), then you can separate each line by ',' and each time take the 5th element and add it to an NSMutableArray (issues).
[strFile componentsSeparatedByString:#","] is not really CSV-parsing, there are more complex libraries available for that on cocoapods. If you need error-handling, etc. you better go with a library.
Related
Hi I am trying to display two dimensional array like in this image but not work my code please help me and my json respone is in image which i want to display in UITableView
-(void)getCategories
{
Service *srv=[[Service alloc]init];
NSString *str=#"http://streamtvbox.com/site/api/matrix/";//?country_code=91&phone=9173140993&fingerprint=2222222222";
NSString *method=#"channels";
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
[srv postToURL:str withMethod:method andParams:dict completion:^(BOOL success, NSDictionary *responseObj)
{
NSLog(#"%#",responseObj);
arrayCategories = [responseObj valueForKey:#"categories"];
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrayCategories.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ChannelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [[arrayCategories objectAtIndex:indexPath.row]valueForKey:#"categories"];
return cell;
}
Hope it will help you,
You are doing some minor mistake, do something as below,
arrayCategories = [responseObj valueForKey:#"categories"]; //Which is already there in your code....
And while fetching value in your textLabel, write as below
cell.textLabel.text = [[[arrayCategories objectAtIndex:indexPath.row] componentsSeparatedByString:#"="] objectAtIndex:1];
Do not write here valueForKey "categories".
Let me know if you still face any issue.
I got it the issue is in your response.In categories key you are not getting array , you are getting object.Paste exact log NSLog(#"%#",responseObj); that you get in your success block so that i can help you to sort it out.
i have viewcontroller .h .m and .xib that contain registration form to insert update and delete.
and i have other xib that contain uitableview that show the sqlite data .how can i display ???
i write the code but its gives the error on array of viewcontroller page and other control that are used in viewcontroller.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [data count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[data objectAtIndex:indexPath.row] valueForKey:#"name"];
cell.detailTextLabel.text = [[data objectAtIndex:indexPath.row] valueForKey:#"salary"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
name.text = [[data objectAtIndex:indexPath.row] valueForKey:#"name"];
salary.text = [[data objectAtIndex:indexPath.row] valueForKey:#"salary"];
}
here data is NSArray in viewcontroller.h file gives error here
and also in didSelectRowAtIndexPath method name.text and salary.text gives error because it is the textfield of viewcontroller.
how can i solved it ?????
You have to make sure the data array should be available in otherViewController. For that create a array property in .h file of OtherViewController and while loading this view controller, assign the data array to this property.
Well as you are using SQlite database, you can fetch the data from the database(you'll need to add additional code) in OtherViewController and display it the tableView there.
Also you can't access the private variables of a view controller inside a different view controller. You will have to create properties for them or create public methods.
do it like this.. First create temporary dictionary and than fetch the data from that..
NSDictionary * tmpDictn = [data objectAtIndex:indexPath.row];
cell.textLabel.text = [tmpDictn valueForKey:#"name"];
cell.detailTextLabel.text = [tmpDictn valueForKey:#"salary"];
And same here..
NSDictionary * tmpDictn = [data objectAtIndex:indexPath.row];
name.text = [tmpDictn valueForKey:#"name"];
salary.text = [tmpDictn valueForKey:#"salary"];
I'm trying to insert data into the rows I've created, I will get all info in my Log but it only shows the last info in all of my rows. Could anyone suggest a way to avoid this error?
Please offer me some advice thanks!
You are never re-populating the cells, actually. You are creating the initial visible cells, and just reusing them with the same content.. please look below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
static NSString *CellIdentifier = #"TestCell";
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// HERE YOU ONLY WANT TO INSTANTIATE THE CELL
NSArray *topObjects = [[NSBundle mainBundle] loadNibNamed:#"TestCell" owner:nil options:nil];
for (id currentObject in topObjects)
{
if([currentObject isKindOfClass:[TestCell class]])
{
cell = (TestCell *) currentObject;
break;
}
}
}
// HERE YOU WOULD ACTUALLY POPULATE THE CELL WITH DATA
NSArray *array = [server get_texts:10 offset:0 sort_by:0 search_for:#""];
NSMutableString *s = [[NSMutableString alloc] init];
for (testMetaData *m in array){
[s appendFormat:#"%# %# \n", m.title,m.note];
cell.title.text = m.title;
NSLog(#" title %# ", m.title);
}
return cell;
}
Some info about UITableView:
So, a properly setup tableView only allocates and uses a limited number of UITableViewCells. After allocating, say 5 cells (this number is determined by "How many cells can you see at any given time?"), it will take an already created cell that has been scrolled out of the visible area, and gives it back to you in that method you are using, so you can re-populate it. So, cell variable will not be nil at that time, and your server code never gets called.
I think it has to do with your for loop.
NSMutableString *s = [[NSMutableString alloc] init];
for (testMetaData *m in array){
[s appendFormat:#"%# %# \n", m.title,m.note];
cell.title.text = m.title;
NSLog(#" title %# ", m.title);
}
Your cell.title.text = m.titlewill get the last m.title info at the end of the for loop.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
//Load Cell for reuse
static NSString *CellIdentifier = #"TestCell";
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell =[ [[NSBundle mainBundle] loadNibNamed:#"TestCell" owner:nil options:nil] lastObject];
}
//appending text and config cell
NSArray *array = [server get_texts:10 offset:0 sort_by:0 search_for:#""];
NSString *t = [array objectAtIndex:indexPath.row];
//Config cell - Not sure what you want. Maybe 10 different rows
cell.title.text = t;
return cell;
}
okay, here's what I've been scratching my head over for the last few days. I have created a custom cell for my table view. I have created a separate class (customCell.h) for this cell and linked them together in Xcode.
The custom cell has four UIlabels which I have declared in the .h file of the custom cell and linked to the custom cell via storyboard.
I have imported the customCell.h header file into the .h file of my table view controller
I am trying to do a search on twitter, and then populate the table view and custom cell with the details of the various tweets. The issue is I don't know how to link the results of the tweet to the 4 UIlabel outlets in my custom cell.
When I am declaring some of the outlets of the custom cell in my table view implementation file (even though I've imported the .h file of the custom cell) xcode is saying that it does not recognise the name
I've copied the coding below detailing as far as I can get. Any help would be much appreciated. Thanks in advance
- (void)fetchTweets
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: #"THIS IS WHERE MY TWITTER SEARCH STRING WILL GO.json"]];
NSError* error;
tweets = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return tweets.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TweetCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
NSString *text = [tweet objectForKey:#"text"];
NSString *name = [[tweet objectForKey:#"user"] objectForKey:#"name"];
NSArray *arrayForCustomcell = [tweet componentsSeparatedByString:#":"];
cell.textLabel.text = text;
cell.detailTextLabel.text = [NSString stringWithFormat:#"by %#", name];
return cell;
}
You are creating an instance of the UITableViewCell, which is the default class for tableview cells. In your case, you have to create an instance of your customCell class (which extends the UITableViewCell class). You have to do this in you cellForRowAtIndexPath method:
static NSString *CellIdentifier = #"TweetCell";
customCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if ( cell == nil )
{
cell = [[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Get the tweet
NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
I hope this helped you out!
Steffen.
I'd like to create a simple reference app that lists a group of people, their job title, and their portrait. What I have so far is the list of people and their job title. It works alright, but I think I should have done it differently.
From reading other posts, I suppose I should be using dictionaries. This is how my PList currently looks:
And this is how the important bits of my code look:
#implementation RootViewController
#synthesize staffArray, subtitleArray;
- (void)viewDidLoad
{
[super viewDidLoad];
NSString* path = [[NSBundle mainBundle] pathForResource:#"StaffData" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSMutableArray *tmpNameArray = [dict objectForKey:#"Root"];
self.staffArray = [[NSMutableArray alloc] initWithArray:tmpNameArray copyItems:YES];
NSMutableArray* tmpSubtitleArray = [dict objectForKey:#"Subs"];
self.subtitleArray = [[NSMutableArray alloc] initWithArray:tmpSubtitleArray copyItems:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [staffArray count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
cell.textLabel.text = [staffArray objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [subtitleArray objectAtIndex:indexPath.row];
return cell;
}
Using two arrays kind of defeats the purpose of OOP, I think, because in this case the people aren't connected to their job titles; they just happen to be in the same order. I'd like to create for example:
Array called Jonas, first value = job title, second value = pathToImage.png.
Another array called Andreas, etc etc etc.
What do I do?
I think that as a start, your design lacks an "Employee" object, that has data members like "Name", "JobTitle", etc... After you have this set up, just create an array of people and take whatever you need from there, by index.