Suspender la ejecución de JavaScript en UIWebView

Estoy utilizando con éxito un UIWebView invisible como un motor de ejecución para los fragments de Javascript. Al contrario de lo que sugieren ciertas páginas , no es necesario que sea visible . Si se declara muerto simplemente como

UIWebView* myJSExecutor = [UIWebView new]; 

no solo ejecuta un stringByEvaluatingJavaScriptFromString: lanzado a él, ¡incluso alert() burbujas alert() al escritorio! (No es que sea algo que le gustaría hacer a menudo) Descargo de responsabilidad: probado solo en iOS 5+

Ahora, tengo otro UIWebView normalmente visible con contenido de página web normal, y quiero que suspenda la ejecución de JavaScript: es dejar de actuar en el timer y en los events DOM. Pensé que removeFromSuperview con stopLoading y setting delegate = nil haría el truco. Pero no, tan pronto como vuelvo a agregar la UIWebView a alguna vista visible, puedo ver que los timeres se ejecutaban todo el time.

Entiendo la esquizofrenia de mi requerimiento. Le agradezco que trabaje en segundo plano por un lado (al contrario de algunas observaciones), pero quiero suspenderlo por otro lado. Pero aún me gustaría preguntar si hay alguna forma, quizás incluso privada, de suspenderla. Safari para iOS es capaz de suspender las tabs del browser en segundo plano. Chrome para iOS no puede, lo que puede ser una triste testing negativa 🙁

Si buscas una locura, tengo una idea.

La única manera que sé de pausar JavaScript es mostrar una alerta, confirmar, solicitar o enviar una request de ajax con async=false .

¿La alerta está oculta cuando se oculta el UIWebView? Si es así, puede enviar una alerta cuando desee que se congele. El usuario tendría que descartarlo cuando volviera a mostrar la vista:

 [web stringByEvaluatingJavaScriptFromString:@"alert('Press OK to continue...')"]; 

O tal vez podría descartarlo mediante progtwigción. Estoy seguro de que estarías de acuerdo en que toda esta sugerencia está destinada a problemas, pero es un pensamiento.

¿Necesita una UIWebView completa? De lo contrario, podría invocar JavaScriptCore directamente.

 - (NSString *)runJS:(NSString *)aJSString { JSContextRef ctx = JSGlobalContextCreate(NULL); JSStringRef scriptJS = JSStringCreateWithUTF8CString([aJSString UTF8String]); JSValueRef exception = NULL; JSValueRef result = JSEvaluateScript([self JSContext], scriptJS, NULL, NULL, 0, &exception); JSGlobalContextRelease(ctx); ... 

Esto le daría más control sobre todo el time de ejecución de JS, pero desafortunadamente no he encontrado una API para suspender la ejecución de timeres que no sea la liberación de todo el context.

Para get un ejemplo más completo de cómo usar JavaScriptCore, consulte https://github.com/jfahrenkrug/AddressBookSpy/blob/master/AddressBookSpy/AddressBookSpy/ABSEngine.m

Esto podría sonar obvio, pero si puede editar el JS que está ejecutando en UIWebView, ¿no puede simplemente almacenar una variable global en el JS llamado 'pausa' y comprobar que cuando los timeres están activando?

 var paused = false; var thread = setInterval(function() { if(!paused) { // normal timer checking etc } }, 300); 

A continuación, simplemente dispara [webView stringByEvaluatingJavaScriptFromString: @ "paused = true;"] cuando eliminas la vista web y establece paused = false cuando vuelves a agregarla a la vista.