How to write array data into excel file (CSV) in objective c - ios

I am trying to write the array data into excel (actually it is a CSV, but it is opened in excel). I used the following code to do that:
NSMutableArray *list;
list = [[NSMutableArray alloc] init];
NSString *string = [list componentsJoinedByString:#","];
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"yourFileName.csv"];
[data writeToFile:appFile atomically:YES];
It works fine, but the problem is I have 20 objects in my 'list' array and all those 20 objects are written in side by side cells. What I want is to write the first 4 objects in one line and then move to the new line and again write the next 4 objects in that line till all the objects in the list array are completed.
Can anyone help me with this issue?

NSMutableArray *list = ...
NSMutableString *buffer = [NSMutableString string];
for (NSUInteger i = 0; i < list.count; i++) {
NSString *value = list[i];
if (i > 0) {
if (i % 4 == 0) { //after every 4th value
buffer.append("\n"); //end line
}
else {
buffer.append(",");
}
}
buffer.append(value);
//if your values contain spaces, you should add quotes around values...
//buffer.appendFormat(#"\"%#\"", value);
}
NSData *data = [buffer dataUsingEncoding:NSUTF8StringEncoding];
...

To break lines in CSV just input a \r\n in the "end of the line". Be caerfull because in the mac you only need \r or \n (not really sure right now)

Related

View Image array from web folder in iOS

