Pregunta

Estoy escribiendo una aplicación Cocoa, que utiliza NSURLs -. Necesito quitar la porción fragmento de la URL (la parte #BLAH)

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

He encontrado algo de código en WebCore que parece hacerlo mediante el uso de la funcionalidad CFURL, pero nunca 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 " debido a que la primera línea en urlByRemovingComponent siempre devuelve kCFNotFound

Estoy perplejo. ¿Hay una mejor manera de ir sobre 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;
    }
}
¿Fue útil?

Solución

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

Otros consejos

Esto es muy una vieja cuestión, y que ya ha sido contestada, pero por otra opción sencilla es así como lo hice:

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

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

Swift 3.0

se eliminará el fragmento

if let fragment = url.fragment{
  url = URL(string: url.absoluteString.replacingOccurrences(of: "#\(fragment)", with: "")!
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top