2010-05-29 8 views
8

Próbuję przekazać wiele rzeczy ze strony internetowej wewnątrz UIWebView z powrotem do mojej aplikacji iPhone za pomocą metody shouldStartLoadWithRequest z UIWebView.Triggering shouldStartLoadWithRequest z wieloma window.location.href połączeń

Zasadniczo moja strona internetowa wywołuje window.location.href = "command: // foo = bar" i jestem w stanie przechwycić to w mojej aplikacji bez problemu. Teraz, jeśli utworzę pętlę i wykonam wiele wywołań window.location.href na raz, wtedy powinienem wywołać tylko StartStartLoadWithRequest, a wywołanie, które otrzyma, jest ostatnim wywołaniem window.location.href na końcu pętli.

To samo dzieje się z widokiem na Androida, tylko ostatni window.location.href zostaje przetworzony.

+0

Znalazłem sprytne rozwiązanie. Dynamicznie utwórz element iframe dla każdego polecenia i ustaw jego src na "command: // foo = bar", możesz odpalić to wielokrotnie w pętli i shouldStartLoadWithRequest zostanie wywołany za każdym razem! Teraz, aby dowiedzieć się, jak to zoptymalizować. Nie sądzę, że dobrze byłoby stworzyć tysiące elementów iframe (nawet jeśli są one ukryte). Wszelkie sugestie na ten temat? – AlBeebe

+0

Chciałbym spróbować zoptymalizować każde połączenie z lokalizacją. Jeśli możesz wysyłać tylko 60-minutowe połączenia, a następnie upewnij się, że wszystkie połączenia są blokowane za pomocą wystarczającej liczby zmiennych i fragmentów zapytań, aby obsłużyć wiele poleceń na każde połączenie. Możesz również sprawdzić wkWebView: http://nshipster.com/wkwebkit/ automatyzuje on znaczną część tego procesu i jest bardziej niezawodny. – newshorts

Odpowiedz

39
iFrame = document.createElement("IFRAME"); 
iFrame.setAttribute("src", "command://foo=bar"); 
document.body.appendChild(iFrame); 
iFrame.parentNode.removeChild(iFrame); 
iFrame = null; 

Więc ta tworzy iframe, ustawia źródło do poleceń Im próbuje przejść do aplikacji, a następnie jak najszybciej jej dołączane do shouldStartLoadWithRequest ciała jest wywoływana, następnie usuwamy iframe z organizmu, a ustaw go na wartość null, aby zwolnić pamięć.

Testowałem również to na webview Android za pomocą shouldOverrideUrlLoading i również działało poprawnie!

+3

To rozwiązanie jest ohydnie brzydkie, ale wydaje się najmniej ohydnie brzydkim rozwiązaniem. Wygląda na to, że JavaScript "optymalizuje się", ignorując wywołania window.location, które są następnie zastępowane przez inne wywołania window.location. Dziękuję za uratowanie mnie od bardzo bolesnej sesji debugowania! – Arkaaito

+0

@Arkaaito +1 dla ohydnie brzydkiego, całkowicie zgadzam się z – AlBeebe

+4

Chcę śledzić, ponieważ napisałem to 2 lata temu. Napisałem aplikację na Androida i iPhone'a, która była w zasadzie widokiem internetowym zawiniętym w natywną aplikację. Użyłem tego rozwiązania, aby móc komunikować się ze strony internetowej do rodzimej aplikacji i działało bezbłędnie przez ostatnie 2 lata. Miałem ponad 500 000 pobrań aplikacji. – AlBeebe

0

Nie, zmiana adresu URL elementu iframe nie uruchomi się, jeśli nie zmieni sięWersjaBlokada, co najmniej nie ma w systemie Android 2.2.

3

Uderzyłem również ten problem i oto moje rozwiązanie, które działa dla mnie. Wszystkie moje funkcje JavaScript używają tej funkcji __js2oc (msg) do przekazywania danych i zdarzeń do obiektu C za pomocą shouldStartLoadWithRequest: P.S. zamień "polecenie:" na używany przez ciebie "appname:".

/* iPhone JS2Objective-C bridge interface */ 
var __js2oc_wait = 300; // min delay between calls in milliseconds 
var __prev_t = 0; 
function __js2oc(m) { 
    // It's a VERY NARROW Bridge so traffic must be throttled 
    var __now = new Date(); 
    var __curr_t = __now.getTime(); 
    var __diff_t = __curr_t - __prev_t; 
    if (__diff_t > __js2oc_wait) { 
    __prev_t = __curr_t; 
    window.location.href = "command:" + m; 
    } else { 
    __prev_t = __curr_t + __js2oc_wait - __diff_t; 
    setTimeout(function() { 
     window.location.href = "command:" + m; 
    }, (__js2oc_wait - __diff_t)); 
    } 
} 
Powiązane problemy