26

のスキームを変更する簡単な方法はあり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文字列を自分で解析する以外の提案はありますか(これは実行できますが、実行しないようにしたい)?このメソッドにhttpまたはhttpsのいずれかでURLを渡すことができるようにするために何をしますか。

4

6 に答える 6

52

更新された回答

NSURLComponentsここにあなたの友達です。httpこれを使用して、スキームをと交換できますhttps。唯一の注意点はNSURLComponentsRFC3986NSURLを使用することですが、古い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];
于 2013-01-18T05:57:37.957 に答える
29

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/
于 2014-06-17T18:18:05.310 に答える
5

Swift5

extension URL {
    func settingScheme(_ value: String) -> URL {
    let components = NSURLComponents.init(url: self, resolvingAgainstBaseURL: true)
    components?.scheme = value
    return (components?.url!)!
}

}

使用法

if nil == url.scheme { url = url.settingScheme("file") }
于 2020-02-28T15:51:07.547 に答える
1

おそらく、を使用するresourceSpecifierと役立ちます:

return [[[NSURL alloc] initWithString:[NSString stringWithFormat:@"https:%@", [inURL resourceSpecifier]]]];
于 2014-07-02T11:17:44.557 に答える
0
NSString *newUrlString =  [NSString stringWithFormat:@"https://%@%@", 
                          inURL.host, inURL.path];
if (inURL.query) {
    newUrlString = [newUrlString stringByAppendingFormat:@"?%@", inURL.query];
}
return [NSURL URLWithString:newUrl];

[注]ポートおよびその他のフィールド処理に関連するコードは、簡略化のために削除されています。

于 2013-01-18T06:13:15.503 に答える
0

resourceSpecifierNSURL の変数を使用して、このようにしました

迅速

var resourceSpecifier: String? { get } 

目的-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];
    }
于 2014-10-17T10:08:58.843 に答える