Last active
June 27, 2016 16:19
-
-
Save Andrewpk/5d5159c60f6401b17e456103b430f061 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.m | |
// NSURLWeirdness | |
// | |
// Created by Andrew Kehrig on 6/24/16. | |
// Copyright © 2016 dudid llc. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
@interface NSURL (BetterRelativeToURLSupport) | |
+(instancetype)betterURLWithString:(NSString*)relativeString relativeToURL:(NSURL*)baseURL; | |
@end | |
@implementation NSURL (BetterRelativeToURLSupport) | |
+(instancetype)betterURLWithString:(NSString*)relativeString relativeToURL:(NSURL*)baseURL | |
{ | |
//It's called 'relativeToURL' for a reason right? Even if this baseURL doesn't end in a / | |
//we should fix it because the developer said this is the base URL so the entire URL | |
//should be treated as the base. | |
if ([baseURL.absoluteString characterAtIndex:(baseURL.absoluteString.length - 1)] != '/' ) { | |
baseURL = [NSURL URLWithString:[baseURL.absoluteString stringByAppendingString:@"/"]]; | |
} | |
//So this is an interesting part. | |
//The only requirements are that the string conform to RFC2396, that it not be nil, | |
//and that it will be interpreted relative to the baseURL. So why, if the baseURL | |
//has additional path components, do we nix those and interpret it, in a more absolute | |
//style? We probably shouldn't - the user asked for a baseURL with additional path | |
//components, so if they exist, we should interpret the relativeString relative | |
//with the entire baseURL and all included path components. | |
if ([baseURL pathComponents].count > 1 && [relativeString characterAtIndex:0] == '/') { | |
relativeString = [@"." stringByAppendingString:relativeString]; | |
} | |
return [NSURL URLWithString:relativeString relativeToURL:baseURL]; | |
} | |
@end | |
int main(int argc, const char * argv[]) { | |
@autoreleasepool { | |
NSString *basePath = @"https://some.awesome.host.com:9999/api/v1"; | |
NSString *relativePath = @"/account/user/1"; | |
NSURL *baseURL = [NSURL URLWithString:basePath]; | |
NSURL *unexpectedURL = [NSURL URLWithString:relativePath relativeToURL:baseURL]; | |
NSRange range = NSMakeRange(0, 1); | |
NSString *moreRelativePath = [relativePath stringByReplacingCharactersInRange:range withString:@"./"]; | |
NSURL *potentiallyExpectedURL = [NSURL URLWithString:moreRelativePath relativeToURL:baseURL]; | |
NSLog(@"\n---------\n\nunexpected URL absoluteString: %@\n", unexpectedURL.absoluteString); | |
NSLog(@"potentially \"expected\" URL absoluteString: %@\n", potentiallyExpectedURL.absoluteString); | |
NSLog(@"expected URL absoluteString: %@\n", [NSURL betterURLWithString:relativePath relativeToURL:baseURL].absoluteString); | |
/** example output | |
--------- | |
unexpected URL absoluteString: https://some.awesome.host.com:9999/account/user/1 | |
2016-06-24 02:28:09.283 NSURLBugXcode7[29155:385606] potentially "expected" URL absoluteString: https://some.awesome.host.com:9999/api/account/user/1 | |
2016-06-24 02:28:09.283 NSURLBugXcode7[29155:385606] expected URL absoluteString: https://some.awesome.host.com:9999/api/v1/account/user/1 | |
Program ended with exit code: 0 | |
*/ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment