Изменение схемы NSURL
Есть ли простой способ изменить схему NSURL
? Я понимаю, что NSURL
является неизменным. Моя цель - изменить схему URL-адреса на "https", если привязан к Security.framework
, и "http", если структура не связана. Я знаю, как определить, связана ли структура.
Этот код прекрасно работает, если у URL-адреса нет параметров (например, "param1 = foo & param2 = bar" ):
+(NSURL*)adjustURL:(NSURL*)inURL toSecureConnection:(BOOL)inUseSecure {
if ( inUseSecure ) {
return [[[NSURL alloc] initWithScheme:@"https" host:[inURL host] path:[inURL path]] autorelease];
}
else {
return [[[NSURL alloc] initWithScheme:@"http" host:[inURL host] path:[inURL path]] autorelease];
}
}
Но если URL-адрес имеет параметры, [inURL path]
опускает их.
Любые предложения, не содержащие синтаксический разбор строки URL (что я могу сделать, но я хочу попробовать не делать)? Я делаю то, что можно передавать URL-адресам с помощью http или https для этого метода.
Ответы
Ответ 1
Обновленный ответ
NSURLComponents
- ваш друг здесь. Вы можете использовать его для замены схемы http
для https
. Единственное предостережение: NSURLComponents
использует RFC 3986, тогда как NSURL
использует более старые RFC 1738 и 1808, поэтому есть некоторые различия в поведении в случаях краев, но вы вряд ли попадете в эти случаи (и NSURLComponents
имеет лучшее поведение в любом случае).
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
components.scheme = inUseSecure ? @"https" : @"http";
return components.URL;
Оригинальный ответ
Почему бы не просто немного манипулировать строкой?
NSString *str = [url absoluteString];
NSInteger colon = [str rangeOfString:@":"].location;
if (colon != NSNotFound) { // wtf how would it be missing
str = [str substringFromIndex:colon]; // strip off existing scheme
if (inUseSecure) {
str = [@"https" stringByAppendingString:str];
} else {
str = [@"http" stringByAppendingString:str];
}
}
return [NSURL URLWithString:str];
Ответ 2
Если вы используете iOS 7 и более поздние версии, вы можете использовать NSURLComponents
, как показано здесь
NSURLComponents *components = [NSURLComponents new];
components.scheme = @"http";
components.host = @"joris.kluivers.nl";
components.path = @"/blog/2013/10/17/nsurlcomponents/";
NSURL *url = [components URL];
// url now equals:
// http://joris.kluivers.nl/blog/2013/10/17/nsurlcomponents/
Ответ 3
Возможно, использование resourceSpecifier
поможет:
return [[[NSURL alloc] initWithString:[NSString stringWithFormat:@"https:%@", [inURL resourceSpecifier]]]];
Ответ 4
Я сделал это так, используя переменную resourceSpecifier
в NSURL
SWIFT
var resourceSpecifier: String? { get }
OBJECTIVE-C
@property(readonly, copy) NSString *resourceSpecifier Discussion
Это свойство содержит спецификатор ресурса. Например, в URL http://www.example.com/index.html?key1=value1#jumplink спецификатор ресурса -//www.example.com/index.html?key1=value1# jumplink (все после двоеточия).
-(NSURL*) URLByReplacingScheme
{
NSString *newUrlString = kHttpsScheme;
if([self.scheme isEqualToString:kEmbeddedScheme])
newUrlString = kHttpScheme;
newUrlString = [newUrlString stringByAppendingString:[NSString stringWithFormat:@":%@", self.resourceSpecifier]];
return [NSURL URLWithString:newUrlString];
}
Ответ 5
NSString *newUrlString = [NSString stringWithFormat:@"https://%@%@",
inURL.host, inURL.path];
if (inURL.query) {
newUrlString = [newUrlString stringByAppendingFormat:@"?%@", inURL.query];
}
return [NSURL URLWithString:newUrl];
[Примечание]
Код для обработки портов и других полей для простоты удаления.