How do I parse a csv file? - ios

I'm trying to implement a label that shows me the current location's weather data as the following:
NSString *request = [NSString stringWithFormat:#"http://api.worldweatheronline.com/free/v1/weather.ashx?q=%#&format=csv&num_of_days=0&show_comments=no&key=myKeyThatIRemovedForThisQuestion",city];
NSURL *URL = [NSURL URLWithString:request];
NSError *error;
NSString *csv = [NSString stringWithContentsOfURL:URL encoding:NSASCIIStringEncoding error:&error];
NSArray *items = [csv componentsSeparatedByString:#","];
NSLog(csv);
NSLog([items firstObject]);
NSLog([items objectAtIndex:1]);
The logging line for the csv works.
The logging line for the first object in the array works.
But the objectatindex line throws an unexpected error:
libc++abi.dylib: terminating with uncaught exception of type
NSException
A sample of csv on console:
2014-02-27 21:27:43.626 Clock[1470:70b] 08:28 PM,17,116,http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png,Partly Cloudy ,9,15,100,E,0.2,59,16,1012,75
2014-02-27,18,64,8,46,13,22,169,SSE,263,http://cdn.worldweatheronline.net/images/wsymbols01_png_64/wsymbol_0009_light_rain_showers.png,Patchy light drizzle,3.8
How can I make this thing work so I can get my data from the array?

I've used Dave Delong's CSV parser a few times without issue. This can be found here: https://github.com/davedelong/CHCSVParser
It is also available via CocoaPods as CHCSVParser. This library has a test suite - and works fairly efficiently.

Related

Searching data from txt file in iOS

I have a .txt file in which some data is present, when I stored it in an array I got 50000 words. I want to search the data from text file according to user input and show it on UITableview cell, how is it possible ?
Can any body help me?
Here is my code to read data from .txt file in viewDidLoad:
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"myList" ofType:#"txt"];
NSError *error;
NSString *fileContents = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:&error];
if (error)
NSLog(#"Error reading file: %#", error.localizedDescription);
// maybe for debugging...
NSLog(#"contents: %#", fileContents);
NSArray *listArray = [fileContents componentsSeparatedByString:#"\n"];
NSLog(#"items = %d", [listArray count]);
You should use fast enumeration using block. Those are fastest of all for loop iteration. But changing the value in that array at time of enumeration could cause a crash.
Here is a link of how to use block enumeration
Here is a link of how it performance wise.
Hope this helps you!!

NSJSONSerialization in my function returns an error

I have a function that looks like this:
-(void)writeArrayOnFile {
NSArray* converterArray = [[NSArray alloc] initWithArray:[self swContainer]];
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:#"saved.json"];
NSError *e = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:converterArray options:0 error:&e];
if (jsonData) {
[jsonData writeToFile:url.path atomically:YES];
}
NSLog(#"%#", jsonData);
}
On breakpoint, the converterArray comes in with correct objects:
[0] Movie * 0x8d5e100 0x08d5e100
NSObject NSObject
_swBtnValue BOOL YES
_thSmallLink UIImage * 0x8fdcd80 0x08fdcd80
_thLargeLink __NSCFString * #"http://content9.flixster.com/movie/11/17/45/11174563_ori.jpg" 0x08fb9530
_mvName __NSCFString * #"Delivery Man" 0x08fc48e0
_dvdReleaseDate __NSCFString * #"2014-03-25" 0x08fb49a0
_mvRating __NSCFString * #"PG-13" 0x08fc4920
_mvSyn __NSCFString * #"From DreamWorks Pictures comes "Delivery Man", the story of affable underachiever David Wozniak, whose mundane life is turned upside down when he finds out that he fathered 533 children through sperm donations he made twenty years earlier. In debt to the mob, rejected by his pregnant girlfriend, things couldn't look worse for David when he is hit with a lawsuit from 142 of the 533 twenty-somethings who want to know the identity of the donor. As David struggles to decide whether or not he should reveal his true identity, he embarks on a journey that leads him to discover not only his true self but the father he could become as well. (c) Disney" 0x08fadd00
[1] Movie * 0x8fda800 0x08fda800
[2] Movie * 0x8d68720 0x08d68720
but on breakpoint the "writeToFile" method (from the jsonData object) returns this: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (Movie)
Is it because of the UIImage value? What am I not seeing? Thanks much.
Yes, it's because of the UIImage. NSJSONSerialization only works with NSString, NSNumber, NSArray, NSDictionary, and NSNull. See the NSJSONSerialization docs for full details.
If you want to include the image, you'll have to convert it to NSData first, probably using either UIImagePNGRepresentation or UIImageJPEGRepresentation.

Using format specifier in for a URL in iOS

I'm having problems with using format specifiers for url's. Using the zBar scanner to scan a php link. I've spent a lot of time researching here on overflow but I cannot find the answer.
This is the code I use in my viewcontroller.m:
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://mywebsite.co.uk/TM.php?id=%#",self.scannedValue]]];
//NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Sample" ofType:#"JSON"]];
NSArray *jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:Nil];
I'm trying to get the part after id to take in any integer number like 200,201,202,203,...
For some strange reason it only works when I type the number in itself as id=201 or id=202.
when I use NSLog for NSLog(#"%#",scannedValue) it shows the following:
2014-02-26 21:45:27.185 MeCombine[2412:60b] http://mywebsite.co.uk/TM.php?id=201
2014-02-26 21:45:27.277 MeCombine[2412:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
Can anyone tell me why this happens please?
A few notes:
scannedValue = sym.data;
is string, sum is ZBarSymbol class object
In the ZBarSymbol class
#property (readonly, nonatomic) NSString *data;
is the starting value.
When a value is successfully scanned it will return a NSString *data in the delegate method.
I can only provide a guess, since I don't see all of your code, but here's what I think goes on:
Your http link is malformed (http:: instead of http:). The jsonData object will be nil if it can't load the URL for whatever reason.
You don't do any null checking, and this nil object is sent to whatever method processes your json data, which throws a NSInvalidArgumentException if the data object is nil.
NSData's +dataWithContentsOfURL: does not tolerate nil URL, which in this case happens because of the incorrect URL format, notice you have two : in the URL after http. The correct URL would be.
http://mywebsite.co.uk/TM.php?id=%#
The modern and potentially more foolproof way of building URLs would be to use NSURLComponents (iOS 7 and OS X 10.9)
NSURLComponents *comps = [NSURLComponents componentsWithString:#"http://www.mywebsite.co.uk"];
comps.query = [NSString stringWithFormat:#"id=%#", self.scannedValue];
comps.path = #"/TM.php";
NSURL *URL = comps.URL;
The main benefit would be the ability to isolate the base URL into a constant string and then alter the query/path from elsewhere, both making things a bit more modular and easier to maintain than a hardcoded value in code.

iOS Read a Stream but returns null

Ok boys and girls, this is my prob :
I'd like to read a JSON stream in my iOS app, but when i tried, it returns
2013-04-12 02:35:01.479 Test[81414:303] (null)
but my file exist and is absolutely not empty !! You can find it here http://api.kalokod.com/cce/mainfeed.json
And my script to read it is :
NSError *error;
NSURL *file = [NSURL URLWithString:#"http://api.kalokod.com/cce/mainfeed.json"];
NSString *string = [NSString stringWithContentsOfURL:file
encoding:NSUTF8StringEncoding
error:&error];
NSLog(#"%#", string);
I tested your code, and received a Cocoa Error 261. This means that the JSON you are trying to load isnt encoded with UTF-8, so using NSUTF8StringEncoding wont work. Try this
NSString *string = [NSString stringWithContentsOfURL:file
encoding:NSASCIIStringEncoding
error:&error];
I suspect this might be your problem -- that there are non-UTF8 characters in your JSON string.
Log your NSError *error to see if you get a Cocoa error 261.

Encrypted twitter feed

I'm developing an iOS application , that will take a twits from twitter,
I'm using the following API
https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&count=2&screen_name=TareqAlSuwaidan
The problem are feed in Arabic Language ,
i.e the text feed appears like this
\u0623\u0646\u0643 \u0648\u0627\u0647\u0645
How can i get the real text (or how to encode this to get real text) ?
This is not encrypted, it is unicode. The codes 0600 - 06ff is Arabic. NSString handles unicode.
Here is an example:
NSString *string = #"\u0623\u0646\u0643 \u0648\u0627\u0647\u0645";
NSLog(#"string: '%#'", string);
NSLog output:
string: 'أنك واهم'
The only question is exactly what problem are you seeing, are you getting the Arabic text? Are you using NSJSONSerialization to deserialize the JSON? If so there should be no problem.
Here is an example with the question URL (don't use synchronous requests in production code):
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&count=2&screen_name=TareqAlSuwaidan"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSArray *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSDictionary *object1 = [jsonObject objectAtIndex:0];
NSString *text = [object1 objectForKey:#"text"];
NSLog(#"text: '%#'", text);
NSLog output:
text: '#Naser_Albdya أيدت الثورة السورية منذ بدايتها وارجع لليوتوب واكتب( سوريا السويدان )
Those are Unicode literals. I think all that's needed is to use NSString's stringWithUTF8String: method on the string you have. That should use NSString's native Unicode handling to convert the literals to the actual characters. Example:
NSString *directFromTwitter = [twitterInterface getTweet];
// directFromTwitter contains "\u0623\u0646\u0643 \u0648\u0627\u0647\u0645"
NSString *encodedString = [NSString stringWithUTF8String:[directFromTwitter UTF8String]];
// encodedString contains "أنك واهم", or something like it
The method call inside the conversion call ([directFromTwitter UTF8String]) is to get access to the raw bytes of the string, that are used by stringWithUTF8String. I'm not exactly sure on what those code points come out to, I just relied on Python to do the conversion.

Resources