В моем приложении 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
?
Вы определенно не должны возвращать 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;
}
Более простой способ выполнить вашу задачу будет иметь один WKWebView и использовать HTML для разделения заголовка и деталей. Самое простое решение состоит в том, чтобы иметь один HTML-документ с заголовком и всеми подробностями, но если вам нужно динамически добавлять данные, которые также можно использовать, используйте DOM. Повторное использование Javascript для заголовка и детализации будет проще всего при таком подходе.