WKWebview не будет правильно загружать определенные веб-сайты

Мне нужно загрузить широкий ассортимент URL-адресов веб-сайтов (которые исходят от веб-службы) в WKWebview.

Некоторые веб-сайты ведут себя достаточно хорошо и загружаются правильно, просто заменив «http» на «https» в URL-адресе:

http://www.yahoo.com/news -> loads blank
**https://www.yahoo.com/news -> loads OK!!**

URLs without the https:// prefix will NOT load at all.

http://www.google.com -> blank 
**https://www.google.com -> Loads OK!!!**
http://www.bbc.co.uk/news (no .plist Exception) -> blank
https://www.bbc.co.uk/news (no .plist Exception) -> blank
http://www.bbc.co.uk/news (WITH .plist Exception) -> blank
https://www.bbc.co.uk/news (WITH .plist Exception) -> blank

(Я вставил https://www.bbc.co.uk/news в браузере MAC OS. , и был перенаправлен на https://www.bbc.co.uk/news, поэтому Я их тоже пробовал :)

https://www.bbc.com/news (WITH .plist Exception) -> Images and text are loaded in a messy, unformatted, basic way.
http://www.bbc.com/news (WITH .plist Exception) -> Images and text are loaded in a messy, unformatted, basic way.
https://www.bbc.com/news (WITHOUT .plist Exception) -> blank
http://www.bbc.com/news (WITHOUT .plist Exception) -> blank

Другие URL-адреса ведут себя так же, как примеры BBC или Yahoo выше.

Это своего рода исключение, которое я использую в файле .plist.

Это мой код:

- (void)viewDidLoad{
    [super viewDidLoad];
    CGRect wkFrame = _wios10container.frame;
    NSLog(@"WPVC - viewDidLoad, wkFrame: %@",NSStringFromCGRect(wkFrame));
    WKWebViewConfiguration *wkConfiguration = [[WKWebViewConfiguration alloc] init];
    _webviewIOS10 = [[WKWebView alloc] initWithFrame:_wios10container.frame configuration:wkConfiguration];
    _webviewIOS10.navigationDelegate = self;
    [_wios10container addSubview:_webviewIOS10];
}

Мои вопросы:

  1. Как я могу правильно загружать веб-сайты, такие как BBC?
  2. Как я могу подготовить свое приложение для загрузки любого URL-адреса, не нуждаясь в огромном списке исключений?
  3. Приложение работает нормально, если я устанавливаю для NSAppTransportSecurity.NSAllowsArbitraryLoads значение YES, но мне это совсем не нравится. Какая альтернатива этому у меня есть ради одобрения Security и App Store?

person Josh    schedule 08.03.2017    source источник


Ответы (3)


Более надежным способом сделать это будет использование WKNavigationDelegate и, в вашем случае, оценка URL-адреса. Чтобы справиться с огромным списком (не зная больше об этом списке), я бы выполнил оценку регулярного выражения для выполнения на его основе. Также вы можете создать политику перенаправления, основанную на ваших потребностях.

Например:

class WebNavigationHandler: NSObject, WKNavigationDelegate {

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {

        //Based on the navigation action decide what to do.
        if canINavigate {
            decisionHandler(.allow)
        } else {
            decisionHandler(.cancel)
        }
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void) {

        // Base on the navigationResponse

        if canINavigate {
            decisionHandler(.allow)
        } else {
            decisionHandler(.cancel)
        }
    }

}

let webview = WKWebView()
webview.navigationDelegate = WebNavigationHandler()

Надеюсь, это ответит на ваш вопрос.

person Ricowere    schedule 08.03.2017
comment
Я попробую это, спасибо. Под большим списком я имею в виду: я не могу предвидеть все возможные URL-адреса, которые могут появиться во время выполнения, установив их по отдельности в файле .plist. Я вернусь, когда попробую ваш подход. - person Josh; 08.03.2017

Я думаю, вы ищете настройку NSAllowArbitraryLoadsInWebContent для NSAppTransportSecurity. См. этот документ Apple: https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html

person Dave Weston    schedule 09.03.2017

После долгих проб и ошибок эта формула сработала для меня:

  1. НЕ заменяйте http: на https: в строке URL
  2. Добавьте отдельные доменные исключения для каждого домена, который вы хотите поддерживать. Моему приложению требуется отображать только 8 веб-сайтов, так что эта комбинация работает нормально!:
<key>bbc.co.uk</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <true/>
                <key>NSExceptionMinimumTLSVersion</key>
                <string>TLSv1.2</string>
                <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
                <false/>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <true/>
                <key>NSThirdPartyExceptionMinimumTLSVersion</key>
                <string>TLSv1.2</string>
                <key>NSRequiresCertificateTransparency</key>
                <false/>
            </dict>

Необязательно, первый также применяется для этого другого подхода, загружая URL-адрес в SFSafariViewController. Я соглашусь на этот подход, который достаточно надежен и даже имеет кнопки «Назад», «Далее», «Обновить» и «Поделиться» во встроенной навигации. бар. Вот код:

    NSURL *wkURL = [NSURL URLWithString:wkURLstring];
    SFSafariViewController *safariVC = [[SFSafariViewController alloc] initWithURL:wkURL];
    [self.view.window.rootViewController presentViewController:safariVC animated:YES completion:^{
        NSLog(@"Full Safari Webview Launched");
    }];
person Josh    schedule 09.03.2017