2009-11-05 6 views
6

Tôi đang viết một ứng dụng Cocoa, sử dụng NSURLs - tôi cần xóa phần đoạn của URL (phần #BLAH).Xóa phân đoạn url khỏi NSURL

dụ: http://example.com/#blah nên kết thúc như http://example.com/

Tôi tìm thấy một số mã trong WebCore mà dường như để làm điều đó bằng cách sử dụng chức năng CFURL, nhưng nó không bao giờ tìm thấy phần đoạn trong URL. Tôi đã đóng gói nó trong một thể loại mở rộng:

-(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]; 
} 

này được sử dụng như vậy:

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

không may, NEWURL kết thúc lên được "http://example.com/#blah" vì dòng đầu tiên trong urlByRemovingComponent luôn trả kCFNotFound

Tôi bị bối rối. Có cách nào tốt hơn để thực hiện việc này không?

Mã làm việc, nhờ 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; 
    } 
} 

Trả lời

7

Làm thế nào về điều này:

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

gần. dường như lastPathComponent trả về mảnh, và là một phương thức NSString. Tôi đã đăng mã cuối cùng cho câu hỏi. – pixel

+0

NSURL cũng có phần tử lastPathComponent không trả về đoạn, nhưng nó là 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

+0

có vấn đề gì với url.fragment? – Sam

1

này là khá một câu hỏi cũ, và nó đã được trả lời, nhưng đối với một lựa chọn đơn giản này là cách tôi đã thực hiện:

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

nếu có không có đoạn, urlMinusFragment sẽ được giống như myURL

+0

Giải pháp đơn giản, nhưng bạn có thể muốn chuyển sang sử dụng components.firstObject nếu phiên bản iOS/OSX của bạn hỗ trợ nó. An toàn hơn các thành phần truy cập rõ ràng [0], mặc dù componentsSeparatedByString: * nên * luôn trả về một mảng không trống. –

0

Swift 3.0

này sẽ loại bỏ các mảnh

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