Pregunta

En mi aplicación iOS, estoy usando un UiWebView y un protocolo personalizado (con mi propia implementación de NsurlProtocol). He sido bastante cuidadoso al asegurarme de que cada vez que cargue una URL, cargue algo como esto en mi uiwebview:

myprotocol: // myserver/mypath

Y en mi implementación de NsurlProtocol, tomo una copia mutable de la NsurlRequest, la convierto la URL a HTTP: y la envío a mi servidor.

Todo funciona para HTTP Obtener solicitudes. El problema que encuentro es con las solicitudes posteriores. Parece que el UIWebView no codifica correctamente los datos de formulario en el cuerpo httpe si la solicitud usa mi protocolo personalizado.

Una solución al día, ya que estoy usando HTTPS para mis solicitudes de servidor, es que registro mi controlador de protocolo para interceptar http: en lugar de myprotocol: y puedo convertir todas las llamadas a https: esta otra pregunta, aquí, me señaló hacia esa solución:

Pero me pregunto si hay alguna alternativa y/o una mejor manera de lograr lo que quiero.

¿Fue útil?

Solución

En lugar de tratar de usar solicitudes de publicación, un trabajo es continuar usando las solicitudes GET para myprotocol:// URLS, pero transformarlas en tu NSURLProtocol implementación a un http:// y Publique solicitud a su servidor utilizando la cadena de consulta de solicitud como el cuerpo de la publicación.

La preocupación por el uso de solicitudes para obtener grandes cantidades de datos es que en algún lugar a lo largo de la cadena de solicitudes, la línea de solicitud podría truncarse. Sin embargo, esto parece no ser un problema, con protocolos implementados localmente.

Escribí una aplicación de prueba de Cordova corta para experimentar y descubrí que pude enviar un poco más de 1 MIB de datos sin problemas para el servicio de eco de la solicitud HTTP. http://http-eco.jgate.de/

Aquí está mi startLoading implementación:

- (void)startLoading {
    NSURL *url = [[self request] URL];
    NSString *query = [url query];
    // Create a copy of `url` without the query string.
    url = [[[NSURL alloc] initWithScheme:@"http" host:@"http-echo.jgate.de" path:[url path]] autorelease];
    NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:url];
    [newRequest setHTTPMethod:@"POST"];
    [newRequest setAllHTTPHeaderFields:[[self request] allHTTPHeaderFields]];
    [newRequest addValue:@"close" forHTTPHeaderField:@"Connection"];
    [newRequest addValue:@"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    [newRequest setHTTPBody:[query dataUsingEncoding:NSUTF8StringEncoding]];
    urlConnection = [[NSURLConnection alloc] initWithRequest:newRequest delegate:self];
    if (urlConnection) {
        receivedData = [[NSMutableData data] retain];
    }
}

Luego implementé el NSURLConnection Métodos de protocolo para reenviar al apropiado NSURLProtocolClient método, pero construir los datos de respuesta en el caso de Transfer-Encoding:chunked (como es el caso de las respuestas de http://http-eco.jgate.de/).

Otros consejos

Lamentablemente se ve así http: y https: Las solicitudes de esquema se manejan ligeramente de manera ligeramente diferente a otros esquemas (incluidas las personalizaciones) por el marco de la base. Obviamente HTTPBody y HTTPBodyStream Llamadas a relevantes NSURLRequest devoluciones siempre nil para los anteriores. Esto ya se decide la llamada previa de [NSURLProtocol canInitWithRequest] Por lo tanto, personalizado NSURLProtocol La implementación no tiene forma de influir en eso (es demasiado tarde).

Parece que diferente NSURLRequest la clase se usa para http: y https: que 'un predeterminado'. La implementación predeterminada de Gnustep de esta clase devuelve siempre nil de HTTPBody y HTTPBodyStream llamadas. Por lo tanto, implementaciones particulares (por ejemplo, una en PhoneGap, probablemente parte del marco de Foundation) elija NSURLRequest-Tipo de clase basado en el esquema de consultas previas con eso con NSURLProtocol. Para esquemas personalizados, obtienes NSURLRequest que regresa nil para ambos HTTPBody y HTTPBodyStream que desactiva efectivamente el uso del método post (y otros métodos con el cuerpo) en el manejador de esquema URI personalizado.

Tal vez hay una forma de influir en la decisión de cuál NSURLRequest La clase realmente se usa, pero actualmente es desconocida para mí.

Como solución alternativa, aún puedes usar http: o https: esquema y decidir en [NSURLProtocol canInitWithRequest] Basado en otros criterios (por ejemplo, nombre de host).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top