Запуск shouldStartLoadWithRequest с несколькими вызовами window.location.href

Я пытаюсь передать несколько вещей с веб-страницы внутри UIWebView обратно в мое приложение для iPhone с помощью метода shouldStartLoadWithRequest UIWebView.

В основном моя веб-страница вызывает window.location.href = "command: // foo = bar", и я могу перехватить это в моем приложении без проблем. Теперь, если я создаю цикл и выполняю несколько вызовов window.location.href одновременно, тогда shouldStartLoadWithRequest вызывается только один раз, а полученный вызов является самым последним запуском window.location.href в конце цикла.

То же самое происходит с веб-просмотром для Android, обрабатывается только последний window.location.href.


person AlBeebe    schedule 29.05.2010    source источник
comment
Я нашел умное решение. Динамически создавайте iframe для каждой команды и устанавливайте его src равным command: // foo = bar, вы можете запускать это несколько раз в цикле, и shouldStartLoadWithRequest вызывается каждый раз! Теперь изучим, как это оптимизировать. Не думаю, что было бы хорошо создавать тысячи фреймов (даже если они скрыты). Есть предложения по этому поводу?   -  person AlBeebe    schedule 29.05.2010
comment
Я бы также попытался оптимизировать каждый вызов местоположения. Если вы можете отправлять, скажем, только 60 вызовов в минуту, убедитесь, что вы заглушаете каждый вызов достаточным количеством переменных запроса и фрагментов для обработки нескольких команд за вызов. Кроме того, вы можете попробовать wkWebView: nshipster.com/wkwebkit он автоматизирует большую часть этого процесса и является более надежный.   -  person newshorts    schedule 14.08.2015


Ответы (3)


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

Таким образом, это создает iframe, устанавливает его источник в команду, которую я пытаюсь передать приложению, а затем, как только она добавляется к телу, shouldStartLoadWithRequest вызывается, мы удаляем iframe из тела и устанавливаем его на null, чтобы освободить память.

Я также тестировал это на веб-просмотре Android с помощью shouldOverrideUrlLoading, и он также работал правильно!

person AlBeebe    schedule 29.05.2010
comment
Это решение ужасно уродливо, но кажется наименее уродливым из возможных. Кажется, что Javascript оптимизируется, игнорируя вызовы window.location, которые впоследствии заменяются другими вызовами window.location. Спасибо, что избавили меня от очень болезненного сеанса отладки! - person Arkaaito; 09.10.2012
comment
@Arkaaito +1 за отвратительно уродливые, я полностью согласен - person AlBeebe; 10.10.2012
comment
Я хочу следить, так как опубликовал это 2 года назад. Я написал приложение для Android и iPhone, которое по сути представляло собой веб-просмотр, заключенный в собственное приложение. Я использовал это решение, чтобы я мог общаться из веб-просмотра в собственное приложение, и оно работало безупречно в течение последних 2 лет, у меня было более 500 тысяч загрузок моего приложения. - person AlBeebe; 10.10.2012
comment
3 года наблюдения, 4 000 000 загрузок iOS + Android вместе взятых, и это решение оказалось безупречным. Да, это некрасиво, но работает. - person AlBeebe; 28.11.2013
comment
Вы, сэр, молодцы. Я боролся с этим часами. Наконец правильный поиск в Google привел меня сюда. Спасибо. - person voodoobilly; 04.03.2014
comment
Именно то, что мне нужно. Работает хорошо. - person Stewart Megaw; 16.04.2015

Я тоже столкнулся с этой проблемой, и вот мое решение, которое мне подходит. Все мои функции JavaScript используют эту функцию __js2oc (msg) для передачи данных и событий в Objective-C через shouldStartLoadWithRequest: P.S. замените "command:" на ваш триггер "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));
  }
}
person Foxnolds    schedule 29.09.2011

Нет, изменение URL-адреса iframe не будет запускать shouldOverrideUrlLoading, по крайней мере, в Android 2.2.

person diyism    schedule 02.12.2010