简体   繁体   English

使用自定义URL方案将数据从UIWebView发送回iOS应用程序使用Xcode 8 / iOS 10

[英]Sending Data from a UIWebView back to an iOS Application with a custom URL Scheme breaks with Xcode 8/iOS 10

On iOS versions previous to 10, I was able to send information from the JavaScript/HTML loaded into a UIWebView back to my application by creating an iFrame on the document or setting document.location.href to a custom URL which the web view would tried to load: 在10之前的iOS版本中,我能够通过在文档上创建iFrame或将document.location.href设置为Web视图尝试的自定义URL,将加载到UIWebView的JavaScript / HTML中的信息发送回我的应用程序装载:

<html>
<body><input id="clickMe" type="button" value="clickme" onclick="changeWindow();" /></body>
<script type="text/javascript">
    function changeWindow() {
        //create temp frame
        iFrame = this.createIFrame('onStatusChange://eyJ1c2VyTmFtZSI6IkpBTCIsLCJwcm92aWRlciI6IkVtYWlsIn0=');
        //remove the frame now
        iFrame.parentNode.removeChild(iFrame);
    }

    function createIFrame(src) {
      var rootElm = document.documentElement;
      var newFrameElm = document.createElement('IFRAME');
      newFrameElm.setAttribute('src', src);
      rootElm.appendChild(newFrameElm);
      return newFrameElm;
    }
</script>
</html>

Then on the client, I would just listen for the UIWebViewDelegate callback webView:shouldStartLoadWithRequest:navigationType: , and check to see if the request.URL.scheme was equal to my custom scheme (in this case onStatusChange ). 然后在客户端上,我只是监听UIWebViewDelegate回调webView:shouldStartLoadWithRequest:navigationType: ,并检查request.URL.scheme是否等于我的自定义方案(在本例中为onStatusChange )。

This is a popular way of communicating between the JavaScript and an iOS app, as seen in popular questions such as How to invoke Objective C method from Javascript and send back data to Javascript in iOS? 这是一种流行的JavaScript和iOS应用程序之间的通信方式,如流行的问题,如如何从Javascript调用Objective C方法,并将数据发送回iOS中的Javascript? .

This works on any app built with Xcode 7 (Objective-C or Swift) on iOS 9 and 10 devices. 这适用于在iOS 9和10设备上使用Xcode 7(Objective-C或Swift)构建的任何应用程序。 I'm running into an issue where the delegate method is not called on any applications built with Xcode 8. It's as if the web view isn't even trying to load the URL, which in turn is not triggering the delegate callback. 我遇到了一个问题,即在使用Xcode 8构建的任何应用程序上都没有调用委托方法。就好像Web视图甚至没有尝试加载URL,而后者又不会触发委托回调。

Were there any changes to UIWebView or WebKit from Xcode 7 to 8 or iOS 9 to 10 which would cause this not to work? 从Xcode 7到8或iOS 9到10的UIWebView或WebKit是否有任何变化会导致这种情况无效? What's really puzzling to me is that a production app I have built with Objective-C in Xcode 7 targeting iOS 8 works on an iOS 10 device, but a debug build built with Xcode 8 of the exact same codebase does not work. 令我感到困惑的是,我在Xcode 7中针对iOS 8使用Objective-C构建的生产应用程序可以在iOS 10设备上运行,但使用完全相同代码库的Xcode 8构建的调试版本不起作用。

Ok, long story short we use a special URL scheme onStatusChange:// to send Base64 encoded data from the web view back to our iOS application. 好吧,长话短说我们在onStatusChange://上使用特殊的URL方案将Base64编码的数据从Web视图发送回我们的iOS应用程序。 I believe UIWebView on iOS 10 chokes when trying to load a URL that ends in one or more equals sign characters, and loads about:blank instead of the actual URL. 我相信iOS 10上的UIWebView在尝试加载以一个或多个等号符号结尾的URL时会发出嘎嘎声,并加载about:blank而不是实际的URL。

Since this works perfectly on iOS 9, I'm assuming this is a defect with iOS 10 and have opened rdar://29035522 . 由于这在iOS 9上完美运行,我假设这是iOS 10的缺陷并已打开rdar://29035522 A full reproducible example of the issue is available in the body of that radar. 该雷达的主体提供了一个完整的可重现的问题示例。

I am reading through the Base-N encoding RFC to determine if it is acceptable to remove the padding = characters at the end of my data string, or if they need to be removed from the web and added on the client before decoding the data. 我正在阅读Base-N编码RFC以确定是否可以删除数据字符串末尾的padding =字符,或者是否需要从Web中删除它们并在解码数据之前添加到客户端。

The solution I ended up implementing was percent-escaping the Base64 encoded data, and unescaping it on the client. 我最终实现的解决方案是逃避Base64编码数据的百分比,并在客户端上取消它。 Not the most elegant solution, but probably the best for safety. 不是最优雅的解决方案,但可能是最安全的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM