11

What is proper way to extract and remove scheme name and :// from a NSURL?

For example:

 note://Hello  ->  @"Hello"
 calc://3+4/5  ->  @"3+4/5"

so

NSString *scheme = @"note://";
NSString *path   = @"Hello";

for later use in:

[[NSNotificationCenter defaultCenter] postNotificationName:scheme object:path];
ohho
  • 50,879
  • 75
  • 256
  • 383
  • 1
    NSString *str = [urURL absoluteString]; NSString *string = [str stringByReplacingOccurrencesOfString:@":// " withString:@""] //try this – the1pawan Jun 14 '13 at 04:46
  • Take a look at [this](https://github.com/joeldev/JLRoutes/blob/master/JLRoutes/JLRoutes.m#L82). It parses the entire URL scheme, but you get the gist of it. – CodaFi Jun 14 '13 at 04:47

5 Answers5

19

You can look at it like this (mostly untested code, but you get the idea):

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    NSLog(@"url: %@", url);
    NSLog(@"scheme: %@", [url scheme]);
    NSLog(@"query: %@", [url query]);
    NSLog(@"host: %@", [url host]);
    NSLog(@"path: %@", [url path]);

    NSDictionary * dict = [self parseQueryString:[url query]];
    NSLog(@"query dict: %@", dict);
}

So you can do this:

NSString * strNoURLScheme = 
 [strMyURLWithScheme stringByReplacingOccurrencesOfString:[url scheme] withString:@""];

NSLog(@"URL without scheme: %@", strNoURLScheme);

parseQueryString

- (NSDictionary *)parseQueryString:(NSString *)query
{
    NSMutableDictionary *dict = [[[NSMutableDictionary alloc] initWithCapacity:6] autorelease];
    NSArray *pairs = [query componentsSeparatedByString:@"&"];

    for (NSString *pair in pairs) {
        NSArray *elements = [pair componentsSeparatedByString:@"="];
        NSString *key = [[elements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *val = [[elements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];        
        [dict setObject:val forKey:key];
    }
    return dict;
}
WrightsCS
  • 50,551
  • 22
  • 134
  • 186
7

My inclination is to roll your own string searching for this:

NSRange dividerRange = [urlString rangeOfString:@"://"];
NSUInteger divide = NSMaxRange(dividerRange);
NSString *scheme = [urlString substringToIndex:divide];
NSString *path = [urlString substringFromIndex:divide];

This does what you've asked for in quite a literal fashion, dividing the URL in half around its scheme. For more advanced handling, you'll have to provide more details.

Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
5

just use the NSURL's API named: resourceSpecifier :)

and remove the two slashes from the beginning of the string:

NSURL *url = [NSURL URLWithString:@"https://some.url.com/path];

url.resourceSpecifier will result in: //some.url.com/path

Nikita
  • 1,811
  • 1
  • 20
  • 41
  • 2
    **This** is the correct answer. From TFM: "Any URL is composed of these two basic pieces. The full URL would be the concatenation of [myURL scheme], ':', [myURL resourceSpecifier]" – jjrscott Sep 13 '19 at 07:37
1

Remember, don't fight the frameworks especially when it comes to NSURL. This SO answer has a good breakdown of its abilities. https://stackoverflow.com/a/3693009/142358

NSURL's scheme and path properties are exactly what you want which (assuming the rest of your URL looks like a path) leaves you with this:

NSString *schemeWithDelimiter = [NSString stringWithFormat:@"%@://",[myURL scheme]];
[[NSNotificationCenter defaultCenter] postNotificationName: schemeWithDelimiter object:[myURL path];

No string searching needed!

Community
  • 1
  • 1
Steve Moser
  • 7,647
  • 5
  • 55
  • 94
1

Swift5, URL extension:

var resourceSpecifier: String {
    get {
        let nrl : NSURL = self as NSURL
        return nrl.resourceSpecifier ?? self.absoluteString
    }
}
var simpleSpecifier: String {
    get {
        let str = self.resourceSpecifier
        return str[2..<str.count]
    }
}
slashlos
  • 913
  • 9
  • 17