2009-11-05 9 views
6

Estoy escribiendo una aplicación Cocoa, que usa NSURLs - Necesito eliminar la parte del fragmento de la URL (la parte #BLAH).Eliminando fragmento de url de NSURL

ejemplo: http://example.com/#blah debería terminar como http://example.com/

me encontré con algo de código en WebCore que parece hacerlo mediante el uso de la funcionalidad CFURL, pero nunca se encuentra la porción fragmento de la URL. He encapsulado en una categoría extensión:

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

Esto se utiliza como tal:

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

por desgracia, NEWURL termina siendo "http://example.com/#blah" porque la primera línea en urlByRemovingComponent siempre devuelve kCFNotFound

Estoy perplejo. ¿Hay una mejor manera de resolver esto?

Código de Trabajo, gracias a 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; 
    } 
} 

Respuesta

7

¿Qué tal esto:

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

cerca. aparentemente lastPathComponent devuelve el fragmento, y es un método NSString. He publicado el código final de la pregunta. – pixel

+0

NSURL también tiene un lastPathComponent que no devuelve el fragmento, pero es 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

¿Qué pasa con url.fragment? – Sam

1

Esto es muy una vieja cuestión, y que ya ha sido contestada, pero por otra opción sencilla esta es cómo lo hice:

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

si hay hay fragmento, urlMinusFragment será el mismo que myURL

+0

Buena solución simple, pero es posible que desee cambiar a usar components.firstObject si su versión iOS/OSX lo admite. Es más seguro que acceder explícitamente a los componentes [0], aunque los componentesSeparatedByString: * deben * siempre devolver una matriz no vacía. –

0

Swift 3,0

se eliminará el fragmento

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