2011-02-11 8 views
21

Resumen del problema: Al explorar sitios que no están en inglés y que no especifican explícitamente la codificación de caracteres correcta con UIWebView en el iOS, la página no se puede mostrar correctamente.¿Cómo cambiar la codificación de caracteres en UIWebView?

explicación detallada: Como el método loadRequest: en UIWebView utilizará la codificación especificada en la cabecera charset enviado desde el servidor web o el juego de caracteres escrita en la etiqueta meta HTML, y por defecto a iso-8859-1 (bueno, No estoy muy seguro de esto) cuando no se especifica el juego de caracteres, lo que hace que los sitios que no están en inglés no se puedan mostrar correctamente.

He intentado con Google una forma de cambiar el conjunto de caracteres que usa UIWebView, pero la única forma es usar el método loadData:MIMEType:textEncodingName:baseURL: para especificar el nombre de la codificación.

Sin embargo, no es una buena idea usar loadData:MIMEType:textEncodingName:baseURL: + NSURLConnection en lugar de loadRequest:, porque UIWebView no llamará al método delegado webView:shouldStartLoadWithRequest:navigationType: para marcos, e incluso si encontramos una manera para ser notificado cuando UIWebView cargar un marco, no podemos llamar al loadData:MIMEType:textEncodingName:baseURL: para cargar el contenido del marco, porque cargará el marco como página externa si lo hacemos.

Además, he intentado utilizar un hack de JavaScript, pero parece que la propiedad es de solo lectura y no se puede cambiar.

[webView stringByEvaluatingJavaScriptFromString:@"document.characterSet='utf-8';"]; 

Otra solución es la inserción de una etiqueta meta con respecto al HTML, y pedir UIWebView para cargar el código modificado, pero el problema del marco mencionado anteriormente también se aplican aquí.

<meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 

Pregunta: ¿Hay alguna solución mejor que puede cambiar la codificación de caracteres en una página web cargada en UIWebView y manejar adecuadamente los marcos?

+1

indique su URL aquí, entonces me permiten comprobar. –

+0

¿tiene usted control sobre la página web o el servidor? – Magnus

+0

@magnus que sería demasiado fácil;) – Till

Respuesta

6

Puede hacerlo cargando manualmente el HTML, modificándolo y luego cargando el contenido modificado en UIWebView.

  • cargar manualmente el código HTML de la página que no incluye la etiqueta meta, en una cadena (por ejemplo, utilizar NSURLConnection)
  • usando manipulación de cadenas, insertar su etiqueta meta codificación adecuada en el HTML cargada manualmente
  • establece el código HTML en su vista web de la cadena modificada usando loadHTMLString:

Ahora, esto va a funcionar bien para una página web que contiene enlaces. Si contiene enlaces, descubrirá que después de que hacen clic en un enlace, la nueva página no tendrá su modificación en su lugar. Por lo tanto, deberá interceptar manualmente todos los clics. He aquí cómo usted puede hacer eso:

+0

¿Recibirá la devolución de llamada del delegado para los marcos también? – Till

+0

De acuerdo con la documentación, sí. http://developer.apple.com/library/IOs/#documentation/UIKit/Reference/UIWebViewDelegate_Protocol/Reference/Reference.html –

+0

¿cómo "modificó el contenido antes de configurarlo en UIWebView"? loadHTMLString no se puede cargar en un marco específico, pero siempre el documento raíz. – howanghk

1

Esto es lo que hago,
averiguar primero si se trata de texto, si lo es, tengo los datos, establezca la codificación y cargarlo usando UIWebView>loadData:MIMEType:textEncodingName:baseURL.
Aquí está el código:

  1. Consigue el MIMEType el envío de una petición HEAD síncrona.
    Queremos utilizar una solicitud HEAD HTTP que generally is fast enough.
    Y queremos hacer la solicitud sincrónicamente por dos razones, necesitamos que el resultado de la solicitud continúe y queremos evitar problemas de solicitud concurrente like this.

    
    NSMutableURLRequest *headRequest = [NSMutableURLRequest requestWithURL:url]; 
    [headRequest setHTTPMethod:@"HEAD"]; 
    NSHTTPURLResponse *headResponse; 
    NSError *error = nil; 
    [NSURLConnection sendSynchronousRequest:headRequest 
             returningResponse:&headResponse 
                error:&error]; 
    if (error != nil) { 
        NSLog(@"loadURLWithString %@",[error localizedDescription]); 
    } 
    NSString *mimeType = [headResponse MIMEType]; 
    


  2. A continuación, si se trata de texto, cargarlo con UIWebView>loadData:MIMEType:textEncodingName:baseURL
    Para mantener la aplicación sensibles, se recomienda poner el siguiente código en un bloque y ejecutarlo dentro de una GCD queue.

    
    if([mimeType rangeOfString:@"text" 
            options:NSCaseInsensitiveSearch].location == 0) { 
    
        [wview loadData:[NSData dataWithContentsOfURL: url] MIMEType:mimeType 
         textEncodingName:encoding baseURL:nil]; 
    
+0

Gracias por responder. Sin embargo, esto solo funcionará en el documento raíz. Si hay iframes o frameset, no funcionará. Lea el cuarto párrafo para obtener más detalles sobre por qué no resolvió el problema. – howanghk

+0

Además, el uso de solicitud síncrona y - [NSString initWithContentsOfURL] son ​​altamente __discouraged__ ya que bloquearía el hilo principal, o tiene que enviarlos a un hilo de fondo. El hilo de desove es una operación bastante costosa y, por lo tanto, la solicitud asincrónica es un mejor enfoque. – howanghk

+0

Actualizó la respuesta. No he intentado para documentos con iframes o conjuntos de marcos pero, este enfoque fue útil para mí y podría ser útil para alguien más. En cuanto al segundo comentario, estoy usando GCD y bloques para evitar bloquear el hilo principal o los hilos de desove. – user454322

Cuestiones relacionadas