Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two NSURLs that are practically equivalent but have cosmetic string differences?

Under IOS, I wish to identify pairs of NSURLs that are either identical or differ slightly but refer to the same destination. For instance http://google.com vs http://google.com/.

isEquals reports those NSURLs as diferent. Nor can I find a way to obtain a 'canonical' or 'normalized' form of an NSURL to compare those forms instead.

NSURL *a = [NSURL URLWithString:@"http://google.com"];
NSURL *b = [NSURL URLWithString:@"http://google.com/"];

if([a isEqual:b]) {
  NSLog(@"Same"); // Not run
}

if([[a absoluteURL] isEqual:[b absoluteURL]]) {
  NSLog(@"Same"); // Still not run
}

if([[a URLByStandardizingPath] isEqual:[b URLByStandardizingPath]]) {
  NSLog(@"Same"); // Still not run
}

How can I compare two NSURLs while ignoring string differences that do not affect the intent of the URL?

like image 495
Jim Blackler Avatar asked Apr 27 '11 08:04

Jim Blackler


1 Answers

According to RFC 2616, http://google.com and http://google.com/ are equivalent. This is what it says (section 3.2.3):

When comparing two URIs to decide if they match or not, a client SHOULD use a case-sensitive octet-by-octet comparison of the entire URIs, with these exceptions:

  • A port that is empty or not given is equivalent to the default port for that URI-reference;

  • Comparisons of host names MUST be case-insensitive;

  • Comparisons of scheme names MUST be case-insensitive;

  • An empty abs_path is equivalent to an abs_path of "/".

For reference, the syntax is given as http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]

Unfortunately, NSURL has to support schemes other than HTTP, so it cannot make the assumption that RFC 2616 provides a generic rule. I think your best fix is to create a category with your own compare method for http URLs that specifically checks for an empty absolute path.

like image 143
JeremyP Avatar answered Oct 16 '22 05:10

JeremyP