Подтвердить что ты не робот

Изменение схемы 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 для этого метода.

4b9b3361

Ответ 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];

[Примечание] Код для обработки портов и других полей для простоты удаления.