How to convert NSData which contains a line break to a NSString - ios7

The following code works perfectly to convert the NSData that I got from a URL/JSON file to a NSString, EXCEPTION MADE by the cases that data contains line breaks!
What's wrong with my code?
My Code:
NSError *errorColetar = nil;
NSURL *aColetarUrl = [[NSURL alloc]initWithString:#"http://marcosdegni.com.br/petsistema/teste/aColetar3.php"];
NSString *aColetarString = [NSString stringWithContentsOfURL:aColetarUrl encoding:NSUTF8StringEncoding error:&errorColetar];
NSLog(#"NSString: %#", aColetarString);
if (!errorColetar) {
NSData *aColetarData = [aColetarString dataUsingEncoding:NSUTF8StringEncoding];
self.arrayAColetar = [NSJSONSerialization JSONObjectWithData:aColetarData options:kNilOptions error:nil];
}
NSLog(#"arrayAColetar %#", self.arrayAColetar);
Log Results:
**NSString**: [{"id_atendimento":"2","observacoes":"ABC-Enter-->
DEF-Enter-->
GFH-END"},{"id_atendimento":"1","observacoes":"123Enter-->
345Enter-->
678End"}]
**arrayAColetar** (null)
As you can see my bottom line is an empty array :(
Thanks in advance!

By checking the error message hidden under 'error:nil' I found a "Unescaped control character around character" issue and implemented the code below from Unescaped control characters in NSJSONSerialization
and got a new 'cleaned' string.
- (NSString *)stringByRemovingControlCharacters: (NSString *)inputString {
NSCharacterSet *controlChars = [NSCharacterSet controlCharacterSet];
NSRange range = [inputString rangeOfCharacterFromSet:controlChars];
if (range.location != NSNotFound) {
NSMutableString *mutable = [NSMutableString stringWithString:inputString];
while (range.location != NSNotFound) {
[mutable deleteCharactersInRange:range];
range = [mutable rangeOfCharacterFromSet:controlChars];
}
return mutable;
}
return inputString;
}

Related

Why does -[NSString compare:options:] return true when the strings are not equal?

I am checking if a string appears twice in a row within an array. This code doesn't seem to work, as it just prints out the entire array. What am I missing?
NSString *nameString =
[NSString stringWithContentsOfFile:#"/usr/share/dict/words"
encoding:NSUTF8StringEncoding
error:NULL];
NSArray *names = [nameString componentsSeparatedByString:#"\n"];
//Save last item
NSMutableString *lastOne = [NSMutableString stringWithCapacity:20];
// Go through the array one string at a time
for (NSString *n in names) {
if ([n compare:lastOne options:NSCaseInsensitiveSearch]) {
NSLog(#"%#", n);
}
[lastOne setString:n];
}
compare: and related functions don't return booleans, they return an NSComparisonResult. If you want to see if a string is equal you should instead use
if ([n compare:lastOne options:NSCaseInsensitiveSearch] == NSOrderedSame)

NSString doesn't overwrites with a new value

Trying to remove all the urls from text:
- (NSString *)cleanText:(NSString *)text{
NSString *string = #"This is a sample of a http://abc.com/efg.php?EFAei687e3EsA sentence with a URL within it.";
NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray *matches = [linkDetector matchesInString:string options:0 range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult *match in matches) {
if ([match resultType] == NSTextCheckingTypeLink) {
NSString *matchingString = [match description];
NSLog(#"found URL: %#", matchingString);
string = [string stringByReplacingOccurrencesOfString:matchingString withString:#""];
}
}
NSLog(string);
return string;
}
However string returns unchanged (there is match).
Upd.: Console output:
found URL: <NSLinkCheckingResult: 0xb2b03f0>{22, 36}{http://abc.com/efg.php?EFAei687e3EsA}
2013-10-02 20:19:52.772
This is a sample of a http://abc.com/efg.php?EFAei687e3EsA sentence with a URL within it and a number 097843.
Ready working recipe done by #Raphael Schweikert.
The problem is that [match description] does not return the matching string; it returns a string that looks like this:
"<NSLinkCheckingResult: 0x8cd5150>{22,36}{http://abc.com/efg.php?EFAei687e3EsA}"
To replace the matched URL in your string, you should do:
string = [string stringByReplacingCharactersInRange:match.range withString:#""];
According to Apple’s own Douglas Davidson, the matches are guaranteed to be in the order they appear in the string. So instead of sorting the matches array (as I suggested), it can just be iterated in reverse.
The whole code sample would then look as follows:
NSString *string = #"This is a sample of a http://abc.com/efg.php sentence (http://abc.com/efg.php) with a URL within it and some more text afterwards so there is no index error.";
NSDataDetector *linkDetector = [NSDataDetector dataDetectorWithTypes:0|NSTextCheckingTypeLink error:nil];
NSArray *matches = [linkDetector matchesInString:string options:0 range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult *match in [matches reverseObjectEnumerator]) {
string = [string stringByReplacingCharactersInRange:match.range withString:#""];
}
The check for match.resultType == NSTextCheckingTypeLink can be omitted as you’ve already specified in the options that you’re only interested in links.

Objective-C - Works with strings, find a substring with NSRange

I'm working with the strings and i have a little problem that i'm not understanding. In fact, i have a string like this: "ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=168BA548-9C81-4B08-B69C-B775E5DD9341&ext=JPG" and i need to find the string between "URLs:" and "?id=" . For doing this, i'm trying to create a new string using the NSRange. In this mode i give the first index and the last index that i need, but it seems not working.
Here there is my code:
NSString *description = [asset description];
NSRange first = [description rangeOfString:#"URLs:"];
NSRange second = [description rangeOfString:#"?id="];
NSString *path = [description substringWithRange: NSMakeRange(first.location, second.location)];
It return to me this kind of string: "URLs:assets-library://asset/asset.JPG?id=168BA548-9C81-4B08-B69C-B775E5DD9341&ext=JPG". Is it correct? I'm expecting to obtain "assets-library://asset/asset.JPG" string.
Where i'm doing wrong? Is there a better way to do this?
I have followed this url for help: http://www.techotopia.com/index.php/Working_with_String_Objects_in_Objective-C
Thanks
Try this range:
NSMakeRange(first.location + first.length, second.location - (first.location + first.length))
Don't parse the ALAsset description string! If the description ever changes your code breaks. Use the methods ALAsset and NSURL provide you. First, get the dictionary of URLs (mapped by asset type) through the valueForProperty: method. Then, for each URL, get the absoluteString and remove the query string from it. I got the string you were looking for by placing the following code in the application:didFinishLaunchingWithOptions: method from the single-view iPhone app template.
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop) {
NSDictionary *URLDictionary = [asset valueForProperty:ALAssetPropertyURLs];
for (NSURL *URL in [URLDictionary allValues]) {
NSString *URLString = [URL absoluteString];
NSString *query = [URL query];
if ([query length] > 0) {
NSString *toRemove = [NSString stringWithFormat:#"?%#",query];
URLString = [URLString stringByReplacingOccurrencesOfString:toRemove withString:#""];
NSLog(#"URLString = %#", URLString);
}
}
}];
} failureBlock:^(NSError *error) {
}];
NSRange first = [description rangeOfString:#"URLs:"];
gives you the position of the U, so you need to take first.location+5 to get the start position of assets-library.
NSRangeMake(loc,len) takes a starting location loc and a length, so you need to use second.location-first.location-5 to get the length you are looking for.
Adding it all up, replace the last line with:
NSRange r = NSMakeRange(first.location+5, second.location-first.location-5);
NSString *path = [description substringWithRange:r];

yahoo weather api parsing

How can I parse the wind spped for the following JSON that I have received from the link
http://weather.yahooapis.com/forecastjson?w=2502265. I am getting a garbage value from it but getting the rest of the values correctly. Can anybody let me know how can I get the wind speed out of it?
{"units":{"temperature":"F","speed":"mph","distance":"mi","pressure":"in"},"location":{"location_id":"USCA1116","city":"Sunnyvale","state_abbreviation":"CA","country_abbreviation":"US","elevation":82,"latitude":37.39,"longitude":-122.03},"wind":{"speed":0,"direction":"CALM"},"atmosphere":{"humidity":"86","visibility":"10","pressure":"30.21","rising":"falling"},"url":"http:\/\/weather.yahoo.com\/forecast\/USCA1116.html","logo":"http:\/\/l.yimg.com\/a\/i\/us\/nt\/ma\/ma_nws-we_1.gif","astronomy":{"sunrise":"06:27","sunset":"18:11"},"condition":{"text":"Fair","code":"33","image":"http:\/\/l.yimg.com\/a\/i\/us\/we\/52\/33.gif","temperature":49},"forecast":[{"day":"Today","condition":"PM Showers","high_temperature":"64","low_temperature":"47"},{"day":"Tomorrow","condition":"Partly Cloudy","high_temperature":"62","low_temperature":"45"}]}
NSString *linkForWoeid = [NSString stringWithFormat:#"http://where.yahooapis.com/geocode?location=%#,%#&flags=J&gflags=R&appid=zHgnBS4m",latitude,longitude];
NSURL *woeid = [NSURL URLWithString:linkForWoeid];
NSData *WoeidData = [NSData dataWithContentsOfURL:woeid];
if (WoeidData != NULL)
{
NSError *woeiderr = nil;
//NSLog(#"linkForWoeid:%#woeid:%#woeidData:%#",linkForWoeid,woeid,WoeidData);
NSDictionary *response1=[NSJSONSerialization JSONObjectWithData:WoeidData options:NSJSONReadingMutableContainers error:&woeiderr];
NSDictionary *woeidDict = [[[[response1 objectForKey:#"ResultSet"]objectForKey:#"Results"]objectAtIndex:0]objectForKey:#"woeid"];
NSString *address=[NSString stringWithFormat:#"http://weather.yahooapis.com/forecastjson?w=%#",woeidDict];
NSURL *url=[NSURL URLWithString:address];
NSData *data=[NSData dataWithContentsOfURL:url];
NSError *eqw=nil;
if (data != NULL)
{
NSDictionary *response=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&eqw];
//NSLog(#"response:%#",response);
NSString *highTempDict = [[[response objectForKey:#"forecast"]objectAtIndex:0] objectForKey:#"high_temperature"];
NSString *temp = [highTempDict stringByAppendingFormat:#" 'F"];
NSString *windSpeed = [[response objectForKey:#"wind"] objectForKey:#"speed"];
NSLog(#"wind :%#",windSpeed);
if (windSpeed == 0)
{
NSLog(#"insideif");
windSpeed = #"0";
}
NSString *imageView = [[response objectForKey:#"condition"]objectForKey:#"image" ];
Hi Rasi Please use NSNumber instead of NSString here
NSNumber *windSpeed = [[response objectForKey:#"wind"] objectForKey:#"speed"];
As in JSON it's coming as integer value (without quotes) so it is not a NSString but NSNumber
And you can get it's string value as [windSpeed stringValue];

how to read a txt file and store in NSArray?

i am trying to read a txt file and store it in a NSArray. here is my code, but it seems there is something missing that i don't know!
NSURL *url=[NSURL URLWithString:#"http://www.google.com/robots.txt"];
NSMutableArray *robots=[NSMutableArray arrayWithContentsOfURL:url];
NSLog(#"%#",robots);
You have to load the contents of URL into string first like
NSString *content = [NSString stringWithContentsOfURL:URL encoding:NSUTF8StringEncoding error:nil];
Then split this string like this:
NSArray *parsed = [content componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
Now parsed array will contain strings from the URL.
Edit:
If you want to filter your array, add this code:
NSIndexSet *indexes = [parsed indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
NSRange range = [(NSString *)obj rangeOfString:#"Disallow"];
if (range.location != NSNotFound)
{
return YES;
}
return NO;
}];
NSArray *disallowed = [parsed objectsAtIndexes:indexes];
disallowed will be populated with the strings that contains Disallow string