Problem with NSRange - iphone

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

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
}

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?

Related

iOS rangeOfString can't locate the string that is definitely there

I am writing code in objective-c. I would like to extract a url from a string.
Here is my code:
NSMutableString *oneContent = [[latestPosts objectAtIndex:i] objectForKey:#"content"];
NSLog(#"%#", oneContent);//no problem
NSString *string = #"http";
if ([oneContent rangeOfString:string].location == NSNotFound) {
NSLog(#"string does not contain substring");
} else {
NSLog(#"string contains substring!");
}
As you can see, I want to extract a url from the oneContent string, and I have checked that oneContent definitely contains "http", but why does the result show nothing?
Is there some better way to extract the url?
Check oneContent or the actual code you are running.
This works:
NSMutableString *oneContent = [#"asdhttpqwe" mutableCopy];
NSLog(#"%#", oneContent);//no problem
NSString *string = #"http";
if ([oneContent rangeOfString:string].location == NSNotFound) {
NSLog(#"string does not contain substring");
} else {
NSLog(#"string contains substring!");
}
NSLog output:
Untitled[5911:707] asdhttpqwe
Untitled[5911:707] string contains substring!
It is probably best not to use a Mutable string unless there is some substantial reason to do so.
I would suggest using NSScanner.

UITextView Autocomplete modification

I'm currently using this HTAutocompleteTextField to fill in a UITextField with a predefined list, should A user start typing in an entry that already exists. There are a couple of problems that I've been having however. The first is that it seems to stop when a comma is typed in (but not apostrophes). I've been looking around and I'm really not sure why it's doing it. I thought at one point it could be that the comma was a different comma, like an apostrophe issue I had due to importing the list from a word document. However, it wasn't the case. The second issue is more of an addition which I'm not really sure how to implement. I also want the autosuggest to detect suggestions for words in mid string, not just from the beginning. So for instance typing in "String" would suggest "This is a String". This currently how it does the auto suggest, but I have no idea how to do the above things.
NSString *prefixLastComponent = [componentsString.lastObject stringByTrimmingCharactersInSet:space];
if (ignoreCase)
{
stringToLookFor = [prefixLastComponent lowercaseString];
}
else
{
stringToLookFor = prefixLastComponent;
}
for (NSString *stringFromReference in colorAutocompleteArray)
{
NSString *stringToCompare;
if (ignoreCase)
{
stringToCompare = [stringFromReference lowercaseString];
}
else
{
stringToCompare = stringFromReference;
}
if ([stringToCompare hasPrefix:stringToLookFor])
{
return [stringFromReference stringByReplacingCharactersInRange:[stringToCompare rangeOfString:stringToLookFor] withString:#""];
}
}
If anyone could give me any pointers on how to get this done, I'd appreciate it.
Regards,
Mike
Managed to go about solving both issues. For any one who uses this Git Repository, the reason why commas don't work when using the preset methods is because of NSArray *componentsString = [prefix componentsSeparatedByString:#","];. Remove the comma so it's NSArray *componentsString = [prefix componentsSeparatedByString:#""]; and it should work nicely. To fix the other problem where it only detects the start of words, I changed the methods a little. Here are my changes in HTAutocompleteManager.m
int i = 0;
for (NSString *stringFromReference in colorAutocompleteArray)
{
NSString *stringToCompare;
if (ignoreCase)
{
stringToCompare = [stringFromReference lowercaseString];
}
else
{
stringToCompare = stringFromReference;
}
if ([stringToCompare hasPrefix:stringToLookFor])
{
//NSLog(#"Removing String: %# atIndex: %d", [colorAutocompleteArray objectAtIndex:i], i);
[colorAutocompleteArray removeObjectAtIndex:i];
[colorAutocompleteArray insertObject:stringFromReference atIndex:0];
//NSLog(#"Adding String atIndex 0: %#", stringFromReference);
return [stringFromReference stringByReplacingCharactersInRange:[stringToCompare rangeOfString:stringToLookFor] withString:#""];
}
else if ([stringToCompare hasSuffix:stringToLookFor] && ([stringToLookFor length] >= 3)) {
return [NSString stringWithFormat:#" %#", stringFromReference];
}
else if (!([stringToCompare rangeOfString:stringToLookFor].location == NSNotFound) && ([stringToLookFor length] >= 3))
{
return [NSString stringWithFormat:#" %#", stringFromReference];
}
++i;
}
The reason for reordering the Array is because after the 3rd character is typed it will prioritise the other two if statements because they will be reached first if there is a generic term in multiple entries in the array (like "Street" in a list of locations). I know it's not necessary to have the "hasSuffix" if statement, but I left it in case someone wants to use it on it's own. Lastly, I added in a space before stringFromReference so that it doesn't look weird when there's a suggestion straight after the input text. When we exit the UITextField we remove this space like this (inside HTAutocompleteTextField.m - commitAutocompleteText):
NSString *currentText = self.text;
if ([self.autocompleteString isEqualToString:#""] == NO
&& self.autocompleteDisabled == NO)
{
if ([self.autocompleteString hasPrefix:#" "]) {
self.autocompleteString = [self.autocompleteString substringFromIndex:1];
}
self.text = [NSString stringWithFormat:#"%#", self.autocompleteString];
self.autocompleteString = #"";
[self updateAutocompleteLabel];
}
return ![currentText isEqualToString:self.text];
Hope this makes sense to anyone who's in a similar situation.
Mike

Condition always fails though the comparative values seems correct in iOS

When I check the value of number in nslog it shows '0'
NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
NSNumber *number=[data objectForKey:#"serial"];
NSLog(#"%#",number);
if(number ==0 )
{
imgButton.hidden=YES;
}
But the condition always fails , I also changed the code like this
NSString *number=[data objectForKey:#"serial"]
NSLog(#"%#",number);
if(number == #"0" )
{
imgButton.hidden=YES;
}
But here too the condition fail ,What is the issue with this?
In the first code you are checking a NSNumber, object, against an int.
The correct check is:
if([number intValue] == 0) {
imgButton.hidden = YES;
}
In the second code you are checking two NSString, but you have to use the "isEqualToString" method and not "==". The correct code is:
if([number isEqualToString:#"0"]) {
imgButton.hidden = YES;
}
NSNumber is an object, 0 is an integer (a primitive type). They will never be equal. But you can change the comparison like this [number intValue] == 0 and this will work when the value of your NSNumber is 0.
On the string comparison, you should use the method
isEqualToString:NSString *)string
for the comparison.
For NSNumbers its
isEqualToNumber:(NSNumber *)number
Because otherwise you arent comparing if they have the same value, but if they are stored in identical memory space.

NSString substring wont compare

My string comparison keeps returning false and I dont understand why. Even my nslog says the value is correct. Do you know why my comparison keeps returning false even though the strings appear to be the same? If I step through the program type shows SV as its value. I have ensured there are no spaces in this string as well. We get the first two chars of this:
SV2B799E5B-4306-4965-B5DD-944D3970E6B6
NSString *fPath = [path stringByAppendingPathComponent:[directoryContent objectAtIndex:x]];
NSString *fName = [directoryContent objectAtIndex:x];
NSString *type = [fName substringToIndex:2];
NSLog(#"TYPE: %#",type);
if ([type caseInsensitiveCompare:#"SV"])
{
NSData *file = [[NSData alloc] initWithContentsOfFile:fPath];
if (file)
{
[[WebService sharedWebService]saveVolunteer:nil :YES :[directoryContent objectAtIndex:x] :file];
[file release];
}
}
[NSString -caseInsensitiveCompare:] does not return a BOOL, it returns an NSComparisonResult. This is going to be 0 if the strings are equal (in a case insensitive fashion), which is why you're seeing that result.
Invert your result and you'll be set, or to be more correct, check to see if it is == NSOrderedSame.
The method you are calling returns an NSComparisonResult, not a boolean value. It so happens that an NSComparisonResult of equal has the value zero, which is interpreted as false.
caseInsensitiveCompare: returns a NSComparisonResult. Try [type caseInsensitiveCompare:#"SV"] == NSOrderedSame

What is the shortest way to write rangeOfString with list of names, dictionary, king james bible, etc?

This is embarrassing. I don't want to use coredata or text file. I need shortest way to write this code.
names ("John", "Matthew", "thomas", "isaac", "bible", "Mayan", "2012", more names)
This code takes extremely long and wasting too much memory, download time, and waste of space. Not recommend it. 10,000 lines.
NSString *selectives = Name.text;
if ([selectives rangeOfString:#"John"].location != NSNotFound) {
//
}
if ([selectives rangeOfString:#"Matthew"].location != NSNotFound) {
//
}
Second. This code doesn't work. I don't what I'm doing wrong here. I'm lost. I need help!
NSString *string = Name.text;
NSString *NameMe = [NSString stringWithString:#"Jake", "miller", "thomas", "isaac"];
if([string rangeOfString:NameMe].location !=NSNotFound)
{
//
}
Is there a better way to write this? How do you write? I'm not good at this.
In the first case you can use fast enumeration to shorten your code.
NSArray *searchStrings = // Set up your search strings however you want
NSString *selectives = Name.text
for (NSString *searchString in searchStrings) {
if [selectives rangeOfString:searchString].location != NSNotFound {
// Your processing here
}
}
In the second case this line is wrong
NSString *NameMe = [NSString stringWithString:#"Jake", "miller", "thomas", "isaac"];
You aren't passing in a properly formed string. #"Jake" is valid, the rest, because they are outside the #"..." section are not.