背景
我正在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)
}
}
答案 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"]))
}
}
}