NSRangeException when searching for bytes near end of NSData - ios

I want to check the last 2 bytes of files in my app to make sure they are not corrupt .jpg's
rangeOfData:options:range: looks like a good option, but I am having a hard time figuring out how to get a proper NSRange. The range I am looking for is starting near the end of the NSData, up to the end.
Here is what I have so far:
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
NSRange range = {([imageData length]-8),[imageData length]};
NSString *str = #"FFD9";
NSData *jpgTest = [str dataUsingEncoding:NSUTF8StringEncoding];
NSRange found = [imageData rangeOfData:jpgTest options:NSDataSearchBackwards range:range];
Here is the error I get:
** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSConcreteData rangeOfData:options:range:]: range {14954, 14962} enxceeds data length 14962'
How do I properly get the range to search the last few bytes of my NSData?

The second member of NSRange is not the end point of the range but its length. So in your case it should be:
NSRange range = {([imageData length]-8), 8};

Related

ios crash in 'NSCFString dataUsingEncoding:allowLossyConversion:]: didn't convert all characters'

I want to convert NSString to NSData with following code:
NSUInteger lengthTest = contentStr.length;
NSStringEncoding encodingStr = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
if ([contentStr canBeConvertedToEncoding:encodingStr]) {
NSData *data = [contentStr dataUsingEncoding:encodingStr allowLossyConversion:YES];
lengthTest = [data length];
}
But my fabric report a Crash named: NSCFString dataUsingEncoding:allowLossyConversion:]: didn't convert all characters'
I want to know which character could cause this problem and fix it , expecting someone could help me.

Extracting URLs from NSString into NSMutableString

