Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change a NSURL's scheme

Tags:

ios

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.

like image 655
kamprath Avatar asked Jan 18 '13 05:01

kamprath


2 Answers

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]; 
like image 74
Lily Ballard Avatar answered Oct 03 '22 19:10

Lily Ballard


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/ 
like image 42
onmyway133 Avatar answered Oct 03 '22 19:10

onmyway133