I have a requirement to take a string that represents a URL that can be in many formats and standardise it so it conforms with the URL spec.
If the URL string does not have a scheme, or it has a scheme that is not 'http' or 'https', it should use a default scheme.
I wanted to use NSURLComponents but if a scheme is not provided it parses the host as a path
NSURLComponents *components = [NSURLComponents componentsWithString:@"www.google.com.au"];
components.scheme = @"http";
NSLog(@"1: %@", components.path);
NSLog(@"2: %@", components.host);
NSLog(@"3: %@", components.string);
testtest[2619:869020] 1: www.google.com.au
testtest[2619:869020] 2: ((null))
testtest[2619:869020] 3: http:www.google.com.au <-- Invalid
Therefore I ended up with this category on NSString
#define DEFAULT_SCHEME @"http"
@implementation NSString (standardiseUrlFormat)
- (NSString*)standardiseUrlFormat {
NSURLComponents *components = [NSURLComponents componentsWithString:self];
BOOL hasScheme = components.scheme != nil;
// If no scheme or an invalid scheme is provided, default to http
if (!hasScheme) {
// We have to use string concatenation here because NSURLComponents will
// put the hostname as the path if there is no scheme
return [NSString stringWithFormat:@"%@://%@", DEFAULT_SCHEME, self];
}
// Now we know that a scheme exists, check if it is a correct scheme
if (![components.scheme isEqualToString:@"http"] &&
![components.scheme isEqualToString:@"https"]) {
// Overwrite scheme if not supported
components.scheme = DEFAULT_SCHEME;
}
return [components string];
}
@end
With the following output
NSLog(@"1: %@", [@"http://www.google.com" standardiseUrlFormat]);
NSLog(@"2: %@", [@"www.google.com" standardiseUrlFormat]);
NSLog(@"3: %@", [@"https://www.google.com" standardiseUrlFormat]);
NSLog(@"4: %@", [@"https://www.google.com/some_path" standardiseUrlFormat]);
NSLog(@"5: %@", [@"www.google.com/some_path" standardiseUrlFormat]);
testtest[7411:944022] 1: http://www.google.com
testtest[7411:944022] 2: http://www.google.com
testtest[7411:944022] 3: https://www.google.com
testtest[7411:944022] 4: https://www.google.com/some_path
testtest[7411:944022] 5: http://www.google.com/some_path
Can anyone suggest a cleaner solution that doesn't use two methods (NSURLComponents and string concatenation) to construct the string?
答案 0 :(得分:1)
根本不要使用字符串连接。使用NSURLComponents 形成所需的NSURL;这就是它的用途。例如,如果您不喜欢scheme
的内容,将<{em> scheme
设置为您想要的内容。
编辑我想我以为我发现这是一个无主机的URL,你会手动重新调整它,例如。
let s = "www.apple.com/whatever" as NSString
let arr = s.pathComponents
let c = NSURLComponents()
c.scheme = "http"
c.host = arr[0]
c.path = "/" + (Array(arr.dropFirst()) as NSArray).componentsJoinedByString("/")
但也许这不可能做到,问题实际上是没有方案的URL或多或少不是URL。