Save NSArray variable as CSV file with objective-C - objective-c

Please may i know how to save a NSArray variable as CSV file using objective-C and Xcode.
I want to save it in: \tmp file
NSArray *TArray;
NSMutableArray *Xdata;
NSMutableArray *Ydata;
for(int i = 1; i < 10; i++)
{
[Xdata addObject:[NSNumber numberWithFloat:(i/3.14)]];
[Ydata addObject:[NSNumber numberWithFloat:(i*3.14)]];
}
TArray = [[NSArray alloc] initWithObjects:Xdata, Ydata, nil];
So how can i save "TArray" as CSV file ?
Thanks :)

I think storing CSV file in NSArray does not mean anything... as CSV file will contain strings only. You can store CSV file in NSString.
Please go through my answer in the previous post for storing csvString in NSString.
EDIT:
I forgot to link my question, but please go through this link, which will give you example...
Generate CSV sample iphone app/code

Related

Reading 'CSV' file - Cannot read csv file contains loong string

I am using following method to read .csv file. It is working fine for csv files which contains normal strings, numbers ect.
But it fails to read csv files contains long strings (eg: description of 5,6 lines).
Is there is such technical difficulty? Your help is highly appreciated.
-(void)readTitleFromCSV:(NSString*)path AtColumn:(int)column
{
//arrBreeds = [[NSMutableArray alloc]init];
NSMutableArray *arrTemp = [[NSMutableArray alloc]init];
NSString *fileDataString=[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSArray *linesArray=[fileDataString componentsSeparatedByString:#"\n"];
// preparing array with questions and answers
for(int i=0; i<[linesArray count];i++){
[arrTemp addObject:[[linesArray objectAtIndex:i] componentsSeparatedByString:#","] ];
}
NSLog(#"ArrBreeds %#", arrTemp);
}
You are first separating the text from your CSV file based on line break and then separating the components. This happens something like this:
absd,sgsgs
dfdf,dfghj
Here you should get 3 objects after parsing , but with your code you will get 4.
You could just go on with this:
NSArray *linesArray=[fileDataString componentsSeparatedByString:#","];

How can I handle this in cocoa? Retrieve an entry from a plist file?

I have this small excel file given by a brazilian government authority, it contains records for each city in Brazil, a ZIP Code range for each city and its "city code" .
I need to retrieve for a given city its "city code".
I imagine the best way would be to parse a given zip code for the city and return its "city code", based on the first two columns that display the zip code range.
I am confident that using AppleScript I can compile a plist file for the given Excel file. But can someone point me for a few lines of objectiveC code to retrieve the given entry from a plist file once I parse the ZIP code?
Please see excel file at http://www.idanfe.com/dl/codes.xls.zip
Thanks.
I have uploaded a sample plist file to http://www.idanfe.com/dl/cityCodes.plist
Further explanation:
I will parse a ZIP CODE value like: 01123010 which is in the range of 01001000 and 05895490, so my routines should return me City Code = 3550308 and City Name = São Paulo.
I have no idea how to achieve this, I might have built the sample plist wrong.
I am confident I can build a plist file using AppleScript, reading from the Excel sheet.
But retrieving the City code for a given ZIP CODE range is a puzzle.
+++ EDIT: +++
I think I have solved it, but it looks kind of clumsy, as almost everything I write.
This AppleScript reads the Excel sheet and writes the plist file : http://www.idanfe.com/dl/creating.scpt.zip
Here you find the 1 MB plist file: http://www.idanfe.com/dl/cityCodes.plist.zip
This is the code I wrote to get the City Code I need:
NSString *zipCodeString;
zipCodeString = #"99990000";
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"cityCodes" ofType:#"plist"];
NSDictionary *cityCodes_dictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSArray *allKeys = [cityCodes_dictionary allKeys];
int i = 0;
for (i = 0 ; i <= [allKeys count]; i++) {
NSString *someKey = [allKeys objectAtIndex:i];
NSRange range08 = NSMakeRange (0, 8);
NSRange range88 = NSMakeRange (8, 8);
NSString *startZipCode = [someKey substringWithRange:range08];
NSString *finalZipCode = [someKey substringWithRange:range88];
int startZipCodeInt = [startZipCode intValue];
int finalZipCodeInt = [finalZipCode intValue];
if(startZipCodeInt <= [zipCodeString intValue] && finalZipCodeInt >= [zipCodeString intValue]){
NSLog(#"we found a winner");
NSString *cityCode = [NSString stringWithFormat: #"%#",[[cityCodes_dictionary objectForKey:someKey]objectForKey:#"City Code"]];
[cityCodeIBGEField setStringValue:cityCode];
NSLog(#"cityCode = %#",cityCode);
break;
} else {
// NSLog(#"no winners");
}
}
Basically I append the start zipCode and finalZip Code into one string of 16 digits, so I create one single record in the plist file.
Then when searching for the City Code I break the long key (2 zip codes) in 2 (back to normal zipCode) and search to see which record fits the given zipCode I need a cityCode for.
Some how it doesn't look the best for me, but for my own surprise the code is very fast, although in a loop.
I would appreciate comments...
Thanks,
I would use indexOfObjectPassingTest: to do this kind of search. Something like this:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSString* plistPath = [[NSBundle mainBundle] pathForResource:#"cityCodes" ofType:#"plist"];
self.cityCodes_dictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
[self findCityWithZip:#"01123010"];
}
-(void)findCityWithZip:(NSString *) searchZip {
NSUInteger indx = [self.cityCodes_dictionary.allKeys indexOfObjectPassingTest:^BOOL(NSString *zip, NSUInteger idx, BOOL *stop) {
NSString *startZipCode = [zip substringWithRange:NSMakeRange(0, 8)];
NSString *finalZipCode = [zip substringWithRange:NSMakeRange(8, 8)];
return (searchZip.integerValue < finalZipCode.integerValue && searchZip.integerValue > startZipCode.integerValue);
}];
NSLog(#"%#",[self.cityCodes_dictionary valueForKey:[self.cityCodes_dictionary.allKeys objectAtIndex:indx]]);
}
Reading the plist shouldn't be a problem at all if it is structured as a dictionary:
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile: #"cities.plist"];
//NSString *zipStr = [dict valueForKey: #"CityNme"]; //this was an example
That's the easy part. The harder part is parsing and structuring the plist file from an xls file.
Or did I misunderstand your question?
PS: to get a quick look at the dictionary's plist structure, create a mock dictionary and NSLog it's description to see how it's supposed to be (or writeToFile to see the file contents or of course refer to the docs)
edit
You load the supplied plist file in a dictionary using the above code. Then you retrieve another dictionary from within it using
NSDictionary *city = [dict valueForKey : #"yourZipCodeHere"];
From that dictionary you get the cityCode like this
NSString *cityCode = [city valueOrKey: #"City Code"];
As for your range problem, I'm not sure I understand it completely. But you can get an array of all the zip codes using
NSArray *zipArray = [dict allKeys];
And then you can simply iterate over that to get the correct zip code.
PS: I don't know much apple script and would be interested in how you converted the xls to plist using it.

Not showing smily ( Emoji ) in in UITextView in iOS?

I have stored all uni-codes(emoji characters) in plist supported by iphone. When i write directly as
- (IBAction)sendButtonSelected:(id)sender {
NSMutableArray *emoticonsArray = [[NSMutableArray alloc]initWithObjects:#"\ue415",nil];
NSString *imageNameToPass = [NSString stringWithFormat:#"%#",[emoticonsArray objectAtIndex:0]];
NSLog(#"imageNameToPass1...%#",imageNameToPass);
messageTextView.text =imageNameToPass;
}
it show emoji in textview but as soon as i fetch from plist
NSString *plistPath1 = [[NSBundle mainBundle] pathForResource:#"unicodes" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath1];
activeArray= [dictionary objectForKey:categoryString];
NSLog(#"activeArray...%#",activeArray);
emoticonsArrayForHomeEmoji = [[NSMutableArray alloc]initWithCapacity:[activeArray count]];
for(int i=0; i<[activeArray count]; i++)
{
id objects = (id)[activeArray objectAtIndex:i];
[emoticonsArrayForHomeEmoji insertObject:objects atIndex:i];
}
NSString *imageNameToPass = [NSString stringWithFormat:#"%#",[emoticonsArrayForHomeEmoji
objectAtIndex:0]];
NSLog(#"imageNameToPass1...%#",imageNameToPass);
messageTextView.text =imageNameToPass;
then it shows unicode as text \ue415 in text view instead of emoji.
What i am doing wrong?. Please help me out!
Wel said by #AliSoftware, the Plist data will be read as-it is, so you can add the emojis to your plist by following this steps:
1) Go to your top bar, and click on Edit.
2) Now select Special Characters
3) Now drag and drop emoji to plist.
For more details I am adding snap shots. take a look at it.
The \uxxxx notation is only interpreted by the compiler (as the source code is usually in ASCII or MacRoman or whatever but not often UTF8)
Plist files uses the characters directly, and are encoded in UTF8.
So you should insert the emoji character itself into the plist directly, instead of using the \uxxxx notation, as the Plist data will be read as-is.
Lion and Mountain Lion Keyboard palettes contains emoji characters directly, so that should not be difficult to insert the characters when editing the PLIST anyway.

How to properly create an array of arrays by reading in data from a file

So far I have:
//read in data from CSV file and separate it into 'row' strings:
// where dataString is simply a CSV file with lines of CSV data
// 31 lines with 9 integers in each line
NSArray *containerArray = [dataString componentsSeparatedByString:#"\n"];
NSArray *rowTemp; //local variable just for my sake
NSMutableArray *tableArray;//mutable array to hold the row arrays
//For each index of containerArray:
//take the string object (string of CSV data) and then,
//create an array of strings to be added into the final tableArray
for (int i = 0; i < [containerArray count]; i++) {
rowTemp = [[containerArray objectAtIndex:i] componentsSeparatedByString:#","];
[tableArray addObject:rowTemp];
}
Then when I try the following, it returns: (null)
NSLog(#"Row 6, cell 1 is %#", [[tableArray objectAtIndex:5] objectAtIndex:0]);
Any ideas? is there a better way?
FYI this data is static and very unlikely to change. Any way to create and populate a static array rather than using a mutable array, would be much appreciated.
Thanks in advance.
I just got the answer! with some help from iPhoneSDK forums, and what I failed to do was actually create the tableArray. What I did in the code above was merely create the variable. NSMutableArray *tableArray; and did not actually create the mutable array I wanted. Instead what I should have done was: NSMutableArray *tableArray = [NSMutableArray arrayWithCapacity: [containerArray count]]; Which worked like a charm.

getting NSArray length/count - Objective C

Well I've looked at similar problems over the site but haven't reached a solution thus far so I must be doing something wrong.
Essentially, I am importing a text file, then splitting each line into an element of an array. Since the text file will be updated etc.. I won't every know the exact amount of lines in the file and therefore how many elements in the array. I know in Java you can do .length() etc.. and supposedly in Objective C you can use 'count' but i'm having no luck returning the length of my array... suggestions?
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"allshows"
ofType:#"txt"];
NSString *fileString = [NSString stringWithContentsOfFile:filePath];
NSArray *lines = [fileString componentsSeparatedByString:#"\n"];
NSUInteger *elements = [lines count];
NSLog(#"Number of Shows : ", elements);
and what is being output is NOTHING. as in "Number of Shows : " - blank, like it didn't even count at all.
Thank you for any help!
You're missing the format string placeholder. It should be:
NSLog(#"Number of shows: %lu", elements);
You need to use a format specifier to print an integer (%d):
NSLog(#"Number of Shows : %d", elements);
Looking at your other post, it seems like you are a Java developer. In Java's System.out, you just append the variables. In Objective-C, I suggest you look at "print format specifiers". Objective-C uses the same format.