Xcode 4 NSRangeException Error after split string - xcode

I'm trying to split a string and separate it into variable but am getting the following error:
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 ..
1]'
Code:
NSLog(#"%#", strResult);
NSArray* LocInfo = [strResult componentsSeparatedByString: #"|"];
NSString* Response1 = [LocInfo objectAtIndex: 0];
NSString* Response2 = [LocInfo objectAtIndex: 1];
NSString* Response3 = [LocInfo objectAtIndex: 2];
Any ideas? Thanks!

Your strResult is broken into LocInfo array that contains only two elements, and you tried to access third one.
As your string already contains 1 / 2 or 3 NSStrings, therefore no need to again store then into NSString, you can directly use them by LocInfo[index].
If you need to check how many strings are there simply use : [LocInfo count];

Related

Error converting a NSString to a NSURL

The following snippet produces the debugger listing that follows it. Yet, if Line Two replaces Line One, there is no error. LineTwo was obtained by coping and pasting the debugger output from a previous run. Can you explain this to me?
//LINE ONE
NSString* aString = self.urlText;
NSLog(#"aString: %#",aString);
//LINE TWO
//NSString* aString = #"file:///Users/oldmancoyote1/Documents/A%20REFERENCE%20SYSTEM/C/Computers/iOS/C%20and%20Obj.%20C/C%20Language/1-4.6.html";
NSURL* testURL = [NSURL fileURLWithPath:aString];
2016-01-03 12:44:30.307 webScrol[1505:62452] aString: file:///Users/oldmancoyote1/Documents/A%20REFERENCE%20SYSTEM/C/Computers/iOS/C%20and%20Obj.%20C/C%20Language/1-4.6.html
2016-01-03 12:44:30.307 webScrol[1505:62452] -[NSURL length]: unrecognized selector sent to instance 0x6080000a4800
2016-01-03 12:44:30.307 webScrol[1505:62452] Failed to set (contentViewController) user defined inspected property on (NSWindow): -[NSURL length]: unrecognized selector sent to instance 0x6080000a4800
aString is actually an NSURL object despite being stored in an NSString variable. This must have happened in earlier code than what you have provided.
When it’s passed to [NSURL fileURLWithPath:], that function tries to treat it as an NSString by calling its length method and the program crashes.

Exception using NSPredicate with the Photos Framework : Define -[NSFunctionExpression constantValue]!

The following code throws an NSInvalidArgumentException on the call to fetchAssetsWithOptions:
PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
allPhotosOptions.sortDescriptors =
#[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:NO]];
allPhotosOptions.predicate =
[NSPredicate predicateWithFormat:#"pixelHeight >= pixelWidth * 1.95" ];
self.allPhotos = [PHAsset fetchAssetsWithOptions:allPhotosOptions];
The message is
NSInvalidArgumentException ... reason: '*** -constantValue only defined for abstract class.
Define -[NSFunctionExpression constantValue]!'
I tried numerous variations on the predicate format string, but always get this message when I try to use multiplication. What am I doing wrong?
I'm not certain why, but when you don't pass any format arguments to predicateWithFormat: and use it with Photos you get this error;
I was able to fix the issue by ensuring I was passing format arguments. So in your case:
float heightLimit = pixelWidth * 1.95;
[NSPredicate predicateWithFormat:#"pixelHeight >= %f", heightLimit];

Removing unwanted characters from json response

I am trying to load data from a json response stored in an NSArray into a tableview.
json:
"fulltime": [
2,
2
],
Above is the json but when I display to screen it looks like the below code.
( 2, 2)
I have tried using the following to remove unwanted characters the brackets () in this case but i am getting the warning below the code.
NSArray *place= [jsonResults objectAtIndex:indexPath.row];
NSString *score= [place valueForKey:#"fulltime"];
Firstly tried this:
NSString *score = [[[place valueForKey:#"fulltime"]objectAtIndex:indexPath.row] stringByReplacingOccurrencesOfString:#"(" withString:#""];
And then this:
NSString *jsonstring = [score stringByReplacingOccurrencesOfString:#"\)\n" withString:#""];
jsonstring = [jsonstring stringByReplacingOccurrencesOfString:#"\t" withString:#""];
This is the error i get each time:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber stringByReplacingOccurrencesOfString:withString:]: unrecognized selector sent to instance 0x1f55f270'
I am not sure is it a problem with the way i am trying o remove the characters or the way i am parsing the data. Below is a better view of the json, everything else parses fine up until i want to access "fulltime"
"date": "2013-03-17 16:00:00",
"home_id": 8455,
"home": "Chelsea",
"homeshort": "Chelsea",
"away_id": 8654,
"away": "West Ham United",
"awayshort": "West Ham",
"status": "Finished",
"halftime": [1, 0],
"fulltime": [2, 0],
"extratime": [0, 0],
"penalties": [0, 0],
try like this may be it'l helps you,
[[[jsonarray objectAtIndex:0] valueForKey:#"fulltime"] objectAtIndex:0]
Not sure if I understood what you want, but to parse those numbers I would do something like:
NSDictionary * place= [jsonResults objectAtIndex:indexPath.row];
NSArray * fulltime = [place valueForKey:#"fulltime"];
NSNumber * num1 = [fulltime objectAtIndex:0];
NSNumber * num2 = [fulltime objectAtIndex:1];
NSLog(#"Fulltime is %d, %d", [num1 intValue], [num2 intValue]);

NSArray out of bounds check

noobie question.. What is the best way to check if the index of an NSArray or NSMutableArray exists. I search everywhere to no avail!!
This is what I have tried:
if (sections = [arr objectAtIndex:4])
{
/*.....*/
}
or
sections = [arr objectAtIndex:4]
if (sections == nil)
{
/*.....*/
}
but both throws an "out of bounds" error not allowing me to continue
(do not reply with a try catch because thats not a solution for me)
Thanks in advance
if (array.count > 4) {
sections = [array objectAtIndex:4];
}
If you have an integer index (e.g. i), you can generally prevent this error by checking the arrays bounds like this
int indexForObjectInArray = 4;
NSArray yourArray = ...
if (indexForObjectInArray < [yourArray count])
{
id objectOfArray = [yourArray objectAtIndex:indexForObjectInArray];
}
Keep in mind NSArray is in sequential order from 0 to N-1 items
Your are trying to access item which has exceeded limit and a array is nil then compiler would throw out of bound error.
EDIT : #sch's answer above shows how can we check if NSArray has required ordered item present in it or not.
You can use the MIN operator to fail silently like this [array objectAtIndex:MIN(i, array.count-1)], to either get next object in the array or the last. Can be useful when you for example want to concatenate strings:
NSArray *array = #[#"Some", #"random", #"array", #"of", #"strings", #"."];
NSString *concatenatedString = #"";
for (NSUInteger i=0; i<10; i++) { //this would normally lead to crash
NSString *nextString = [[array objectAtIndex:MIN(i, array.count-1)]stringByAppendingString:#" "];
concatenatedString = [concatenatedString stringByAppendingString:nextString];
}
NSLog(#"%#", concatenatedString);
Result: "Some random array of strings . . . . . "

Check for String within a String

I'm trying to compare two strings
NSString strOne = #"Cat, Dog, Cow";
NSString strTwo = #"Cow";
How do I determine if strOne contains strTwo
Try using rangeOfString:
NSRange result = [strOne rangeOfString:strTwo];
From the documentation:
Returns an NSRange structure giving the location and length in the receiver of the first occurrence of aString. Returns {NSNotFound, 0} if aString is not found or is empty (#"").
For anyone needing the code to check is a string exists within a string, here's my code thanks to fbrereto. This example checks to see if any string contained in an array of strings (stringArray) can be found within a string (myString):
int count = [stringArray count];
for (NSUInteger x = 0; x < count; ++x) {
NSRange range = [self.myString rangeOfString:[stringArray objectAtIndex:x]];
if (range.length > 0) {
// A match has been found
NSLog(#"string match: %#",[stringArray objectAtIndex:x]);
}
}
I believe this is the correct syntax for checking if the range exists (correcting response from Kendall):
range.location != NSNotFound
Gradually straying off topic, but I always explode my strings, which would mean just exploding it using your search string as a key and you can use the array count to see how many instances you have.
Just incase anyone is coming from a code language that uses "explode" to blow a string up into an array like me, I found writing my own explode function tremendously helpful, those not using "explode" are missing out:
- (NSMutableArray *) explodeString : (NSString *)myString key:(NSString*) myKey
{
NSMutableArray *myArray = [[NSMutableArray alloc] init];
NSRange nextBreak = [myString rangeOfString:myKey];
while(nextBreak.location != NSNotFound)
{
[myArray addObject: [myString substringToIndex:nextBreak.location]];
myString = [myString substringFromIndex:nextBreak.location + nextBreak.length];
nextBreak = [myString rangeOfString:myKey];
}
if(myString.length > 0)
[myArray addObject:myString];
return myArray;
}
works like this:
[self explodeString: #"John Smith|Age: 37|Account Balance: $75.00" key:#"|"];
which will return this array:
[#"John Smith", #"Age: 37", #"Account Balance: $75.00"];
This lets you quickly pull out a specific value in a tight space, Like if you have a client and you want to know how much money he has:
[[self explodeString: clientData key: pipe] objectAtIndex: 1];
or if you wanted specifically the dollar amount as a float:
[[[self explodeString: [[self explodeString: clientData key: pipe] objectAtIndex: 1] key: #": "] objectAtIndex: 2] floatValue];
anyway I find arrays way easier to work with and more flexible, so this is very helpful to me. Additionally with a little effort you could make an "explodable string" data type for your private library that lets you treat it like a string or return an index value based on the key
ExplodableString *myExplodableString;
myExplodableString.string = #"This is an explodable|string";
NSString *secondValue = [myExplodableString useKey: #"|" toGetValue: index];

Resources