Ios 当UIWebView完成加载Ajax时获取回调

Ios 当UIWebView完成加载Ajax时获取回调,ios,swift,uiwebview,Ios,Swift,Uiwebview,当Ajax在UIWebView中完成加载时,是否可能收到通知?在安卓系统中,我可以这样做: @SuppressLint("SetJavaScriptEnabled") private void setUpWebView() { webview = view.findViewById(R.id.webView); webview.getSettings().setJavaScriptEnabled(true); webview.addJavascriptInterface(

当Ajax在UIWebView中完成加载时,是否可能收到通知?在安卓系统中,我可以这样做:

@SuppressLint("SetJavaScriptEnabled")
private void setUpWebView() {
    webview = view.findViewById(R.id.webView);
    webview.getSettings().setJavaScriptEnabled(true);
    webview.addJavascriptInterface(new JavaScriptInterface(), "HtmlViewer");
    webview.setWebViewClient(new LoginWebView());
    webview.loadUrl("EXAMPLE URL");
}

private class LoginWebView extends WebViewClient {
    @SuppressLint({"JavascriptInterface"})
    @Override
    public void onPageFinished(WebView view, String url) {
        view.loadUrl("javascript:(function(){" +
            "\n" + "    jQuery(document).ajaxComplete(function(event, request, settings){" +
            "\n" + "        var responseCode = JSON.parse(request.responseText).result.responseCode;" +
            "\n" + "        window.HtmlViewer.ajaxResponse(settings.url, responseCode);" +
            "\n" + "    });" +
            "\n" + "})();";);
    }
}

private class JavaScriptInterface {
    @JavascriptInterface
    public void ajaxResponse(String url, String responseCode) {
        // Gets notified when Ajax finished loading
    }
}

现在,每次Ajax完成加载时,都会调用我的
ajaxResponse
方法。在UIWebView中也可以实现这一点吗?

您可以使用
evaluateJavaScript:completionHandler:

webView.evaluateJavaScript("yourJSfuncsToRunAJAX") { response, error in
    //if error didn't occure do sth after js function finished
}

不幸的是,iOS 8不推荐使用UIWebView,因此您应该切换到WKWebView。 From:“在iOS 8及更高版本中运行的应用程序中,请使用WKWebView类而不是UIWebView。”

要在ajax完成时获得通知,可以使用来自的已接受响应。我在javascript和swift之间使用了相同的原则


希望能有所帮助。

我终于找到了解决这个问题的办法。有很多解决方案,但它们都使用jQuery,而jQuery在
WKWebView
中似乎不起作用。这是我的原始
JavaScript
解决方案

下面是ViewController实现,它允许您在
WKWebView
中完成每个AJAX请求时收到通知:

import UIKit
import WebKit

class WebViewController: UIViewController {

    private var wkWebView: WKWebView!
    private let handler = "handler"

    override func viewDidLoad() {
        super.viewDidLoad()

        let config = WKWebViewConfiguration()
        let userScript = WKUserScript(source: getScript(), injectionTime: .atDocumentStart, forMainFrameOnly: false)
        config.userContentController.addUserScript(userScript)
        config.userContentController.add(self, name: handler)

        wkWebView = WKWebView(frame:  view.bounds, configuration: config)
        view.addSubview(wkWebView)

        if let url = URL(string: "YOUR AJAX WEBSITE") {
            wkWebView.load(URLRequest(url: url))
        } else {
            print("Wrong URL!")
        }
    }

    private func getScript() -> String {
        if let filepath = Bundle.main.path(forResource: "script", ofType: "js") {
            do {
                return try String(contentsOfFile: filepath)
            } catch {
                print(error)
            }
        } else {
            print("script.js not found!")
        }
        return ""
    }
}

extension WebViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if let dict = message.body as? Dictionary<String, AnyObject>, let status = dict["status"] as? Int, let responseUrl = dict["responseURL"] as? String {
            print(status)
            print(responseUrl)
        }
    }
}
userContentController
每次加载AJAX请求时都会调用委托方法。我正在传递那里的
状态
响应
,因为这是我的案例所需要的,但您也可以获得有关请求的更多信息。以下是所有可用属性和方法的列表:

我的解决方案受@John Culviner的回答启发:

谢谢你的回答。问题是我需要使用
UIWebView
,它不允许使用带有回调的
evaluateJavaScript
函数。我想我可以尝试使用
WKWebView
(它有糟糕的cookie管理系统,这就是为什么我需要使用
UIWebView
)。问题是我不知道JS脚本在iOS版本中应该是什么样子。在Android上,我正在调用
window.HtmlViewer.ajaxsresponse(settings.url,responseCode)让我向函数传递回调信息。如何在iOS上实现这一点?@user3448282 Apple建议使用WKWebView,请尝试一下;)JS在每个浏览器上都非常相似,所以如果它在基于chromium的浏览器上工作,那么它也应该在safari上工作。
var open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function() {
    this.addEventListener("load", function() {
        var message = {"status" : this.status, "responseURL" : this.responseURL}
        webkit.messageHandlers.handler.postMessage(message);
    });
    open.apply(this, arguments);
};