Подтвердить что ты не робот

Как я могу получить файл с помощью WKWebView?

Существует файл (CSV), который я хочу загрузить. Он находится за экраном входа на веб-сайт. Я хотел показать WKWebView, чтобы позволить пользователю войти в систему, а затем загрузить приложение после входа в систему.

Я попытался загрузить файл за пределами WKWebView после входа пользователя на сайт, но данные сеанса, кажется, изолированы, потому что он загружает html-документ с формой входа вместо желаемого файла.

Я также попытался добавить объект WKUserScript в объект WKUserContentController, но script не запускается, когда загружается не-HTML файл.

Есть ли способ получить доступ к этому файлу, позволяя пользователям регистрироваться через WKWebView?

4b9b3361

Ответ 1

В настоящее время экземпляры WKWebView игнорируют любые сетевые хранилища по умолчанию (NSURLCache, NSHTTPCookieStorage, NSCredentialStorage), а также стандартные сетевые классы, которые вы можете использовать для настройки сетевых запросов (NSURLProtocol и т.д.).

Таким образом, файлы cookie экземпляра WKWebView не хранятся в стандартном хранилище Cookie вашего приложения, поэтому NSURLSession/NSURLConnection, который использует только стандартное хранилище Cookie, не имеет доступа к файлам cookie WKWebView (и именно это, вероятно, проблема у вас есть: "статус входа", скорее всего, хранится в файле cookie, но NSURLSession/NSURLConnection не увидит файл cookie).

То же самое относится к кешу, учетным данным и т.д. WKWebView имеет свои собственные хранилища и, следовательно, не очень хорошо работает со стандартными сетевыми классами Cocoa.

Вы также не можете настраивать запросы (добавлять собственные HTTP-заголовки, изменять существующие заголовки и т.д.), использовать свои собственные схемы URL-адресов и т.д., так как NSURLProtocol не поддерживается WKWebView.

Итак, сейчас WKWebView довольно бесполезен для многих приложений, потому что он не участвует со стандартными сетевыми API-интерфейсами Cocoa.

Я все еще надеюсь, что Apple изменит это до выхода iOS 8, потому что иначе WKWebView будет бесполезен для многих приложений, и мы, вероятно, будем придерживаться UIWebView немного дольше.

Итак, отправляйте отчеты об ошибках в Apple, поэтому Apple узнает, что эти проблемы являются серьезными и должны быть исправлены.

Ответ 2

Проверяли ли вы ответные файлы cookie, возвращенные из запроса. Вы можете использовать метод делегата, как это.

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
    NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];

    for (NSHTTPCookie *cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
    }

    decisionHandler(WKNavigationResponsePolicyAllow);
}

Ответ 3

Я сделал нечто похожее на то, что вы пытаетесь сделать:

  • используйте веб-представление для входа в систему, как вы уже делаете
  • установите navigationDelegate на веб-просмотр
  • реализовать -webView:decidePolicyForNavigationResponse:decisionHandler в вашем делетете
  • когда вызывается этот метод делегата (после входа пользователя в систему), вы можете проверить navigationResponse.response (отдать его на NSHTTPURLResponse*) и искать заголовок Set-Cookie, который содержит информацию о сеансе, которая вам понадобится для аутентификации сессий.
  • вы можете загрузить CSV вручную, указав заголовок Cookie в своем запросе с помощью файлов cookie, указанных в ответе.

Обратите внимание, что методы делегата вызываются только для запросов "основного кадра". Это означает, что запросы AJAX или внутренние кадры не будут запускать его. Вся страница должна обновиться для этого.

Если вам нужно вызвать поведение для запросов AJAX, iframes и т.д., вам нужно будет добавить некоторый javascript.

Ответ 4

Кажется, у меня нет cookie сеанса, когда я пытаюсь выполнить запрос от userContentController didReceiveScriptMessage.

Однако, когда вызывается из решенияPolicyForNavigationAction, следующий код обнаруживает, что я вошел в систему.

     let urlPath: String = "<api endpoint at url at which you are logged in>"

    let url = NSURL(string: urlPath)
    let session = NSURLSession.sharedSession()
    let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in

        let string1 = NSString(data: data, encoding: NSUTF8StringEncoding)
        println(string1)
        println(data)
        if(error != nil) {
            println("Error sending token to server")
            // Print any error to the console
            println(error.localizedDescription)
        }
        var err: NSError?

    })

    task.resume()

Ответ 5

Вы можете получить файл cookie через Javascript:

Затем вы можете использовать полученный файл cookie для загрузки файла вручную:

webView.evaluateJavaScript("(function() { return document.cookie })()", completionHandler: { (response, error) -> Void in
  let cookie = response as! String
  let request = NSMutableURLRequest(URL: docURL)
  request.setValue(cookie, forHTTPHeaderField:  "Cookie")

  NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { (data, response, error) in
    // Your CSV file will be in the response object
  }).resume()
})