2009-11-05 85 views
6

我在写一个Cocoa应用程序,它使用NSURLs - 我需要删除URL的片段部分(#BLAH部分)。从NSURL中删除URL片段

例如: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; 
    } 
} 

回答

7

如何:

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

接近。显然lastPathComponent确实返回片段,并且是一个NSString方法。我已经发布了问题的最终代码。 – pixel 2009-11-05 19:59:45

+0

NSURL也有一个lastPathComponent,它不返回片段,但它的值为10.6+ http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html# // apple_ref/doc/uid/20000301-SW22 – nall 2009-11-05 20:01:20

+0

url.fragment有什么问题? – Sam 2014-01-23 12:24:09

1

这是一个很老的问题,它已经有了答案,但对于另一种简单的选择这我是如何做到的:

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

if there没有片段,urlMinusFragment将相同myURL

+0

不错的简单解决方案,但如果你的iOS/OSX版本支持它,你可能想切换到使用components.firstObject。它比显式访问组件[0]更安全,即使componentsSeparatedByString:*应该总是返回一个非空数组。 – 2015-02-27 18:04:28

0

夫特3.0

此将移除片段

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