iOS 从 UIWebView 迁移到 WKWebView for JavaScript POST

原文 标签 ios swift payment 3d-secure

我正在 Swift 的 Native iOS App 中实现安全支付解决方案。

基本上,当我开始支付请求时,如果支付卡注册了 3D Check,我会在响应中收到“PaReq”和“ACSURL”。

然后我需要做java脚本POST。

一旦用户完成操作,我需要提取“PaRes”并在下一次服务调用中发送它。

这是使用 UIWebView 在 Objective-C 中的工作解决方案。我想在 Swift 中使用 WKWebView 实现相同的事情,因为 UIWebView 已被弃用。

- (void)viewDidLoad {
    [super viewDidLoad];

    UIWebView *webView=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, self.secureViewContainer.frame.size.width ,self.secureViewContainer.frame.size.height)];
    webView.delegate = self;
    [self.view addSubview:webView];

    NSString *termURL = @"https://www.apple.com";

    self.webViewURL = @"";
    self.webViewHTMLString = [NSString stringWithFormat:@"<html><body><form name='redirectToIssuerForm' id='redirectToIssuerForm' action='%@' method='post'><input type='hidden' name='PaReq' value='%@' /><input type='hidden' name='TermUrl' value='%@' /><input type='hidden' name='MD' value='' /><input type='submit' id='submitButton' value='Click here to continue' /></form><script>function submitForm(){document.getElementById('submitButton').style.display='none'; document.getElementById('submitButton').click();} window.onload = (function(){submitForm();});</script></body></html>",self.acsurl,self.pareq,termURL];

    [webView loadHTMLString:self.webViewHTMLString baseURL:nil];

}

- (void)webViewDidFinishLoad:(UIWebView *)webView{

    if([webView.request.URL.absoluteString isEqualToString:@"about:blank"]){
        [webView stringByEvaluatingJavaScriptFromString:@"submitForm()"];
    }
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{

    if([ [NSString stringWithFormat:@"%@",request.URL] isEqualToString:@"https://www.apple.com/"]){ 

    NSData *data = request.HTTPBody;

    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];

    NSLog(@"\n\n\n  3D Secure - dataString: %@", dataString);

        return NO;
    }
    else{

        return YES;

    }
}

这是我尝试使用 WKWebView 迁移到 Swift 的内容:
override func viewDidLoad() {

    super.viewDidLoad()

    let webConfiguration = WKWebViewConfiguration()
    let customFrame = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: 0.0, height: self.secureViewContainer.frame.size.height))
    self.webView = WKWebView (frame: customFrame , configuration: webConfiguration)
    webView.uiDelegate = self
    webView.navigationDelegate = self
    self.secureViewContainer.addSubview(webView)          
}
override func viewWillAppear(_ animated: Bool) {

    super.viewWillAppear(animated)
    let termURLString = "https://www.apple.com"
    var paReqString = response.PaRequest
    var acsurlString = response.ACSURL

    // create HTML String 

    let webViewHTMLString = String(format:"<html><body><form name='redirectToIssuerForm' id='redirectToIssuerForm' action='%@' method='post'><input type='hidden' name='PaReq' value='%@' /><input type='hidden' name='TermUrl' value='%@' /><input type='hidden' name='MD' value='' /><input type='submit' id='submitButton' value='Click here to continue' /></form><script>function submitForm(){document.getElementById('submitButton').style.display='none'; document.getElementById('submitButton').click();} window.onload = (function(){submitForm();});</script></body></html>",acsurlString,paReqString,termURLString)

        // Load HTML String
        webView.loadHTMLString(webViewHTMLString, baseURL: nil)
 }

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

    if webView.url?.absoluteString == "about:blank" {

        webView.evaluateJavaScript("submitForm()", completionHandler: {
            result in

            print("\n\n\n Result - \(result)\n\n\n")

        })
    }

}

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

    if let url = navigationAction.request.url,url.absoluteString.hasPrefix("https://www.apple.com/") {
        let data = navigationAction.request.httpBody

        print("\n\n  data : \(String(describing: data))")

        decisionHandler(.cancel)
        return
    }
    decisionHandler(.allow)
}

问题是“结果”和“数据”都是零。

1:我会在 webView(_:decidePolicyFor:decisionHandler:) (或)在 webView:didFinishNavigation: 中获得 java 脚本结果吗?

2:在 UIWebView 工作解决方案中,我可以将 termURL 更改为任何 url,如“https://www.apple.com”,我仍然可以获得数据,有人可以解释一下这个 Javascript POST 是如何工作的吗?

3:请指点我一个指南/教程,以了解更多关于 JavaScript 和 Native iOS App 交互的信息。

最佳答案

看起来你在正确的轨道上。 I recently wrote an article on this subject, and that should explain everything you need.

首先,如果你想从你的 javascript 代码中向 native 代码发送一些东西,你需要使用 window.webkit在您的 javascript 代码中。你需要在你的 swift 代码中实现 WKScriptMessageHandler 和 WKNavigationDelegate,并实现这个函数:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    //This function handles the events coming from javascript.
    //We can access properties through the message body, like this:
    guard let response = message.body as? String else { return }
    print(response)
}

有关这方面的更多信息,请参阅文章。

您将要做的所有发送都将通过webview.evaluateJavascript() .确保 javascript 函数有效,因为 webkit 错误不会显示在 Xcode 控制台中。您必须为此实现自定义 messageHandler。

关于iOS 从 UIWebView 迁移到 WKWebView for JavaScript POST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49658467/

相关文章:

android - 如何在 Android 上向用户付款

mobile - Square 是否有用于接受付款的 API?

ios - NSData不接受转义的/UTF8编码的URL

swift - Lambda/封闭大小导致编译时超时

ios - swift :Instagram的故事和饲料细胞的风格

ios - NSURLProtocol和Swift-iOS7中的错误

macos - 什么格式存储大量混合数据

paypal - Braintree生产帐户请求被拒绝

ios - 将现有应用替换为另一个新应用-iOS App Store

iphone - LinkedIn 集成 r_network 和 w_messages 请求在 iOS sdk 中无法协同工作