在IOS WebView

时间:2017-06-02 16:57:46

标签: ios swift wkwebview

背景

我正在Android重写Swift个应用程序。该应用程序的重点是它在webView中加载一个网站,允许用户登录,然后让他们访问名为“下载您的数据”的链接。

问题

现在,当用户点击IOS中的链接时,它会在视图中打开一个txt文件。因此整个txt文件出现在屏幕上的视图中。

在Android中,它会下载文件,我可以通过文件系统访问它,然后POST将数据发送到服务器。

问题

考虑到数据出现在屏幕上并且没有下载或让我通过文件系统访问该文件,

我可以通过什么方式或方式访问文件中的文件或数据,以便将其发布到服务器上?

示例代码

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {

    var webView: WKWebView!

    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let viewUrl = URL(string: "https://www.example.com")
        let viewUrlRequest = URLRequest(url: viewUrl!)
        webView.load(viewUrlRequest)
    }

}

1 个答案:

答案 0 :(得分:0)

<强>解决方案

我处理这个问题的方法是在发出请求时嗅探流量。寻找必要的头和url端点,然后在Swift中形成一个查询来处理文件下载。一旦我得到了数据,我就能用它做任何我想做的事情。在我的情况下,我把它发布到服务器。

<强>查尔斯

您可以找到Charles here

  

Charles是一个HTTP代理/ HTTP监视器/反向代理,可以启用   开发人员查看之间的所有HTTP和SSL / HTTPS流量   他们的机器和互联网。这包括请求,响应和   HTTP标头(包含cookie和缓存信息)。

您需要此操作来调查您需要进行的http请求才能获取应用中的数据。这样,您可以实用地生成请求并控制应用程序的流程。

在我的应用中,我使用javascript来模拟点击并强制下载。我必须将正确的标题附加到我使用Charles找到的http请求中。

解决方案说明

这是一个使用Swift并注入javascript的示例。这显示了如何添加标头并发出http请求。你将不得不花时间弄清楚你需要改变什么来使这项工作。但逻辑在这里。

在我的情况下,我必须将用户登录到网站,单击接受条款和条件的链接,然后单击链接以下载数据。如果你只需要点击一个端点,那么你就不需要像我这样广泛。如果你确实需要模拟点击,那么我的代码应该会有很多帮助。

示例代码

import Foundation
import UIKit

class Downloader: NSObject {
    enum Step { case idle, login, agreeToTerms, download }


    var currentStep = Step.idle
    var uiwebview: UIWebView!
    var username: String = ""
    var password: String = ""
    var completion: ((Data?, Error?) -> Void)?

    static var downloader: Downloader!

    static func download(username: String, password: String, completion: @escaping (Data?, Error?) -> Void) {
        if self.downloader == nil { self.downloader = Downloader() }

        self.downloader.uiwebview = UIWebView(frame: CGRect(x: 0, y: 0, width: 320, height: 480))
        self.downloader.uiwebview.scalesPageToFit = true
        self.downloader.uiwebview.delegate = self.downloader

        self.downloader.username = username
        self.downloader.password = password
        self.downloader.completion = completion

        let url = URL(string: "URL-END-POINT-HERE")!
        self.downloader.currentStep = .login
        self.downloader.uiwebview?.loadRequest(URLRequest(url: url))
    }
}

extension Downloader: UIWebViewDelegate {
    func webViewDidFinishLoad(_ webView: UIWebView) {
        if self.currentStep == .login, webView.request!.url?.absoluteString == "SOME-OTHER-URL-ACTION" {
            let script = "document.getElementById('signInNew:inputUserId').value = '\(self.username)'; document.getElementById('signInNew:inputPassword').value = '\(self.password)'; document.getElementById('signInNew:signin_login').click()"
            self.currentStep = .agreeToTerms
            webView.stringByEvaluatingJavaScript(from: script)
        } else if self.currentStep == .agreeToTerms, webView.request!.url?.absoluteString == "https://www.nslds.ed.gov/npas/pub/disclaimer.htm" {
            self.currentStep = .download
            webView.stringByEvaluatingJavaScript(from: "document.getElementsByClassName('button signIn')[0].click()")
        } else if self.currentStep == .download, webView.request?.url?.absoluteString == "SOME-OTHER-URL-ACTION" {
            let url = URL(string: "SOME-OTHER-URL-ACTION")!
            var request = URLRequest(url: url)
            var headers = request.allHTTPHeaderFields ?? [:]

            if let cookies = HTTPCookieStorage.shared.cookies(for: url) {
                for (key, value) in HTTPCookie.requestHeaderFields(with: cookies) { headers[key] = value }
            }
            // headers here - change these to the correct headers
            headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
            headers["Accept-Encoding"] = "gzip, deflate, sdch, br"
            headers["Accept-Language"] = "en-US,en;q=0.8"
            headers["Connection"] = "keep-alive"
            headers["Referer"] = "URL-REFERER-HERE-END-POINT"
            headers["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301"
            //headers["Referer"] = "URL-REFERER-HERE-END-POINT"
            request.allHTTPHeaderFields = headers
            request.httpShouldHandleCookies = false

            URLSession.shared.dataTask(with: request) { data, response, error in
                self.completion?(data, error)
            }.resume()
        } else {
            print("URL mismatch: \(webView.request!.url!.absoluteString)")
            self.completion?(nil, NSError(domain: "Connection", code: 100, userInfo: [NSLocalizedDescriptionKey: "Check username & password \nDownload sequence mismatch"]))
        }
    }
}