2009-11-05 58 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: "")! 
}