11

I'm having a problem with NSRange. Here is my code:

NSRange range = [[[NSHTTPCookie requestHeaderFieldsWithCookies:[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:cookie]]] objectForKey:@"Cookie"] rangeOfString:@"x"];
NSLog(@"%f", range.length);
if (range.length >= 1) {
    NSLog(@"Do Something");
} else {
    NSLog(@"AUTHING");
}

Console output:

0.000000
Do something

And then the second time I run through the code:

0.000000
AUTHING

What the hell is going on? NSNotFound I think it was does not work and I'm not the only person finding this problem so using it is not a solution.

Thanks for any help.

Cheers

Edit: I tried using NSLog(@"%d", range.length) but it gives incorrect output the first time it runs through, the second time it runs through it is correct. I've tried using NSNotFound thinking that the strange output is due to it being NSNotFound but it didn't trigger

Rudiger
  • 6,515
  • 13
  • 48
  • 94

2 Answers2

38

If you want to see if the string was found using -[NSString rangeOfString:], you need to see if NSRange.location == NSNotFound:

if (range.location != NSNotFound) {
    // String was found
else {
    // String not found
}
Nick Forge
  • 20,944
  • 7
  • 50
  • 77
  • Nope, same result as with length. – Rudiger Nov 30 '10 at 04:38
  • In that case, your string probably doesn't contain what you think it should contain. What does the `cookieParameter` string contain when you use @aosik's code from above? – Nick Forge Nov 30 '10 at 05:53
  • 1
    In which case, either your `header` doesn't contain an object for the key `@"Cookie"`, or it is `nil` also. This process (divide and conquer) is known as debugging… ;-) – Nick Forge Nov 30 '10 at 06:34
  • Thank you for that, it does not say in the doco that rangeOfString: on a null object would return undefined results and therefore I have to check the object first before rangeOfString. I've already done this but the doco should either say null would produce undefined results or work - neither of which is the case. – Rudiger Nov 30 '10 at 11:06
  • 1
    Due to how Objective-C works, it's safe to assume that any non-object value returned by a message that was passed to a `nil` object is undefined. This isn't specific to `rangeOfString:`. Sending any message to `nil` will return `nil`, but if that method is supposed to return a C primitive that has a different size to `id`, you will get an undefined result. You should therefore check to see if `cookieParameter == nil` before you call `rangeOfString:`. – Nick Forge Nov 30 '10 at 11:25
2

As a general comment, debugging is much easier if you split up the nested method calls and do a quick NSLog to see what's going on. (i'm not that good at adhering to that so it's not meant as criticism).

One thing i first noted was the use of "%f" to display the length, try using %i (integer) and you should be able to get the correct length. %f will always display 0.00000.

what url are you using? given that you are pulling the data from the headers, the string "x" may or may not be present in the field. i would suggest NSLog-ing the NSString* object that you pull out of the dictionary and checking to see what's going on. E.g.:NSString *cookie = @"http://www.google.com/";

NSHTTPCookieStorage *store = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSURL *url = [NSURL URLWithString:cookie];
NSDictionary *header = [NSHTTPCookie requestHeaderFieldsWithCookies: [store cookiesForURL:url]];
NSString *cookieParameter = [header objectForKey:@"Cookie"];    

NSLog(@"Cookie param is %@", cookieParameter);

// Test range of "x"
NSRange range = [cookieParameter rangeOfString:@"x"];
NSLog(@"%f", range.length); // will print out 0.00000
NSLog(@"%i", range.length); // will print out correct length (always 1 for "x")
NSLog(@"%i", range.location); // will print out the location of the first instance of "x"
if (range.length >= 1) {
    NSLog(@"Do Something");
} else {
    NSLog(@"AUTHING");
}

It seems like the code just detects the index of the string "x" from what I can tell, is this the intended result?

aosik
  • 250
  • 2
  • 7
  • x is in replace of something not relevant to the question. All I'm checking is if x is in the string. I tried %i as you said and its the same output as %d. The first time I check %i it is 860329857. I thought this might be defined as NSNotFound but I tried and no dice – Rudiger Nov 30 '10 at 03:41
  • As a side note thats why I used %f, when I get a stupid number like 860329857 I figure its because its not the same type, %d gave the suspected output being 0.00000 – Rudiger Nov 30 '10 at 03:43
  • NSLog(@"%i", range.location); gives a similarly incorrect output sorry. – Rudiger Nov 30 '10 at 04:06