0

I have a picture slideshow app which allows the user to rate 3 images. The ratings get stored in a NSMutableArray called rated like this:

    2014-01-06 07:10:23.040 SlideShowSurvey[50425:70b] (
    1, <-- Rating for Picture 1
    2, <-- Rating for Picture 2
    3  <-- Rating for Picture 3
)

This is then saved to a .csv file using the following code:

-(void)saveRatings
{
    NSString *picRatings = [NSString stringWithFormat:@"%@, \n",self.rated];
    // Find documents directory
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *survey = [docPath stringByAppendingPathComponent:@"pictureRatings.csv"];
    // Create new file if none exists
    if (![[NSFileManager defaultManager] fileExistsAtPath:survey])
    {
        [[NSFileManager defaultManager] createFileAtPath:survey contents:nil attributes:nil];
    }
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:survey];
    [fileHandle seekToEndOfFile];
    [fileHandle writeData:[picRatings dataUsingEncoding:NSUTF8StringEncoding]];
    [fileHandle closeFile];
}

I can then display the results of the .csv file to a UITextView, though it displays it exactly how the array is structured. For example, multiple results display as:

(
    1,
    2,
    3 
),
(
    1,
    2,
    3 
),
(
    1,
    2,
    3 
)

Is there a way I am able to format the array so that it is saved as 1,2,3? And would I be able to add a column header like Picture 1, Picture 2, Picture 3? For example, I would like to display results on the UITextView something like:

Picture 1, Picture 2, Picture 3
1,2,3
1,2,3
1,2,3

I've tried searching but can't seem to find this answer. Any help is appreciated! Thanks.

Edit: I have solved this thanks to jrturton's solution, using the following code:

        // Set column titles for .csv
    NSArray *columnTitleArray = @[@"Picture 1", @"Picture 2", @"Picture 3"];

    NSString *columnTitle = [columnTitleArray componentsJoinedByString:@","];
    NSString *columnTitleToWrite = [columnTitle stringByAppendingString:@"\n"];

    // Separate ratings into cells
    NSString *picRatings = [rated componentsJoinedByString:@","];
    NSString *picRatingsToWrite = [picRatings stringByAppendingString:@"\n"];

    // Find documents directory
..

Then adding this to the method to make sure column headers are only set when a new file is created:

    // Create new file if none exists
    if (![[NSFileManager defaultManager] fileExistsAtPath:survey])
    {
        [[NSFileManager defaultManager] createFileAtPath:survey contents:nil attributes:nil];

        // Set title for new file
        NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:survey];
        [fileHandle writeData:[columnTitleToWrite dataUsingEncoding:NSUTF8StringEncoding]];
    }
..
2
  • why dont you use custom UITableCellView for display Commented Jan 6, 2014 at 7:48
  • I tried to do that but I only know how to load results from the NSMutableArray itself, not from the .csv file. I'm quite new to Objective-C. Do you know of any code examples showing how to load a .csv into a UITableView? Commented Jan 6, 2014 at 7:53

3 Answers 3

1

Here is a much easier way:

NSMutableString *csv = [NSMutableString string];

NSString *label = ...;

[csv appendFormat:@"%@,\n", label];

NSNumber *keyNum = ...;

[csv appendFormat:@"%d,%d\n", [keyNum intValue], [countNum intValue]];

NSString *filename = @"counts.csv";

NSError *error; 

[csv writeToFile:filename atomically:YES encoding:NSUTF8StringEncoding error:&error];
Sign up to request clarification or add additional context in comments.

1 Comment

Please see my updated post, I edited with an attempted solution using some of your code but I can't get it to work. I am unsure what other parts of your code are such as *keyNum and countNum. Can you help me?
0
NSMutableString *csv = [NSMutableString string];

NSString *label = @"\n";

[csv appendFormat:@",", label];

NSString *picRatings = [rated componentsJoinedByString:csv];

I'm not sure what you expect appendFormat to be doing in the above code, this will probably be raising a warning since label is not used. You don't need a mutable string in this case either.

To get the contents of an array separated by commas, do this:

NSString *picRatings = [rated componentsJoinedByString:@","];

You also need to add a new line to the end of this string, so you'd want:

NSString *picRatingsToWrite = [picRatings stringByAppendingString:@"\n"];

Write this string to your file and you should be fine.

3 Comments

Perfect! Your solution is exactly what I need, thanks! The very last thing I'd like is to have column headers, like Picture 1, Picture 2, Picture 3 (as shown in my original post). Do you know how I could achieve this? Thanks a lot for your help.
To do that, just write that string to the file (with a trailing \n) if there isn't anything in there already, or add it to the start of your first-ever rating string.
Brilliant, I was able to set column headers when creating the file, I have updated my post to show this. Thanks for all your help!
0

use this parser and get the data into array and look how you can use data into UITabelViewCell https://github.com/davedelong/CHCSVParser

1 Comment

I've thought about a CSV parser but this app is very simple and stores only a small amount of data in the .csv file, so I decided against trying to implement a parser. Thanks for the reply though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.