Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: parse a URL into segments

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?

like image 671
randombits Avatar asked May 05 '11 19:05

randombits


People also ask

What is URLComponents?

A structure that parses URLs into and constructs URLs from their constituent parts.

What is a URL parser?

URL parsing is a function of traffic management and load-balancing products that scan URLs to determine how to forward traffic across different links or into different servers. A URL includes a protocol identifier (http, for Web traffic) and a resource name, such as www.microsoft.com.

What is Nsurl?

An NSURL object is composed of two parts—a potentially nil base URL and a string that is resolved relative to the base URL. An NSURL object is considered absolute if its string part is fully resolved without a base; all other URLs are considered relative.

What is the name of the class that you can use to build a URL from its constituent pieces?

The NSURLComponents class is a class that is designed to parse URLs based on RFC 3986 and to construct URLs from their constituent parts.


3 Answers

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.

like image 65
Nick Weaver Avatar answered Oct 20 '22 16:10

Nick Weaver


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.

like image 41
Henri Normak Avatar answered Oct 20 '22 17:10

Henri Normak


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]];
    }
like image 12
Andrei Malygin Avatar answered Oct 20 '22 15:10

Andrei Malygin