从 NSURL 中删除 url 片段

发布于 2024-08-11 00:30:14 字数 2353 浏览 9 评论 0原文

我正在编写一个使用 NSURL 的 Cocoa 应用程序——我需要删除 URL 的片段部分(#BLAH 部分)。

例如: http://example.com/#blah 应该最终为 http://example.com/

我在 WebCore 中发现了一些代码,这些代码似乎是通过使用 CFURL 功能来实现的,但它从未在 URL 中找到片段部分。我将它封装在一个扩展类别中:

-(NSURL *)urlByRemovingComponent:(CFURLComponentType)component {
    CFRange fragRg = CFURLGetByteRangeForComponent((CFURLRef)self, component, NULL);
    // Check to see if a fragment exists before decomposing the URL.
    if (fragRg.location == kCFNotFound)
        return self;

    UInt8 *urlBytes, buffer[2048];
    CFIndex numBytes = CFURLGetBytes((CFURLRef)self, buffer, 2048);
    if (numBytes == -1) {
        numBytes = CFURLGetBytes((CFURLRef)self, NULL, 0);
        urlBytes = (UInt8 *)(malloc(numBytes));
        CFURLGetBytes((CFURLRef)self, urlBytes, numBytes);
    } else
        urlBytes = buffer;

    NSURL *result = (NSURL *)CFMakeCollectable(CFURLCreateWithBytes(NULL, urlBytes, fragRg.location - 1, kCFStringEncodingUTF8, NULL));
    if (!result)
        result = (NSURL *)CFMakeCollectable(CFURLCreateWithBytes(NULL, urlBytes, fragRg.location - 1, kCFStringEncodingISOLatin1, NULL));

    if (urlBytes != buffer) free(urlBytes);
    return result ? [result autorelease] : self;
}
-(NSURL *)urlByRemovingFragment {
    return [self urlByRemovingComponent:kCFURLComponentFragment];
}

这就是这样使用的:

NSURL *newUrl = [[NSURL URLWithString:@"http://example.com/#blah"] urlByRemovingFragment];

不幸的是,newUrl 最终成为“http://example .com/#blah”因为 urlByRemovingComponent 中的第一行总是返回 kCFNotFound

我被难住了。有更好的方法来解决这个问题吗?

工作代码,感谢nall

-(NSURL *)urlByRemovingFragment {
    NSString *urlString = [self absoluteString];
    // Find that last component in the string from the end to make sure to get the last one
    NSRange fragmentRange = [urlString rangeOfString:@"#" options:NSBackwardsSearch];
    if (fragmentRange.location != NSNotFound) {
        // Chop the fragment.
        NSString* newURLString = [urlString substringToIndex:fragmentRange.location];
        return [NSURL URLWithString:newURLString];
    } else {
        return self;
    }
}

I'm writing a Cocoa application, which uses NSURLs -- I need to remove the fragment portion of the URL (the #BLAH part).

example: http://example.com/#blah should end up as http://example.com/

I found some code in WebCore that seems to do it by using CFURL functionality, but it never finds the fragment portion in the URL. I've encapsulated it in a extension category:

-(NSURL *)urlByRemovingComponent:(CFURLComponentType)component {
    CFRange fragRg = CFURLGetByteRangeForComponent((CFURLRef)self, component, NULL);
    // Check to see if a fragment exists before decomposing the URL.
    if (fragRg.location == kCFNotFound)
        return self;

    UInt8 *urlBytes, buffer[2048];
    CFIndex numBytes = CFURLGetBytes((CFURLRef)self, buffer, 2048);
    if (numBytes == -1) {
        numBytes = CFURLGetBytes((CFURLRef)self, NULL, 0);
        urlBytes = (UInt8 *)(malloc(numBytes));
        CFURLGetBytes((CFURLRef)self, urlBytes, numBytes);
    } else
        urlBytes = buffer;

    NSURL *result = (NSURL *)CFMakeCollectable(CFURLCreateWithBytes(NULL, urlBytes, fragRg.location - 1, kCFStringEncodingUTF8, NULL));
    if (!result)
        result = (NSURL *)CFMakeCollectable(CFURLCreateWithBytes(NULL, urlBytes, fragRg.location - 1, kCFStringEncodingISOLatin1, NULL));

    if (urlBytes != buffer) free(urlBytes);
    return result ? [result autorelease] : self;
}
-(NSURL *)urlByRemovingFragment {
    return [self urlByRemovingComponent:kCFURLComponentFragment];
}

This is used as such:

NSURL *newUrl = [[NSURL URLWithString:@"http://example.com/#blah"] urlByRemovingFragment];

unfortunately, newUrl ends up being "http://example.com/#blah" because the first line in urlByRemovingComponent always returns kCFNotFound

I'm stumped. Is there a better way of going about this?

Working Code, thanks to nall

-(NSURL *)urlByRemovingFragment {
    NSString *urlString = [self absoluteString];
    // Find that last component in the string from the end to make sure to get the last one
    NSRange fragmentRange = [urlString rangeOfString:@"#" options:NSBackwardsSearch];
    if (fragmentRange.location != NSNotFound) {
        // Chop the fragment.
        NSString* newURLString = [urlString substringToIndex:fragmentRange.location];
        return [NSURL URLWithString:newURLString];
    } else {
        return self;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷鸟归林 2024-08-18 00:30:14

这个怎么样:

NSString* s = @"http://www.somewhere.org/foo/bar.html/#label";
NSURL* u = [NSURL URLWithString:s];

// Get the last path component from the URL. This doesn't include
// any fragment.
NSString* lastComponent = [u lastPathComponent];

// Find that last component in the string from the end to make sure
// to get the last one
NSRange fragmentRange = [s rangeOfString:lastComponent
                                 options:NSBackwardsSearch];

// Chop the fragment.
NSString* newURLString = [s substringToIndex:fragmentRange.location + fragmentRange.length];

NSLog(@"%@", s);
NSLog(@"%@", newURLString);

How about this:

NSString* s = @"http://www.somewhere.org/foo/bar.html/#label";
NSURL* u = [NSURL URLWithString:s];

// Get the last path component from the URL. This doesn't include
// any fragment.
NSString* lastComponent = [u lastPathComponent];

// Find that last component in the string from the end to make sure
// to get the last one
NSRange fragmentRange = [s rangeOfString:lastComponent
                                 options:NSBackwardsSearch];

// Chop the fragment.
NSString* newURLString = [s substringToIndex:fragmentRange.location + fragmentRange.length];

NSLog(@"%@", s);
NSLog(@"%@", newURLString);
无悔心 2024-08-18 00:30:14

这是一个相当老的问题,它已经得到了回答,但对于另一个简单的选项,我就是这样做的:

 NSString* urlAsString = [myURL absoluteString];
 NSArray* components = [urlAsString componentsSeparatedByString:@"#"];
 NSURL* myURLminusFragment = [NSURL URLWithString: components[0]];

如果没有片段, urlMinusFragment 将与 myURL 相同

This is quite an old question, and it has already been answered, but for another simple option this is how I did it:

 NSString* urlAsString = [myURL absoluteString];
 NSArray* components = [urlAsString componentsSeparatedByString:@"#"];
 NSURL* myURLminusFragment = [NSURL URLWithString: components[0]];

if there is no fragment, urlMinusFragment will be the same as myURL

回眸一遍 2024-08-18 00:30:14

Swift 3.0

这将删除片段

if let fragment = url.fragment{
  url = URL(string: url.absoluteString.replacingOccurrences(of: "#\(fragment)", with: "")!
}

Swift 3.0

this will remove the fragment

if let fragment = url.fragment{
  url = URL(string: url.absoluteString.replacingOccurrences(of: "#\(fragment)", with: "")!
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文