stringByReplacingOccurrencesOfString not working as expected - iphone

Having a problem. Here's my code:
Latitude = [TBXML textForElement:lat]; //Latitude & Longitude are both NSStrings
Longitude= [TBXML textForElement:lon];
NSLog(#"LAT:%# LON:%#",Latitude,Longitude);
NSString *defaultURL = #"http://api.wxbug.net/getLiveWeatherRSS.aspx?ACode=000000000&lat=+&long=-&unittype=1";
newURL = [[defaultURL stringByReplacingOccurrencesOfString:#"+"
withString:Latitude]
stringByReplacingOccurrencesOfString:#"-"
withString:Longitude];
NSLog(#"%#",newURL);
And here's the output:
LAT:-33.92 LON:18.42
http://api.wxbug.net/getLiveWeatherRSS.aspxACode=000000000&lat=18.4233.92&long=18.42&unittype=1
As you can see, something strange is happening to the appending code. Am I doing something wrong here?

Before replacing the longitude, the string is
http://....&lat=-33.92&long=-&...
^ ^
The system sees that there are two -, and thus both of them will be replaced by the latitude.
You should use a more descriptive string to replace with, e.g.
NSString *defaultURL = #"http://....&lat={latitude}&long={longitude}&unittype=1";
newURL = [defaultURL stringByReplacingOccurrencesOfString:#"{latitude}"
withString:Latitude];
newURL = [newURL stringByReplacingOccurrencesOfString:#"{longitude}"
withString:Longitude];
or simply use +stringWithFormat:.
NSString* newURL = [NSString stringWithFormat:#"http://....&lat=%#&long=%#&...",
Latitude, Longitude];

Here's where we started:
url = #"http://...?ACode=000000000&lat=+&long=-&unittype=1"
Latitude = #"-33.92"
Longitude = #"18.42"
Then you replaced all occurrences of #"+" with #"-33.92":
url = #"http://...?ACode=000000000&lat=-33.92&long=-&unittype=1"
Then you replaced all occurrences of #"-" with #"18.42". Note that there are two '-' characters; one after lat= and one after long=. The one after 'lat' is there because the string you pasted in had a - in it.
url = #"http://...?ACode=000000000&lat=18.4233.92&long=18.42&unittype=1"
Thus, your final result.

#KennyTM, BJ Homer, and madmik3 are correct. Your value is getting replaced twice.
However, you should technically be building your URL in a totally different manner:
NSMutableDictionary *query = [NSMutableDictionary dictionary];
[query setObject:#"000000000" forKey:#"ACode"];
[query setObject:Latitude forKey:#"lat"];
[query setObject:Longitude forKey:#"long"];
[query setObject:#"1" forKey:#"unittype"];
NSMutableArray *queryComponents = [NSMutableArray array];
for (NSString *key in query) {
NSString *value = [query objectForKey:key];
key = [key stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
value = [value stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString *component = [NSString stringWithFormat:#"%#=%#", key, value];
[queryComponents addObject:component];
}
NSString *queryString = [components componentsJoinedByString:#"&"];
NSString *fullURLString = [NSString stringWithFormat:#"http://api.wxbug.net/getLiveWeatherRSS.aspx?%#", queryString];
NSURL *newURL = [NSURL URLWithString:fullURLString];
(ignoring the efficacy of -stringByAddingPercentEscapesUsingEncoding: for now)
The reason this is better is that according to the HTTP specification, the keys and values in the query of the URL should be URL encoded. Granted, you're only encoding numbers for simple keys. But if that ever changes, you URL might break. (The flaw with this method is that it only allows a single value per key, and the HTTP spec allows you to specify multiple values. For the sake of simplicity, I've left that out)
There are also some issues on using -stringByAddingPercentEscapesUsingEncoding:. For more information on that, check out Objective-c iPhone percent encode a string?.

Your LAT is negative. So the - gets replaced twice.

Related

Remove last portion of the NSURL: iOS

I am trying to remove just the last part of the url, Its a FTP URL.
Suppose, I have a URL like: > ftp://ftp.abc.com/public_html/somefolder/. After removing the last portion I should have it as: ftp://ftp.abc.com/public_html/.
I have tried using stringByDeletingLastPathComponenet and URLByDeletingLastPathComponent, but they dont remove the last portion correctly. They change the entire looks of the url.
for instance, after using the above said methods, here is the URL format i get ftp:/ftp.abc.com/public_html/. It removes one "/" in "ftp://", which is crashing my program.
How is it possible to removve just the last part without disturbing the rest of the URL ?
UPDATE:
NSURL * stringUrl = [NSURL URLWithString:string];
NSURL * urlByRemovingLastComponent = [stringUrl URLByDeletingLastPathComponent];
NSLog(#"%#", urlByRemovingLastComponent);
Using above code, I get the output as :- ftp:/ftp.abc.com/public_html/
Hmm. URLByDeletingLastPathComponent works perfectly given the above input.
NSURL *url = [NSURL URLWithString:#"ftp://ftp.abc.com/public_html/somefolder/"];
NSLog(#"%#", [url URLByDeletingLastPathComponent]);
returns
ftp://ftp.abc.com/public_html/
Do you have some sample code that is yielding improper results?
Max
Now try
NSString* filePath = #"ftp://ftp.abc.com/public_html/somefolder/.";
NSArray* pathComponents = [filePath pathComponents];
NSLog(#"\n\npath=%#",pathComponents);
if ([pathComponents count] > 2) {
NSArray* lastTwoArray = [pathComponents subarrayWithRange:NSMakeRange([pathComponents count]-2,2)];
NSString* lastTwoPath = [NSString pathWithComponents:lastTwoArray];
NSLog(#"\n\nlastTwoArray=%#",lastTwoPath);
NSArray *listItems = [filePath componentsSeparatedByString:lastTwoPath];
NSLog(#"\n\nlist item 0=%#",[listItems objectAtIndex:0]);
}
output
path=(
"ftp:",
"ftp.abc.com",
"public_html",
somefolder,
"."
)
lastTwoArray =somefolder/.
list item 0 =ftp://ftp.abc.com/public_html/
An example of how to extract the last part of NSURL. In this case the location of the file. Sqlite core data
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"CoreAPI.sqlite"];
NSString *localPath = [storeURL absoluteString];
NSArray* pathComponents = [localPath pathComponents];
NSLog(#"%#",[pathComponents objectAtIndex:6]);
NSString * nombre = [NSString stringWithFormat:#"%#", [pathComponents objectAtIndex:6]];
This code returns me the name of the file CoreAPI.sqlite

How to get find and get URL in a NSString in iPhone?

I have a text with http:// in NSString. I want to get that http link from the NSString. How can i get the link/url from the string? Eg: 'Stack over flow is very useful link for the beginners https://stackoverflow.com/'. I want to get the 'https://stackoverflow.com/' from the text. How can i do this? Thanks in advance.
I am not sure what you exactly mean by link but if you want to convert your NSString to NSURL than you can do the following:
NSString *urlString = #"http://somepage.com";
NSURL *url = [NSURL URLWithString:urlString];
EDIT
This is how to get all URLs in a given NSString:
NSString *str = #"This is a grate website http://xxx.xxx/xxx you must check it out";
NSArray *arrString = [str componentsSeparatedByString:#" "];
for(int i=0; i<arrString.count;i++){
if([[arrString objectAtIndex:i] rangeOfString:#"http://"].location != NSNotFound)
NSLog(#"%#", [arrString objectAtIndex:i]);
}
Rather than splitting the string into an array and messing about that way, you can just search for the substring beginning with #"http://":
NSString *str = #"Stack over flow is very useful link for the beginners http://stackoverflow.com/";
// get the range of the substring starting with #"http://"
NSRange rng = [str rangeOfString:#"http://" options:NSCaseInsensitiveSearch];
// Set up the NSURL variable to hold the created URL
NSURL *newURL = nil;
// Make sure that we actually have found the substring
if (rng.location == NSNotFound) {
NSLog(#"URL not found");
// newURL is initialised to nil already so nothing more to do.
} else {
// Get the substring from the start of the found substring to the end.
NSString *urlString = [str substringFromIndex:rng.location];
// Turn the string into an URL and put it into the declared variable
newURL = [NSURL URLWithString:urlString];
}
try this :
nsstring *str = #"Stack over flow is very useful link for the beginners http://stackoverflow.com/";
nsstring *http = #"http";
nsarray *arrURL = [str componentsSeparatedByString:#"http"];
this will give two objects in the nsarray. 1st object will be having:Stack over flow is very useful link for the beginners and 2nd will be : ://stackoverflow.com/ (i guess)
then you can do like:
NSString *u = [arrURL lastObject];
then do like:
nsstring *http = [http stringByAppendingFormat:#"%#",u];
Quite a lengthy,but i think that would work for you. Hope that helps you.

NSString - how to go from "ÁlgeBra" to "Algebra"

Does anyone knows hoe to get a NSString like "ÁlgeBra" to "Algebra", without the accent, and capitalize only the first letter?
Thanks,
RL
dreamlax has already mentioned the capitalizedString method. Instead of doing a lossy conversion to and from NSData to remove the accented characters, however, I think it is more elegant to use the stringByFoldingWithOptions:locale: method.
NSString *accentedString = #"ÁlgeBra";
NSString *unaccentedString = [accentedString stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]];
NSString *capitalizedString = [unaccentedString capitalizedString];
Depending on the nature of the strings you want to convert, you might want to set a fixed locale (e.g. English) instead of using the user's current locale. That way, you can be sure to get the same results on every machine.
NSString has a method called capitalizedString:
Return Value
A string with the first character from each word in the receiver changed to its corresponding uppercase value, and all remaining characters set to their corresponding lowercase values.
NSString *str = #"AlgeBra";
NSString *other = [str capitalizedString];
NSLog (#"Old: %#, New: %#", str, other);
Edit:
Just saw that you would like to remove accents as well. You can go through a series of steps:
// original string
NSString *str = #"ÁlgeBra";
// convert to a data object, using a lossy conversion to ASCII
NSData *asciiEncoded = [str dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
// take the data object and recreate a string using the lossy conversion
NSString *other = [[NSString alloc] initWithData:asciiEncoded
encoding:NSASCIIStringEncoding];
// relinquish ownership
[other autorelease];
// create final capitalized string
NSString *final = [other capitalizedString];
The documentation for dataUsingEncoding:allowLossyConversion: explicitly says that the letter ‘Á’ will convert to ‘A’ when converting to ASCII.
Here's a step by step example of how to do it. There's room for improvement, but you get the basic idea......
NSString *input = #"ÁlgeBra";
NSString *correctCase = [NSString stringWithFormat:#"%#%#",
[[input substringToIndex:1] uppercaseString],
[[input substringFromIndex:1] lowercaseString]];
NSString *result = [[[NSString alloc] initWithData:[correctCase dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding] autorelease];
NSLog( #"%#", result );

Simple function to replace all occurrences of spaces in a string with plus (+) signs in iPhone OS

I want to use this but need a solution for this..
NSString *googleAddress = #"http://maps.google.com?q=";
googleAddress = [googleAddress stringByAppendingString:self.address];
googleAddress = [googleAddress stringByAppendingString:#"+"];
googleAddress = [googleAddress stringByAppendingString:self.city];
googleAddress = [googleAddress stringByAppendingString:#",+"];
googleAddress = [googleAddress stringByAppendingString:self.state];
googleAddress = [googleAddress stringByAppendingString:#"&t=h"];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:googleAddress]];
I need to replace all the spaces in the address, city and state values with plus signs to get google maps to work.
Thanks
googleAddress = [googleAddress stringByReplacingOccurancesOfString:#" " withString:#"+"];
I would take a different approach. Here's how I'd do it:
NSString * q = [NSString stringWithFormat:#"%# %#, %#", self.address, self.city, self.state];
NSDictionary * queryDictionary = [NSDictionary dictionaryWithObjectsAndKeys:q, #"q", #"h", #"t", nil];
NSMutableArray * fields = [NSMutableArray array];
for (NSString * key in queryDictionary) {
NSString * value = [queryDictionary objectForKey:key];
NSString * encoded = [NSString stringWithFormat:#"%#=%#", [key URLEncodedString_ch], [value URLEncodedString_ch]];
[fields addObject:encoded];
}
NSString * queryString = [fields componentsJoinedByString:#"&"];
NSString * googleString = [NSString stringWithFormat:#"http://maps.google.com?%#", queryString];
NSURL * googleURL = [NSURL URLWithString:googleString];
[[UIApplication sharedApplication] openURL:googleURL];
-URLEncodedString_ch can be found here
Why is this better? There are several reasons:
The keys in a query string should be URL encoded. Granted that right now they're just one letter that's in the ASCII set, but can you guarantee that they'll always be?
The values in a query string should be URL encoded. Right now you're only trying to plus-encode the spaces. What if your address contains an & or =? It would be unusual for an address, but not impossible (especially the & in a street name).
This is highly extensible. If you decide to add support for foreign address and need more than a simple ASCII address, it's rather trivial to add the #"UTF-8" and #"oe" object and key to the dictionary for inclusion in the query string.
The percent encoding (if you use the category method linked to above) is more accurate than stringByAddingPercentEscapesUsingEncoding:
Have a look at NSString's stringByReplacingOccurrencesOfString:withString: and NSMutableString's replaceOccurrencesOfString:withString:options:range:.
This snippet may be of use to some people, especially since Google treats + and %20 the same.
NSString *escapedUrlString =
[unescapedString stringByAddingPercentEscapesUsingEncoding:
NSASCIIStringEncoding];
Source: http://blog.evandavey.com/2009/01/how-to-url-encode-nsstring-in-objective-c.html

Swear Filter in Objective-C: Needed for iPhone App

Need to filter our swear words that are inputted to the iPhone app and inserted to our database. I'd like to catch this before passing to our database.
Currently, I was using:
stringByReplacingOccurrencesOfString:#"swear" withString:#""
but this seems inefficient to list 20+ words that need to be filtered. What's the best way to approach this?
Here is my complete code
NSUserDefaults *p = [NSUserDefaults standardUserDefaults];
NSString* string1 = [[p valueForKey:#"user"] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString* string2 = [[p valueForKey:#"pass"] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString* string3 = [[[[[[[[[[[[[[tvA.text stringByReplacingOccurrencesOfString:#"\n" withString:#" "] stringByReplacingOccurrencesOfString:#"&" withString:#"and"] stringByReplacingOccurrencesOfString:#"ç" withString:#"c"] stringByReplacingOccurrencesOfString:#"+" withString:#"plus"] stringByReplacingOccurrencesOfString:#"swear" withString:#""] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString* urlString = [NSString stringWithFormat:#"http://domain.com/qa.php?user=%#&pass=%#&id=%#&body=%#",string1,string2,[p valueForKey:#"a"],string3];
id val1 = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
To do it the way you're doing it, it would be much more sensible to keep a list of filtered strings and their replacements — you could even use an external plist file. Then you could either loop through the list, replacing as you go, or create an NSRegularExpression if you're looking for more sophisticated filtering.