Change a NSURL's scheme

前端 未结 6 2005
無奈伤痛
無奈伤痛 2021-02-02 09:34

Is there an easy way to change the scheme of a NSURL? I do realize that NSURL is immutable. My goal is to change the scheme of an URL to \"https\" if t

相关标签:
6条回答
  • 2021-02-02 10:20

    Perhaps using the resourceSpecifier would help:

    return [[[NSURL alloc] initWithString:[NSString stringWithFormat:@"https:%@", [inURL resourceSpecifier]]]];
    
    0 讨论(0)
  • 2021-02-02 10:21

    Updated answer

    NSURLComponents is your friend here. You can use it to swap out the http scheme for https. The only caveat is NSURLComponents uses RFC 3986 whereas NSURL uses the older RFCs 1738 and 1808, so there is some behavior differences in edge cases, but you're extremely unlikely to hit those cases (and NSURLComponents has the better behavior anyway).

    NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
    components.scheme = inUseSecure ? @"https" : @"http";
    return components.URL;
    

    Original answer

    Why not just do a bit of string manipulation?

    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];
    
    0 讨论(0)
  • 2021-02-02 10:27

    I did it like this, using a variable resourceSpecifier in NSURL

    SWIFT

    var resourceSpecifier: String? { get } 
    

    OBJECTIVE-C

    @property(readonly, copy) NSString *resourceSpecifier Discussion 
    

    This property contains the resource specifier. For example, in the URL http://www.example.com/index.html?key1=value1#jumplink, the resource specifier is //www.example.com/index.html?key1=value1#jumplink (everything after the colon).

      -(NSURL*) URLByReplacingScheme
        {
            NSString *newUrlString = kHttpsScheme;
    
            if([self.scheme isEqualToString:kEmbeddedScheme])
                newUrlString = kHttpScheme;
    
            newUrlString = [newUrlString stringByAppendingString:[NSString stringWithFormat:@":%@", self.resourceSpecifier]];
    
            return [NSURL URLWithString:newUrlString];
        }
    
    0 讨论(0)
  • 2021-02-02 10:27
    NSString *newUrlString =  [NSString stringWithFormat:@"https://%@%@", 
                              inURL.host, inURL.path];
    if (inURL.query) {
        newUrlString = [newUrlString stringByAppendingFormat:@"?%@", inURL.query];
    }
    return [NSURL URLWithString:newUrl];
    

    [NOTE] Code related to port and other fields handling are removal for simplicity.

    0 讨论(0)
  • 2021-02-02 10:33

    If you are using iOS 7 and later, you can use NSURLComponents, as show here

    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/
    
    0 讨论(0)
  • 2021-02-02 10:33

    Swift5

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

    }

    Usage

    if nil == url.scheme { url = url.settingScheme("file") }
    
    0 讨论(0)
提交回复
热议问题