【问题标题】:Can you download a passbook coupon from a UIWebView inside an IOS app?您可以从 IOS 应用程序内的 UIWebView 下载存折优惠券吗?
【发布时间】:2012-11-30 14:05:34
【问题描述】:

是否可以在不修改应用程序以支持新的 MIME 类型或像 Sparrow 所做的未知 MIME 类型的情况下从 web 视图中下载和添加存折?

我有一个带有 webview 的新闻 ios 应用程序。在 webview 中,我显示新闻项目和横幅。当您单击横幅时,我想打开 .pkpass 文件的 url 并将其添加到我的存折中。相反,我得到一个 FrameLoadInterrupted 错误,并且没有任何可见的事情发生。 如果我从 safari 打开 url 这工作正常,chrome,因为本周早些时候(版本 23)也会按预期打开 url。

这可能是 Apple 的一些奇怪策略吗?不允许此 MIME 类型从 web 视图正确打开?

【问题讨论】:

  • 何奔,我相信默认的Safari可以处理的。如果您打开此站点:http://passkit.com/samples/,您可以下载一些示例。您可能想尝试在 UIWebView 中打开此页面,看看它们是否仍然有效。
  • Safari 处理得很好,正如我所提到的。从 UIWebView 没有任何反应。
  • UIWebView 似乎无法打开存折文件。
  • 现在有办法欺骗 UIWebView 打开 .pkpass 吗?因为我认为替代方案是扩展相关应用程序以支持这种 MIME 类型。
  • 你认为它能解决我的问题吗? stackoverflow.com/questions/42415655/…

标签: ios uiwebview passbook


【解决方案1】:

我最好的选择是UIWebView 无法处理 Passbook 通行证。但是,您可以尝试在 UIWebViewDelegate 方法 -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 中捕获下载。

我的意思是你必须自己处理这部分,因为我使用的http://passkit.com/samples/ 不会返回以pkpass 结尾的url,因此它完全取决于你如何请求存折文件。

如果您包含 .pkpass 扩展名,您可以检查请求中的扩展名。

如果您知道存折文件的 URL 类型,您可以在此处编写自己的下载代码并通过 passbook api 将其传递给存折。


似乎没有什么好的解决方法,您可以在 safari 中加载失败的 ULR:

- (void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    NSLog(@"Webview: %@", error);

    if ([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102) {
        NSString *failedURL = [error.userInfo objectForKey:NSURLErrorFailingURLStringErrorKey];

        if (failedURL == nil) {
            return;
        }
        NSURL *url = [NSURL URLWithString:failedURL];

        [[UIApplication sharedApplication] openURL:url];
    }
}

但这只是非常糟糕的编码。

【讨论】:

  • 是的,我同意,但是我使用http://passkit.com/samples/ 构建的演示应用程序没有处理重定向,所以我能从中得到的最多的是一个像https://pass.is/bEmKtX 这样的网址,所以我真的不能句柄. pkpass 的任何通用代码。因此,该解决方案将不起作用。
  • 我不太明白你在这里做什么,但前两段是正确的,你必须抓住请求并自己处理。有一些示例展示了如何做到这一点。
【解决方案2】:

好的,与 WWDC 的工程师交谈,这是 UIWebView 中的一个已知错误,但 Apple 可能不会修复它,因为他们鼓励人们采用新的 SFSafariViewController。如果您需要支持 iOS 6-8,我们确实想出了一个技巧来修复它:

  1. 如果尚未将 PassKit 框架添加到项目中。

    #import <PassKit/PassKit.h>
    
  2. 为 UIWebView 设置委托(例如启动 UIWebView 的视图控制器)

    <UIWebViewDelegate>
    
  3. 添加一个类变量来缓存 UIWebView 请求

    NSURLRequest *_lastRequest;
    
  4. 设置委托

    self.webView.delegate = self;
    
  5. 添加回调以在失败时抓取所有请求并缓存

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
        _lastRequest = request;
        return YES;
    }
    
  6. 添加失败回调并重新获取 URL 以查看它是否是通过,如果是,则向用户呈现该通过

    - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
        // try to get headers in case of passbook pass
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        [NSURLConnection sendAsynchronousRequest:_lastRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            // check for PKPass
            if ([response.MIMEType isEqualToString:@"application/vnd.apple.pkpass"]) {
                NSError *error;
                PKPass *pass = [[PKPass alloc] initWithData:data error:&error];
                if (error) {
                    NSLog(@"Error: %@", error);
                } else {
                    PKAddPassesViewController *apvc = [[PKAddPassesViewController alloc] initWithPass:pass];
                    [self presentViewController:apvc animated:YES completion:nil];
                }
            }
        }];
    }
    

对于应该支持的内容来说,这是一个可怕的 hack,但无论扩展名如何,它都可以工作,并且应该支持重定向。如果想堆上bug train,可以参考radar://21314226

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    相关资源
    最近更新 更多