Доступ к функциям javascripts из источника WKWebView (window.opener)

1

В моем приложении iOS у меня есть два WKWebView управления WKWebView для имитации отношений между родителями и дочерними элементами из 2 вкладки/окна в нашем веб-приложении, чтобы мы могли повторно использовать все эти javascripts. Проблема в том, что между этими двумя WKWebView s нет общего канала связи.

Веб-архитектура:
- Первое/главное окно загружает наши внутренние функции javascript со ссылками, открывающимися во втором/дочернем окне.
- Второе/дочернее окно загружает сторонний веб-контент.
- Содержимое третьей стороны связывается с нашей системой, используя окно источника формы javascript (с использованием API-интерфейса window.opener/window.parent API).

Теперь, в родном приложении, это то, что я делаю, чтобы повторно использовать существующие javascripts и имитировать веб-архитектуру -

а. Ниже js вызов с веб-страницы в 1-м WKWebView -

  window.open("http://localhost/child.html", "myWindow", "width=200,height=100");  

б. WKUIDelegate перехватывает этот вызов (a) и открывает второй WKWebView -

- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
    // Here, window.open js calls are handled by loading the request in another/new web view
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    WebViewController *webViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"WebViewController"];
    webViewController.loadURLString = navigationAction.request.URL.absoluteString;

    // Show controller without interfering the current flow of API call, thus dispatch after a fraction of second
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.navigationController pushViewController:webViewController animated:YES];
    });
    return nil;
}

с. В браузере веб-браузера дочернее окно веб-приложения может получить доступ к функциям js источника, используя window.opener и window.parent

Как добиться такой же функциональности в WKWebView? Другими словами, функции js во втором WKWebView могут вызывать функции js из родительского/исходного WKWebView?

Теги:
wkwebview
window.opener

2 ответа

1
Лучший ответ

Вы определенно не должны возвращать nil из webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures: но экземпляр вашего WKWebView.

К сожалению, я не могу проверить это прямо сейчас. Но, насколько я помню, трюк также не должен игнорировать аргумент WKWebViewConfiguration из webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures: delegate method, но создать второй экземпляр WKWebView, передав этот аргумент как один из параметров initWithFrame:configuration:

Кроме того, согласно документации Apple, похоже, что вам не нужно загружать запрос самостоятельно, если вы возвращаете правильный экземпляр веб-представления. WebKit должен справиться с этим для вас.

В целом ваш код должен выглядеть примерно так:

- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
    WKWebView *childWebView = [[WKWebView alloc] initWithFrame:CGFrameZero configuration:configuration];
    WebViewController *webViewController = [[WebViewController alloc] initWithWebView: childWebView];

    // looks like this is no longer required, but I can't check it now :(
    // [childWebView loadRequest:navigationAction.request];

    // Show controller without interfering the current flow of API call, thus dispatch after a fraction of second
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.navigationController pushViewController:webViewController animated:YES];
    });
    return childWebView;
}
  • 0
    Хороший улов, это выглядит как многообещающий ответ. В восторге. Дадим ему шанс сегодня.
0

Более простой способ выполнить вашу задачу будет иметь один WKWebView и использовать HTML для разделения заголовка и деталей. Самое простое решение состоит в том, чтобы иметь один HTML-документ с заголовком и всеми подробностями, но если вам нужно динамически добавлять данные, которые также можно использовать, используйте DOM. Повторное использование Javascript для заголовка и детализации будет проще всего при таком подходе.

  • 0
    На самом деле, открытие данных в 2 отдельных WKWebViews является обязательным условием, чтобы мы могли повторно использовать архитектуру веб-приложения для этой функции в нашем приложении. Кроме того, с точки зрения пользователя, он обеспечит такой же опыт работы в веб-приложении, как и в нативном приложении.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню