【问题标题】:Removing url fragment from NSURL从 NSURL 中删除 url 片段
【发布时间】:2010-12-13 13:34:55
【问题描述】:

我正在编写一个使用 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;
    }
}

【问题讨论】:

    标签: cocoa nsurl


    【解决方案1】:

    这个怎么样:

    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);
    

    【讨论】:

    • 关闭。显然 lastPathComponent 确实返回了片段,并且是一个 NSString 方法。我已将最终代码发布到问题中。
    • NSURL 也有一个不返回片段的 lastPathComponent,但它是 10.6+ developer.apple.com/mac/library/documentation/Cocoa/Reference/…
    • 如果最后一个路径组件在片段中(例如,某些 Web 应用程序具有的丰富片段 URL)怎么办?
    【解决方案2】:

    这是一个很老的问题,已经回答过了,但是对于另一个简单的选项,我就是这样做的:

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

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

    【讨论】:

    • 不错的简单解决方案,但如果您的 iOS/OSX 版本支持,您可能希望切换到使用 components.firstObject。它比显式访问 components[0] 更安全,即使 componentsSeparatedByString: should 总是返回一个非空数组。
    【解决方案3】:

    斯威夫特 3.0

    这将删除片段

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 1970-01-01
      相关资源
      最近更新 更多