ios - usar - No se puede cambiar UserAgent en UIWebview después de cargar la página
user agent chrome example (1)
La clave predeterminada de usuario UserAgent
es API privada. Por lo tanto, no tiene un comportamiento garantizado. Todas las respuestas serán empíricas.
Dicho esto, parece que la solución correcta es matar y volver a crear su UIWebView
después de cada cambio. UIView
no se ajusta a NSCopying
por lo que deberá hacer algo como:
UIWebView *newWebView = [[UIWebView alloc] initWithFrame:self.webView.frame];
newWebView.delegate = self;
newWebView.scalesPageToFit = YES;
// ... and the autoreseizing mask, etc — no need to do this upon every load
[self.webView.superview insertSubview:newWebView aboveSubview:self.webView];
[self.webView removeFromSuperview];
self.webView = newWebView;
Si eso no funciona, probablemente deba cambiar a un medio documentado de configuración del agente de usuario. Le sugiero que implemente su propio controlador NSURLProtocol
que acepte solicitudes http
y https
que aún no haya visto, modifique el campo del encabezado y las envíe por segunda vez, ese tiempo declinando llevarlos para que caigan al sistema. Será un problema, pero le permitirá cambiar eso, o cualquier otro campo de encabezado, de manera confiable y con efecto inmediato.
Ver el blog de ingeniería de Kifi para un ejemplo.
Mi aplicación IOS tiene varios UIWebView en ella. De vez en cuando, es posible que el usuario deba cambiar de un sitio móvil a un sitio de escritorio de cualquier URL determinada. Estoy utilizando la suplantación de identidad para hacer esto cambiando el UserAgent:
+ (void) startSpoofingUserAgent
{
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"UserAgent" : @"Desktop" }];
[[NSUserDefaults standardUserDefaults] synchronize];
}
También tengo un método que mata la falsificación:
+ (void)stopSpoofingUserAgent
{
NSDictionary *registeredDefaults = [[NSUserDefaults standardUserDefaults] volatileDomainForName:NSRegistrationDomain];
if ([registeredDefaults objectForKey:@"UserAgent"] != nil)
{
NSMutableDictionary *mutableCopy = [NSMutableDictionary dictionaryWithDictionary:registeredDefaults];
[mutableCopy removeObjectForKey:@"UserAgent"];
[[NSUserDefaults standardUserDefaults] setVolatileDomain:mutableCopy forName:NSRegistrationDomain];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
Luego le doy al usuario la capacidad de cambiar de escritorio a móvil y de móvil a escritorio con un botón. Luego recargo la URL con este código:
self.webView.delegate = self;
self.webView.scalesPageToFit = YES;
self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
//Create a URL object.
NSURL *url = [NSURL URLWithString:self.convertedURL];
//URL Request Object
if(self.defaultToDesktopSite)
{
[MINNetworkingUtils startSpoofingUserAgent];
}
else
{
[MINNetworkingUtils stopSpoofingUserAgent];
}
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[self.webView loadRequest:requestObj];
También búfero el estado actual en el que el usuario tiene el UIWebView para que retenga la configuración en todas las instancias. La primera vez que se ejecuta la aplicación, funciona muy bien sin importar en qué estado se encuentre (Escritorio o Móvil).
EL PROBLEMA: El problema es que no puedo cambiar el estado y eso se refleja en la aplicación DESPUÉS de la carga inicial.
Escenario 1:
- El usuario ejecuta la aplicación
- UIWebView está configurado para falsificar UserAgent, lo que obliga a UIWebView a cargar el sitio de escritorio
- ¡FUNCIONA GENIAL!
Escenario 2:
- El usuario ejecuta la aplicación
- UIWebView está configurado para NO falsificar UserAgent, lo que permite que UIWebView cargue un sitio móvil si está disponible
- ¡FUNCIONA GENIAL!
Escenario 3:
- El usuario ejecuta la aplicación
- UIWebView está configurado para falsificar UserAgent
- El sitio aparece con el sitio de escritorio (como se esperaba)
- El usuario cambia el estado a "Móvil" seleccionando el botón
- La aplicación vuelve a cargar el UIWebView utilizando el código anterior (que UN-falsifica la conexión)
- No funciona
- El UIWebView se vuelve a cargar pero sigue utilizando el sitio "Escritorio" y NO el sitio móvil
- (ESTE ESCENARIO funciona de la misma manera si se invierte. En otras palabras, si se supone que UIWebView nos vendrá como "Mobile" la primera vez. Funciona hasta que intento cambiarlo y volver a cargarlo.)
Escenario 4:
- Siga los mismos pasos que en el Escenario 3 PERO descargue la aplicación de la memoria y vuelva a cargarla
- Desde que registré el estado, cuando aparece la aplicación, el UIWebView cree que debe aparecer en el modo "Móvil" (porque el usuario lo cambió cuando ejecutó la aplicación la última vez).
- ¡FUNCIONA DE NUEVO! El UIWebView aparece en modo "Mobile".
Lo que parece estar sucediendo, es que el UIWebView está almacenando algo en algún lugar y no me permite volver a cargar el UIWebView con un spoofing diferente. Si la aplicación se descarga y se vuelve a cargar, UIWebView funciona como se esperaba.
He intentado hacer lo siguiente para forzar que UIWebView NO almacene en búfer nada y no he tenido éxito:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
... reload URL
self.convertedPageURL = [NSString stringWithFormat:@"%@?t=%@", self.convertedPageURL, randomString];
... reload URL
Como dije antes, no puedo hacer que UIWebView cambie de Escritorio a Móvil o de Móvil a Escritorio SIN descargar la aplicación y volver a cargarla.
¡¡¡AYUDA!!!
EDITAR
Este es el código que estaba usando para obtener el valor actual. Una vez que he llamado a esta línea de código, ya no puedo cambiar el UserAgent:
defaultUserAgentString = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];