I have a file with the following content:
cool name http://myurl1.tld/subdir/dir/var/ awesome\nanother cool name http://sub.domain.tld/dir/ nice\nsome nice name http://myname.tld/var/folder/ some\n
I read the file with this Objetive-C code:
NSData* data = [NSData dataWithContentsOfFile:[NSString stringWithFormat:#"../files/name.ext"]];
NSString* raw = [[NSString alloc]
initWithBytes:[data bytes]
length:[data length]
encoding:NSUTF8StringEncoding];
To extract all URLs from the above sample I use:
NSDataDetector* detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:nil];
NSArray* matches = [detector matchesInString:raw options:0 range:NSMakeRange(0, [raw length])];
My goal is to append all extracted URLs into one single string and separate them with a semicolon (without any other stuff from the file) with this loop:
NSMutableString *allURLStrings = [NSMutableString string];
for (NSString *s in matches) {
[allURLStrings appendString:s];
[allURLStrings appendString:#";"];
}
Whenever I try to run the code I get the following output:
terminating with uncaught exception of type NSException (lldb)
I tried to use the loop like this, but then the substringForCurrMatch only contains a slash (/):
NSMutableString * allRepoString = [NSMutableString string];
for (NSTextCheckingResult *s in matches) {
NSString* substringForCurrMatch = [s.URL path];
[allRepoString appendString:substringForCurrMatch];
[allRepoString appendString:#";"];
}
When I inspect s in the loop it shows me the correct object:
Is there a way to get this code working?
EDIT complete error message:
2016-08-11 23:00:19.272 AppName[34831:2892247] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[fetchurlsource allURLStrings]: unrecognized selector sent to instance 0x14c55ea00'
*** First throw call stack:
(0x181fa2db0 0x181607f80 0x181fa9c4c 0x181fa6bec 0x181ea4c5c 0x1000e8b6c 0x1000e8ee0 0x187100c40 0x187100844 0x18710759c 0x187104a88 0x18717afa4 0x1873a63ac 0x1873aa5f0 0x1873a7764 0x1839437ac 0x183943618 0x1839439c8 0x181f5909c 0x181f58b30 0x181f56830 0x181e80c50 0x18716f94c 0x18716a088 0x1000edb10 0x181a1e8b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
None of the code you posted so far can result in the exception you posted.
But the following code is incorrect:
NSMutableString * allRepoString = [NSMutableString string];
for (NSTextCheckingResult *s in matches) {
NSString* substringForCurrMatch = [s.URL path];
[allRepoString appendString:substringForCurrMatch];
[allRepoString appendString:#";"];
}
You do not want to call the path method on s.URL. To get the full URL as a string, use absoluteString. This will give you the URL as a string. path just gives you the path portion of the URL.
NSMutableString * allRepoString = [NSMutableString string];
for (NSTextCheckingResult *s in matches) {
NSString* substringForCurrMatch = [s.URL absoluteString];
[allRepoString appendString:substringForCurrMatch];
[allRepoString appendString:#";"];
}

NSRange changes itself inside for loop

I have an NSDictionary of NSRange objects, with keys for their index in the array. I am attempting to use each of these ranges to create substrings of a larger string, and place each of these substrings in the array. I basically have this completed, but the NSRange is mysteriously changing it's value in the code, causing it to crash and throw an exception. Here is my code:
NSMutableArray*subStringArray = [[NSMutableArray alloc] init];
for(id key in aDict){
NSRange* range = CFBridgingRetain([aDict objectForKey:key]);
NSLog(#"This is a single range: %#",range);
//Range is changed here somehow
NSString* aSubString = [self.content substringWithRange:*range];
NSLog(#"%#",aSubString);
[subStringArray addObject:aSubString];
}
My Log output looks like this:
This is a single range: NSRange: {1874, 72}
2014-06-17 20:07:30.100 testApp[8027:60b] *** Terminating app due to uncaught exception
'NSRangeException', reason: '-[__NSCFString substringWithRange:]: Range {4318599072, 4} out of bounds; string length 5562'
By popular demand :)
The main issue with your code is that you are directly storing an NSRange struct in your dictionary. You can't do this. You must wrap the NSRange in an NSValue to store it in the dictionary.
To add the NSRange you can do:
NSRange range = ... // some range
NSValue *value = [NSValue valueWithRange:range];
dict[someKey] = value;
Then your posted code becomes:
for (id key in aDict) {
NSValue *value = aDict[key];
NSRange range = [value rangeValue];
NSLog(#"This is a single range: %#",range);
//Range is changed here somehow
NSString* aSubString = [self.content substringWithRange:range];
NSLog(#"%#",aSubString);
[subStringArray addObject:aSubString];
}

How do I parse a csv file?

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.

NSLog string is fine but string into UITextView causes exception [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
So I have a view controller and in the viewdidload method it's supposed to load some content from a webpage (just a proof of concept, it'll be cached eventually). It gets the content using the tfhipple library and puts the contents into an array, it logs the data to the console and then I want it to apply the contents to a UITextView. However when the view controller is called it gets so far as to log the text to the console but on the line where it sets it as the contents of the UITextView it causes an exception.
NSData *dataURL;
NSString *url = #"http://www.testwebsite.com/testpage.html";
dataURL = [NSData dataWithContentsOfURL: [NSURL URLWithString: url]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
TFHpple * doc = [[TFHpple alloc] initWithHTMLData:dataURL];
NSArray *elements = [doc searchWithXPathQuery:#"//div[contains(#id,'main-section')]//text()"];
NSString * aboutcontents = [elements objectAtIndex:2];
NSLog(#"test: %#", aboutcontents);
self.aboutbox.text = aboutcontents;
The exception it causes is as follows, along with the console output before hand:
2013-06-24 09:37:51.433 AppName[24765:c07] test: {
nodeContent = "Test Content";
nodeName = text;
raw = "Test Content";
}
2013-06-24 09:37:51.434 AppName[24765:c07] -[TFHppleElement length]: unrecognized selector sent to instance 0x8043be0
2013-06-24 09:37:51.434 AppName[24765:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TFHppleElement length]: unrecognized selector sent to instance 0x8043be0'
*** First throw call stack:
(0x25d012 0x16ebe7e 0x2e84bd 0x24cbbc 0x24c94e 0x76b4fb 0x3347 0x7111c7 0x711232 0x7328c9 0x732704 0x730bda 0x730a5c 0x732647 0x16ff705 0x6332c0 0x633258 0x855ff4 0x16ff705 0x6332c0 0x633258 0x6f4021 0x6f457f 0x6f4056 0x859af9 0x16ff705 0x6332c0 0x633258 0x6f4021 0x6f457f 0x6f36e8 0x662cef 0x662f02 0x640d4a 0x632698 0x22b2df9 0x22b2ad0 0x1d2bf5 0x1d2962 0x203bb6 0x202f44 0x202e1b 0x22b17e3 0x22b1668 0x62fffc 0x2fdd 0x21a5)
libc++abi.dylib: terminate called throwing an exception
(lldb)
I'm a little bit stuck as to why it does this. If I manually set the string aboutcontents to something then it changes the contents of the UITextView without issue.
Any help is as always appreciated.
Try this:
TFHppleElement * aboutcontents = [elements objectAtIndex:2];
NSLog(#"test: %#", [aboutcontents text]);
self.aboutbox.text = [aboutcontents text];
Here is the documentation part taken from hpple:
TFHppleElement * element = [elements objectAtIndex:0];
[e text]; // The text inside the HTML element (the content of the first text node)
[e tagName]; // "a"
[e attributes]; // NSDictionary of href, class, id, etc.
[e objectForKey:#"href"]; // Easy access to single attribute
[e firstChildWithTagName:#"b"]; // The first "b" child node
Try to get attributes for example and see what it returns to you.
you getting resutt for NSString * aboutcontents = [elements objectAtIndex:2]; is a dictionary,convert dictionary into string like this
NSString * aboutcontents=[NSString stringWithFormat:#"%#",[elements objectAtIndex:2]];
Try this.
NSDictionary * aboutcontents = [elements objectAtIndex:2];
NSLog(#"test: %#", aboutcontents);
self.aboutbox.text = [aboutcontents objectForKey:#"nodeContent"];
I don't understand the context but I saw { } in the Log and I guess only dictionaries get printed that way.

Resources