how to convert host of nsurl to lowercase - ios

Let's say I have www.GOOgle.com/.......
I want to change it to www.google.com/....
and keep the rest of url as it is.
I have tried with NSURLComponents, but it didn't work.
// I am taking input from textfield and making the nsurl.
NSURLComponents *components = [NSURLComponents componentsWithString: _textfield.text]; // input from textfield
[[components host] lowercaseString];
NSURL *urlin = [components URL]; //but this gives, www.GOOgle.com
Any lead is appreciated.

As #Larme Suggests you can use method to setHost in url
see below example
NSURLComponents *components = [NSURLComponents componentsWithString: #"https://sTackoverFlow.com/questions/47924276/how-to-convert-host-of-nsurl-to-lowercase"];
[components setHost:[components.host lowercaseString] ];
NSLog(#"%#",components.URL)
H
ttps://stackoverflow.com/questions/47924276/how-to-convert-host-of-nsurl-to-lowercase
NOTE:
http:// is required to add in String otherwise you will get host nil
eg https://www.sTackoverFlow.com/questions/47924276/how-to-convert-host-of-nsurl-to-lowercase it will work
while
www.sTackoverFlow.com/questions/47924276/how-to-convert-host-of-nsurl-to-lowercase
Will Not work

If your string is only url then, you can try this,
let strURL = "http://GOogLe.Com/Testt/xyz"
let url = NSURL(string: strURL)
let domain: String = (url?.host)! //get your host name
print(domain) //GOogLe.Com
let str = strURL.replacingOccurrences(of: domain, with: domain.lowercased())
print(str) //http://google.com/Testt/xyz

Convert the string to lowercase.
Then pass the converted string value to the componentsWithString method.
Sample:
NSString *lowerCaseStringValue = [_textfield.text lowercaseString];
[NSURLComponents componentsWithString: lowerCaseStringValue];

Related

Can WKWebView support encoded url?

If I use an encoded url to open in WKWebView, this webView can not open this link。
NSString* request = #"http%3A%2F%2Fwww.baidu.com%0A";
NSURL* url = [NSURL URLWithString:request];
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
So I must to decode the url before passed it to WKWebView .
Any other pretty way to make the WKWebView support encoded url?
No, there's no other way. Decode the URL. I'm guessing you got this from a URL query string field. If so, take advantage of NSURLComponents. That makes it easy to grab the unencoded value for a query string part.
NSString *valueForKeyInURL(NSString *key, NSURL *URL) {
NSURLComponents *components =
[NSURLComponents componentsWithURL:URL
resolvingAgainstBaseURL:NO];
NSURLQueryItem *theField = nil;
for (NSURLQueryItem *item in components.queryItems) {
if ([item.name isEqual:key]) {
theField = item;
break;
}
}
return item.value;
}

URL Query item from NSURLComponents are nill

I am creating a NSURL URL will contain some escape character (Japanese)
NSString* currentlocationbarString = #"mbos.help.jp/search?q=専門&pg=1"
NSString *escapedString = [currentlocationbarString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSURL* url = [NSURL URLWithString:escapedString];
//url is mbos.help.jp%2Fsearch%3Fq=%E5%B0%82%E9%96%80&pg=1
When I create NSURLComponents and try to get query items it gives me nil.
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url
resolvingAgainstBaseURL:YES];
NSArray *queryItems = urlComponents.queryItems;
//here issue with queryItems
if anybody has solution to get query items please help. Thanks in advance
Issue is not with Unicode Characters, whenever you add encoding use proper character set for my case I was using following setURLHostAllowedCharacterSet it means your NSURLComponents only give encoding for your Host, to get correct queryItems use URLQueryAllowedCharacterSet like this way.
NSString* currentlocationbarString = #"mbos.help.jp/search?q=専門&pg=1"
NSString *escapedString = [currentlocationbarString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL* url = [NSURL URLWithString:escapedString];
So now you can get queryItems.
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url
resolvingAgainstBaseURL:YES];
NSArray *queryItems = urlComponents.queryItems;
At least one of the characters 専門 that you use in your search string is invalid Unicode in the form of unpaired UTF-16 surrogate chars, and thus cannot be encoded by stringByAddingPercentEncodingWithAllowedCharacters:, which therefore returns nil.
You can find an example in this post.
Apparently, you had to check for Japanese characters, if encoding is possible.
I must say, I did not expect that either!

Parse NSURL scheme iOS [duplicate]

What's an efficient way to take an NSURL object such as the following:
foo://name/12345
and break it up into one string and one unsigned integer, where the string val is 'name' and the unsigned int is 12345?
I'm assuming the algorithm involves converting NSURL to an NSString and then using some components of NSScanner to finish the rest?
I can only add an example here, the NSURL class is the one to go. This is not complete but will give you a hint on how to use NSURL:
NSString *url_ = #"foo://name.com:8080/12345;param?foo=1&baa=2#fragment";
NSURL *url = [NSURL URLWithString:url_];
NSLog(#"scheme: %#", [url scheme]);
NSLog(#"host: %#", [url host]);
NSLog(#"port: %#", [url port]);
NSLog(#"path: %#", [url path]);
NSLog(#"path components: %#", [url pathComponents]);
NSLog(#"parameterString: %#", [url parameterString]);
NSLog(#"query: %#", [url query]);
NSLog(#"fragment: %#", [url fragment]);
output:
scheme: foo
host: name.com
port: 8080
path: /12345
path components: (
"/",
12345
)
parameterString: param
query: foo=1&baa=2
fragment: fragment
This Q&A NSURL's parameterString confusion with use of ';' vs '&' is also interesting regarding URLs.
NSURL has a method pathComponents, which returns an array with all the different path components. That should help you get the integer part. To get the name I'd use the host method of the NSURL. The docs say, that it should work if the URL is properly formatted, might as well give it a try then.
All in all, no need to convert into a string, there seems to be plenty of methods to work out the components of the URL from the NSURL object itself.
Actually there is a better way to parse NSURL. Use NSURLComponents. Here is a simle example:
Swift:
extension URL {
var params: [String: String]? {
if let urlComponents = URLComponents(url: self, resolvingAgainstBaseURL: true) {
if let queryItems = urlComponents.queryItems {
var params = [String: String]()
queryItems.forEach{
params[$0.name] = $0.value
}
return params
}
}
return nil
}
}
Objective-C:
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSArray *queryItems = [components queryItems];
NSMutableDictionary *dict = [NSMutableDictionary new];
for (NSURLQueryItem *item in queryItems)
{
[dict setObject:[item value] forKey:[item name]];
}
Thanks to Nick for pointing me in the right direction.
I wanted to compare file urls but was having problems with extra slashes making isEqualString useless. You can use my example below for comparing two urls by first de-constructing them and then comparing the parts against each other.
- (BOOL) isURLMatch:(NSString*) url1 url2:(NSString*) url2
{
NSURL *u1 = [NSURL URLWithString:url1];
NSURL *u2 = [NSURL URLWithString:url2];
if (![[u1 scheme] isEqualToString:[u2 scheme]]) return NO;
if (![[u1 host] isEqualToString:[u2 host]]) return NO;
if (![[url1 pathComponents] isEqualToArray:[url2 pathComponents]]) return NO;
//check some properties if not nil as isEqualSting fails when comparing them
if ([u1 port] && [u2 port])
{
if (![[u1 port] isEqualToNumber:[u2 port]]) return NO;
}
if ([u1 query] && [u2 query])
{
if (![[u1 query] isEqualToString:[u2 query]]) return NO;
}
return YES;
}

ios how to extract the id number part from an app store url?

I would like to extract the id number part from an app store url, for example, following are two app store urls:
https://itunes.apple.com/app/apple-store/id882456583?pt=63826800&ct=%E5%AE%A3%E4%BC%A0%E8%B4%B4001&mt=8
https://itunes.apple.com/app/juan-pi-zhe-kou-shou-ji-shang/id639388447?mt=8&uo=4
I would like to extract the number after "id", i.e. 882456583 and 639388447.
Anyone knows how to do this? Thank you.
Try this
Swift :
let appStoreUrl = NSURL(string: "https://itunes.apple.com/app/juan-pi-zhe-kou-shou-ji-shang/id639388447?mt=8&uo=")
let appId = appStoreUrl?.lastPathComponent?.stringByReplacingOccurrencesOfString("id", withString: "")
Objective C :
NSURL *appStoreUrl = [NSURL URLWithString:#"https://itunes.apple.com/app/juan-pi-zhe-kou-shou-ji-shang/id639388447?mt=8&uo="];
NSString *appId = [appStoreUrl.lastPathComponent stringByReplacingOccurrencesOfString:#"id" withString:#""];
Result:
What you are expecting is this
NSURLComponents *components = [NSURLComponents componentsWithURL:[NSURL URLWithString:#"https://itunes.apple.com/app/apple-store/id882456583?pt=63826800&ct=%E5%AE%A3%E4%BC%A0%E8%B4%B4001&mt=8"] resolvingAgainstBaseURL:NO];
NSLog(#"id = %#",[[[components valueForKey:#"path"] componentsSeparatedByString:#"/"] lastObject]);
in logs you ll have required param.

Change a NSURL's scheme

Is there an easy way to change the scheme of a NSURL? I do realize that NSURL is immutable. My goal is to change the scheme of an URL to "https" if the Security.framework is linked, and "http" if the framework is not linked. I do know how to detect if the framework is linked.
This code works wonderfully if the URL has no parameters (such as "?param1=foo&param2=bar"):
+(NSURL*)adjustURL:(NSURL*)inURL toSecureConnection:(BOOL)inUseSecure {
if ( inUseSecure ) {
return [[[NSURL alloc] initWithScheme:#"https" host:[inURL host] path:[inURL path]] autorelease];
}
else {
return [[[NSURL alloc] initWithScheme:#"http" host:[inURL host] path:[inURL path]] autorelease];
}
}
But if the URL does have parameters, [inURL path] drops them.
Any suggestions short of parsing the URL string myself (which I can do but I want to try not doing)? I do what to be able to pass URLs with either http or https to this method.
Updated answer
NSURLComponents is your friend here. You can use it to swap out the http scheme for https. The only caveat is NSURLComponents uses RFC 3986 whereas NSURL uses the older RFCs 1738 and 1808, so there is some behavior differences in edge cases, but you're extremely unlikely to hit those cases (and NSURLComponents has the better behavior anyway).
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
components.scheme = inUseSecure ? #"https" : #"http";
return components.URL;
Original answer
Why not just do a bit of string manipulation?
NSString *str = [url absoluteString];
NSInteger colon = [str rangeOfString:#":"].location;
if (colon != NSNotFound) { // wtf how would it be missing
str = [str substringFromIndex:colon]; // strip off existing scheme
if (inUseSecure) {
str = [#"https" stringByAppendingString:str];
} else {
str = [#"http" stringByAppendingString:str];
}
}
return [NSURL URLWithString:str];
If you are using iOS 7 and later, you can use NSURLComponents, as show here
NSURLComponents *components = [NSURLComponents new];
components.scheme = #"http";
components.host = #"joris.kluivers.nl";
components.path = #"/blog/2013/10/17/nsurlcomponents/";
NSURL *url = [components URL];
// url now equals:
// http://joris.kluivers.nl/blog/2013/10/17/nsurlcomponents/
Swift5
extension URL {
func settingScheme(_ value: String) -> URL {
let components = NSURLComponents.init(url: self, resolvingAgainstBaseURL: true)
components?.scheme = value
return (components?.url!)!
}
}
Usage
if nil == url.scheme { url = url.settingScheme("file") }
Perhaps using the resourceSpecifier would help:
return [[[NSURL alloc] initWithString:[NSString stringWithFormat:#"https:%#", [inURL resourceSpecifier]]]];
NSString *newUrlString = [NSString stringWithFormat:#"https://%#%#",
inURL.host, inURL.path];
if (inURL.query) {
newUrlString = [newUrlString stringByAppendingFormat:#"?%#", inURL.query];
}
return [NSURL URLWithString:newUrl];
[NOTE]
Code related to port and other fields handling are removal for simplicity.
I did it like this, using a variable resourceSpecifier in NSURL
SWIFT
var resourceSpecifier: String? { get }
OBJECTIVE-C
#property(readonly, copy) NSString *resourceSpecifier Discussion
This property contains the resource specifier. For example, in the URL http://www.example.com/index.html?key1=value1#jumplink, the resource specifier is //www.example.com/index.html?key1=value1#jumplink (everything after the colon).
-(NSURL*) URLByReplacingScheme
{
NSString *newUrlString = kHttpsScheme;
if([self.scheme isEqualToString:kEmbeddedScheme])
newUrlString = kHttpScheme;
newUrlString = [newUrlString stringByAppendingString:[NSString stringWithFormat:#":%#", self.resourceSpecifier]];
return [NSURL URLWithString:newUrlString];
}

Resources