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

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.

Related

Parsing XML from NSString to get values

This question is for manipulating NSString in xcode.
I have a XML text string that I get from the web that looks like this
<current temperature="73" day="Mon" humidity="59" windspeed="10"></current>
How can I get individual values from this string and put them in my NSString variables?
e.g.
NSString *tempStr = ??
NSString *dayStr = ??
NSString *windspeedStr = ??
First, download and include RaptureXML within your project as described on the RaptureXML project site.
For parsing the single given line, use the following snippet - your input is passed as inXmlString;
//transform string into an XML DOM
RXMLElement *rootNode = [RXMLElement elementFromXMLString:inXmlString
withEncoding:NSUTF8StringEncoding];
if (rootNode == nil || ![rootNode isValid])
{
//do something, we failed!
}
else
{
NSString *temperature = [rootNode attribute:#"temperature"];
NSString *day = [rootNode attribute:#"day"];
NSString *windspeed = [rootNode attribute:#"windspeed"];
}
The basic idea is to use the NSString method componentsSeparatedByString: to parse out the data you want. You'll probably need to do a bit more work to get it exactly right for your scenario.
NSArray* paArray1= [pstrXMLString componentsSeparatedByString:#" "];
temlStr= [[[paArray1 objectAtIndex:1] componentsSeparatedByString:#"="] objectAtIndex:1];
dayStr= [[[paArray1 objectAtIndex:2] componentsSeparatedByString:#"="] objectAtIndex:1];
windspeedStr= [[[paArray1 objectAtIndex:3] componentsSeparatedByString:#"="] objectAtIndex:1];

NSString search whole text for another string

I would like to search for an NSString in another NSString, such that the result is found even if the second one does not start with the first one, for example:
eg: I have a search string "st". I look in the following records to see if any of the below contains this search string, all of them should return a good result, because all of them have "st".
Restaurant
stable
Kirsten
At the moment I am doing the following:
NSComparisonResult result = [selectedString compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
This works only for "stable" in the above example, because it starts with "st" and fails for the other 2. How can I modify this search so that it returns ok for all the 3?
Thanks!!!
Why not google first?
String contains string in objective-c
NSString *string = #"hello bla bla";
if ([string rangeOfString:#"bla"].location == NSNotFound) {
NSLog(#"string does not contain bla");
} else {
NSLog(#"string contains bla!");
}
Compare is used for testing less than/equal/greater than. You should instead use -rangeOfString: or one of its sibling methods like -rangeOfString:options:range:locale:.
I know this is an old thread thought it might help someone.
The - rangeOfString:options:range: method will allow for case insensitive searches on a string and replace letters like ‘ö’ to ‘o’ in your search.
NSString *string = #"Hello Bla Bla";
NSString *searchText = #"bla";
NSUInteger searchOptions = NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch;
NSRange searchRange = NSMakeRange(0, string.length);
NSRange foundRange = [string rangeOfString:searchText options:searchOptions range:searchRange];
if (foundRange.length > 0) {
NSLog(#"Text Found.");
}
For more comparison options NSString Class Reference
Documentation on the method - rangeOfString:options:range: can be found on the NSString Class Reference

Uppercase first letter in NSString

How can I uppercase the fisrt letter of a NSString, and removing any accents ?
For instance, Àlter, Alter, alter should become Alter.
But, /lter, )lter, :lter should remains the same, as the first character is not a letter.
Please Do NOT use this method. Because one letter may have different count in different language. You can check dreamlax answer for that. But I'm sure that You would learn something from my answer.
NSString *capitalisedSentence = nil;
//Does the string live in memory and does it have at least one letter?
if (yourString && yourString.length > 0) {
// Yes, it does.
capitalisedSentence = [yourString stringByReplacingCharactersInRange:NSMakeRange(0,1)
withString:[[yourString substringToIndex:1] capitalizedString]];
} else {
// No, it doesn't.
}
Why should I care about the number of letters?
If you try to access (e.g NSMakeRange, substringToIndex etc)
the first character in an empty string like #"", then your app will crash. To avoid this you must verify that it exists before processing on it.
What if my string was nil?
Mr.Nil: I'm 'nil'. I can digest anything that you send to me. I won't allow your app to crash all by itself. ;)
nil will observe any method call you send to it.
So it will digest anything you try on it, nil is your friend.
You can use NSString's:
- (NSString *)capitalizedString
or (iOS 6.0 and above):
- (NSString *)capitalizedStringWithLocale:(NSLocale *)locale
Since you want to remove diacritic marks, you could use this method in combination with the common string manipulating methods, like this:
/* create a locale where diacritic marks are not considered important, e.g. US English */
NSLocale *locale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en-US"] autorelease];
NSString *input = #"Àlter";
/* get first char */
NSString *firstChar = [input substringToIndex:1];
/* remove any diacritic mark */
NSString *folded = [firstChar stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:locale];
/* create the new string */
NSString *result = [[folded uppercaseString] stringByAppendingString:[input substringFromIndex:1]];
Gonna drop a list of steps which I think you can use to get this done. Hope you can follow through without a prob! :)
Use decomposedStringWithCanonicalMappingto decompose any accents (Important to make sure accented characters aren't just removed unnecessarily)
Use characterAtIndex: to extract the first letter (index 0), use upperCaseString to turn it into capitol lettering and use stringByReplacingCharactersInRange to replace the first letter back into the original string.
In this step, BEFORE turning it into uppercase, you can check whether the first letter is one of the characters you do not want to replace, e.g. ":" or ";", and if it is, do not follow through with the rest of the procedure.
Do a [theString stringByReplacingOccurrencesOfString:#"" withString:#""]` sort of call to remove any accents left over.
This all should both capitalize your first letter AND remove any accents :)
Since iOS 9.0 there is a method to capitalize string using current locale:
#property(readonly, copy) NSString *localizedCapitalizedString;
I'm using this method for similar situations but I'm not sure if question asked to make other letters lowercase.
- (NSString *)capitalizedOnlyFirstLetter {
if (self.length < 1) {
return #"";
}
else if (self.length == 1) {
return [self capitalizedString];
}
else {
NSString *firstChar = [self substringToIndex:1];
NSString *otherChars = [self substringWithRange:NSMakeRange(1, self.length - 1)];
return [NSString stringWithFormat:#"%#%#", [firstChar uppercaseString], [otherChars lowercaseString]];
}
}
Just for adding some options, I use this category to capitalize the first letter of a NSString.
#interface NSString (CapitalizeFirst)
- (NSString *)capitalizeFirst;
- (NSString *)removeDiacritic;
#end
#implementation NSString (CapitalizeFirst)
- (NSString *)capitalizeFirst {
if ( self.length <= 1 ) {
return [self uppercaseString];
}
else {
return [[[[self substringToIndex:1] removeDiacritic] uppercaseString] stringByAppendingString:[[self substringFromIndex:1] removeDiacritic]];
// Or: return [NSString stringWithFormat:#"%#%#", [[[self substringToIndex:1] removeDiacritic] uppercaseString], [[self substringFromIndex:1] removeDiacritic]];
}
}
- (NSString *)removeDiacritic { // Taken from: http://stackoverflow.com/a/10932536/1986221
NSData *data = [NSData dataUsingEncoding:NSASCIIStringEncoding
allowsLossyConversion:YES];
return [[NSString alloc] initWithData:data
encoding:NSASCIIStringEncoding];
}
#end
And then you can simply call:
NSString *helloWorld = #"hello world";
NSString *capitalized = [helloWorld capitalizeFirst];
NSLog(#"%# - %#", helloWorld, capitalized);

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.

problem with a string and parse XML

I have a logical condition that does not work. it would compare two characters, one taken from the xml and the other I insert myself.
to let you know I am attaching below the code
NSString *telefono = [NSString stringWithFormat:#"%#", [[arrayColonnine objectAtIndex:indexPath.row]objectForKey:#"telefono"]];
NSString *trimmedTelefono = [telefono stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
senzaTelefono = [[NSString alloc] initWithString:[trimmedTelefono stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
if (telefono == #"NO")
if (trimmedTelefono == #"NO")
if (senzaTelefono == #"NO")
for each of the three strings if I do a log it print NO. but in none of the three cases the if works. how can I fix to make it work?
SOLUTION
the process is just this:
NSString *telefono = [NSString stringWithFormat:#"%#", [[arrayColonnine objectAtIndex:indexPath.row]objectForKey:#"telefono"]];
NSString *trimmedTelefono = [telefono stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([trimmedTelefono isEqualToString:#"NO"]) {
//do something...
}
You should use isEqualToString:
if ([telefono isEqualToString:#"NO"])
if (telefono == #"NO") compares the objects being the same, not the contents being the same.
Don't use == to compare NSString objects.