Pregunta

puedo reemplazar NSURLProtocol y necesidad de respuesta HTTP de retorno con statusCode específica. NSHTTPURLResponse no tiene statusCode organismo, así que traté de reemplazar con:

@interface MyHTTPURLResponse : NSHTTPURLResponse {} 

@implementation MyHTTPURLResponse

    - (NSInteger)statusCode {
        return 200; //stub code
    }
@end

método reemplazado startLoading de NSURLProtocol se ve así:

-(void)startLoading
{   
   NSString *url = [[[self request] URL] absoluteString];
   if([url isEqualToString:SPECIFIC_URL]){
       MyURLResponse *response = [[MyURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://fakeUrl"]
       MIMEType:@"text/plain"
       expectedContentLength:0  textEncodingName:nil];

       [[self client] URLProtocol:self     
            didReceiveResponse:response 
            cacheStoragePolicy:NSURLCacheStorageNotAllowed];

       [[self client] URLProtocol:self didLoadData:[@"Fake response string"
            dataUsingEncoding:NSASCIIStringEncoding]];

       [[self client] URLProtocolDidFinishLoading:self];                

       [response release];

    }
    else{   
        [NSURLConnection connectionWithRequest:[self request] delegate:self];   
    }
}

Sin embargo, este enfoque no funciona, la respuesta creada en NSURLProtocol está siempre con statusCode = 0 en la página web. Al mismo tiempo las respuestas que se devuelven de la red por NSURLConnection tener StatusCodes esperados normales.

Puede alguien por favor ayuda con ideas de cómo configurar statusCode explícitamente NSURLResponse creado? Gracias.

¿Fue útil?

Solución

He implementado método personalizado de inicio utilizando el código siguiente:

    NSInteger statusCode = 200;
    id headerFields = nil;
    double requestTime = 1;

    SEL selector = NSSelectorFromString(@"initWithURL:statusCode:headerFields:requestTime:");
    NSMethodSignature *signature = [self methodSignatureForSelector:selector];

    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:signature];
    [inv setTarget:self];
    [inv setSelector:selector];
    [inv setArgument:&URL atIndex:2];
    [inv setArgument:&statusCode atIndex:3];
    [inv setArgument:&headerFields atIndex:4];
    [inv setArgument:&requestTime atIndex:5];

    [inv invoke];

Otros consejos

Aquí es una solución mejor.

En iOS 5.0 y hasta que no tienen que hacer nada loco con APIs privadas o NSHTTPURLResponse sobrecargar más.

Para crear un NSHTTPUTLResponse con su propio código de estado y cabeceras, ahora puede simplemente usar:

initWithURL:statusCode:HTTPVersion:headerFields:

Lo que no se documenta en la documentación generada pero es realmente presente en el archivo de cabecera NSURLResponse.h y también marcado como una API pública que está disponible en OS X 10.7 y el IOS 5.0.

También tenga en cuenta que si está utilizando el truco NSURLProtocol para realizar llamadas desde un XMLHTTPRequest UIWebView, que se necesita para establecer la cabecera Access-Control-Allow-Origin adecuadamente. De lo contrario, las patadas de seguridad en XMLHTTPRequest y aunque su NSURLProtocol va a recibir y manejar la petición, que no será capaz de enviar una copia de la respuesta.

U obtener el código de estado de sólo el URLResponse. Ninguna necesidad de fijar explícitamente: -

    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&requestError];  

    NSString *responseString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] autorelease];
    NSLog(@"ResponseString:%@",responseString);

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    int statusCode = [httpResponse statusCode];
    NSLog(@"%d",statusCode);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top