I want to be able to view images from a web folder inside my iPhone app. I know how to view the images with a specific url (i.e. www.mywebsite.com/image.jpg). That's easy. I just don't know how to asynchronously load an array. Basically I need to view images with a specific sequence (i.e. mywebsite.com/image_001.jpg, image_002.jpg, image_003.jpg, etc). There may be 10 or 100 images in a folder with that sequence. How do I let my app load images with a sequence?
Following code will sort images of this file format "imageName_number.jpg"
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *webDir=[documentsDirectory stringByAppendingPathComponent:#"WebFolder"];
NSFileManager *filemgr;
NSMutableArray *fileNum;
fileNum=[[NSMutableArray alloc]init];
filemgr = [NSFileManager defaultManager];
//This will give all files of your web directory you can uncomment to get dynamically
//NSArray *filelist = [filemgr contentsOfDirectoryAtPath: webDir error: nil];
// this is just example shows how unsorted will be used to sort image no you can comment this line
NSArray *filelist=[[NSArray alloc]initWithObjects:#"abc_001.jpg",#"def_005.jpg",#"abc_002.jpg",#"abc_0103.jpg",#"abc_0010.jpg",#"abc_008.jpg", nil];
int count = (int)[filelist count];
NSMutableDictionary *dictFileNumWithPath=[[NSMutableDictionary alloc]init];
NSString *imageSeprator=#"_";
for (int i = 0; i < count; i++){
NSString *imageName=[filelist objectAtIndex: i];
if (!([imageName rangeOfString:imageSeprator].location == NSNotFound)) {
NSRange startRange = [imageName rangeOfString:imageSeprator];
NSRange endRange = [imageName rangeOfString:#".jpg"];
NSRange searchRange = NSMakeRange( startRange.location+1, endRange.location-endRange.length);
NSString *strNum= [imageName substringWithRange:searchRange];
NSString *webPath=[webDir stringByAppendingPathComponent:imageName];
[dictFileNumWithPath setObject:[NSNumber numberWithInt:[strNum intValue]] forKey:webPath];
}
}
NSArray *sortedKeysFilePathArray =
[dictFileNumWithPath keysSortedByValueUsingSelector:#selector(compare:)];
NSLog(#"%#", sortedKeysFilePathArray);

Working with NSArray built with a file

I need help with indexes and bounds.
I have an NSArray which contains a parsed file separated by « ; ».
So basically :
- (NSArray *) getArrayFromFile{
NSArray *fileArray;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:#"%#/list.txt", documentsDirectory];
NSString *writedStr = [[NSString alloc]initWithContentsOfFile:fileName encoding:NSUTF8StringEncoding error:nil];
fileArray = [writedStr componentsSeparatedByString:#";"];
return fileArray;
}
I want to work with this array.
NSArray* myArray = [self getArrayFromFile];
for(k = 0; j < [myArray count]; k++){
NSLog(#"%#",[myArray objectAtIndex:k]);
}
But when I run trough the returned NSArray, I always have a "terminating with uncaught exception of type NSException"
Here is the full error : http://pastebin.com/qApXU2s0 when the NSArray contains #"Hello",#"World",#"Array Content", and the original file "Hello;World;Array Content;"
Can someone help me with this ..?
Thank you!
If we take a look at your for loop:
for(k = 0; j < [myArray count]; k++){
You can see that you're using a variable k in the first and third parts of the for statement, and a j in the middle part. So whatever j is, it's value is outside the bounds of your array. You'll want to change that j to a k. You could also change your for loop to do fast iteration, in which case you eliminate the k variable and you don't have the possibility of confusion like this.
What #Gavin said was 100% correct.. but a little tip for the future..
for (NSString *stringInArray in myArray)
{
NSLog(#"%#", stringInArray);
}
The above code snippet is a little nicer to work with.
Or, if you are feeling really brave, checkout enumerateObjectsUsingBlock:

How to write a String in different lines to a .txt file on iOS

I am trying to write a string to a t.t file in the documents folder of my app. I can write the string to it, but when I write another string to the file it overwrites the other string, is it possible to write more strings to a text files, with a blank line between strings, many in this formate
String
String
Strine
…
I am using this code to write the string to an text file, it works for one string, but not for multible strings.
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/Barcodedata.txt",
documentsDirectory];
//create content - four lines of text
NSString *content = [NSString stringWithFormat:#"%#",sym.data];
//save content to the documents directory
[content writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy
error:nil];
There's a few ways to do this, depending on how you implemented your code.
One way would be to load up the original .txt file into a NSMutableString object and then append that new line to the end of the string and re-write out the file (this isn't super efficient, especially as you start appending after 1000 strings, 100 strings, 50 strings, etc.)
Or you could use the low level C function "fwrite" with the append bit set.
Edited:
Since you want to see code, here's how to do it with my first suggestion:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/Barcodedata.txt", documentsDirectory];
//create content - four lines of text
NSError * error = NULL;
NSStringEncoding encoding;
NSMutableString * content = [[NSMutableString alloc] initWithContentsOfFile: fileName usedEncoding: &encoding error: &error];
if(content == NULL)
{
// if the file doesn't exist yet, we create a mutable string
content = [[NSMutableString alloc] init];
}
if(content)
{
[content appendFormat: #"%#", sym.data];
//save content to the documents directory
BOOL success = [content writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy
error:&error];
if(success == NO)
{
NSLog( #"couldn't write out file to %#, error is %#", fileName, [error localizedDescription]);
}
}

Load data from plist to tableview [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to populate UITableView with plist
I save data to plist like this:
- (IBAction)save:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:#"data.plist"];
NSMutableArray *data = [NSMutableArray arrayWithContentsOfFile:plistPath];
if (nil == data) {
data = [[NSMutableArray alloc] initWithCapacity:0];
}
else {
[data retain];
}
NSMutableDictionary *array = [[NSMutableDictionary alloc]init];
[array setObject:label1.text forKey:#"Test1"];
[array setObject:label2.text forKey:#"Test2"];
[array setObject:label3.text forKey:#"Test3"];
[array setObject:label4.text forKey:#"Test4"];
NSLog(#"%#", array);
[data addObject:array];
[array release];
[data writeToFile:plistPath atomically: TRUE];
[data release];
}
NSLog:
2012-07-01 18:52:19.566 testapp[22651:707] {
Test1 = 40;
Test2 = 102;
Test3 = 153;
Test4 = 255;
}
How can I load saved data to uitableview?
To read it, do this:
NSMutableDictionary* plistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
You should then be able to read the values for all the keys like this:
NSString *myValue = [plistDict objectForKey:#"someKey"];
edit:
After rereading your code it seems like you might be doing something you don't want to do. Your current plist structure is a top level array that adds a dictionary to itself every time you invoke "save". Is this what you're trying to do? If so, what represents a cell in your table, an index in the array?
If so, then you want to do
// top level array
NSMutableDictionary* plistArray = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
// individual dictionary at one array index (such as indexPath.row in cellForRowAtIndexPath)
NSMutableDictionary *dictionary = [plistArray objectAtIndex:yourIndex];
In any case, the object you have named "array" is actually a dictionary so you should rename it (or change it to be an array if that's what you want).

IOS: problem to synchronize nsarray with string

I have a NSArray in this way
myArray[0] = [string1, string2, string3, string4, mySecondArray, string5]; (at 0 position)
I write this array inside a txt file in this way
NSString *outputString = #"";
for (int i = 0; i< myArray.count; i++){
outputString = [outputString stringByAppendingString:[[[myArray objectAtIndex:i ] componentsJoinedByString:#"#"] stringByAppendingString:#";"]];
}
NSLog(#"string to write = %#", outputString);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Text.txt"];
NSError *error;
[outputString writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
then the result of NSLog is = (position 0 of myArray) (mySecond array is empty)
one#two#three#four#(
)#five;
I want to know:
Why the array wrap?
When I'll go to read this string how can I know that it's mySecondArray?
When you message componentsJoinedByString: on an NSArray object, it calls description on each of its objects and concatenates them in order. For NSString objects, they are the strings themselves. The array wraps because of the way the description method has been implemented.
As for identifying the array while you are reading the string back, I don't think it is possible. You should consider writing the array to the file rather i.e.
[[myArray objectAtIndex:0] writeToFile:filePath atomically:YES];
or
[myArray writeToFile:filePath atomically:YES];
depending on the requirement. This way you will be able to read the elements back properly.

Resources