【问题标题】:Downloading PKPass in an iOS custom app from my server从我的服务器在 iOS 自定义应用程序中下载 PKPass
【发布时间】:2013-06-24 13:48:08
【问题描述】:

我已经设置了一个返回 PKPass 的服务器。如果我将 URL 复制到浏览器,则会显示一个通行证(在我的 Mac 和我的 iPhone 中)。 我用来下载通行证的代码如下:

NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:kAPIPass]];
if (nil != data) {
    PKPass *pass = [[PKPass alloc] initWithData:data error:nil];
    PKAddPassesViewController *pkvc = [[PKAddPassesViewController alloc] initWithPass:pass];
    pkvc.delegate = self;
    [self presentViewController:pkvc
                       animated:YES
                     completion:^{
                         // Do any cleanup here
                     }
     ];
}

无论如何,当我运行此代码时,出现以下错误:

* 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“仅支持 RGBA 或 白色空间,这个方法是个hack。'

我不知道是什么错误...当我使用 Safari 下载该通行证时,它似乎还可以,甚至代码似乎也可以(只有 3 行简单的行...)有 Passkit 经验的人可以帮助我吗?

编辑:奇怪的是,完全相同的代码正在一个全新的项目中运行

编辑 2: 从 AppDelegate 中删除以下行,删除崩溃,这很奇怪!

[[UINavigationBar appearance] setTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"navbar_bg_gen.png"]]];

【问题讨论】:

  • 您能发布一个指向您的 .pkpass 捆绑包的链接吗?听起来您可能正在为颜色使用 base16 哈希值,而不是 RGB 值,但需要查看 pass.json 以确定。
  • 颜色定义为:"backgroundColor" : "rgb(25,143,133)", "foregroundColor" : "rgb(255,255,255)",

标签: ios passbook passkit


【解决方案1】:

斯威夫特 3

这是使用完成处理程序从服务器下载 .pkpass(存折文件)并显示 pkpassviewcontroller 以进一步添加到苹果钱包的代码。

import PassKit


let url : NSURL! = NSURL(string: "YOUR .pkpass URL GOES HERE")
        let request: NSURLRequest = NSURLRequest(url:
            url as URL)
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)

    let task : URLSessionDataTask = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in

        var error: NSError?
        let pass = try? PKPass(data: data!, error: &error)
        if error != nil {
            DispatchQueue.main.async {
                let alertView = UIAlertView(title: "Error", message: (error?.localizedDescription)!, delegate: nil, cancelButtonTitle: "OK", otherButtonTitles: "Cancel")
                alertView.show()
            }
        }
        else {
            let passLibrary = PKPassLibrary()
            if passLibrary.containsPass(pass!) {
                DispatchQueue.main.async {
                    let alertView = UIAlertView(title: "Already Exist", message: "This pass already added in wallet. Thanks!", delegate: nil, cancelButtonTitle: "OK", otherButtonTitles: "Cancel")
                    alertView.show()
                    self.hideLoading()
                }
            } else {
                let pkvc = PKAddPassesViewController(pass: pass!)
                pkvc.delegate = self
                self.present(pkvc, animated: true, completion: {() -> Void in
                    // Do any cleanup here
                    self.hideLoading()
                })

            }
        }

    })
    task.resume()

【讨论】:

    【解决方案2】:

    当前状态下的代码不会调用 PKAddPassesViewController 来向用户展示通行证。

    假设 Pass 库可用,以下内容适用于您在 iOS6 和 iOS7 中提供的 url:

    NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:kAPIPass]];
    
    if (nil != data) {
        PKPass *pass = [[PKPass alloc] initWithData:passData error:&error];
    
        if(error) {
    
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil];
            [alertView show];
    
        } else {
    
            PKAddPassesViewController *pkvc = [[PKAddPassesViewController alloc] initWithPass:pass];
            pkvc.delegate = self;
            [self presentViewController:pkvc
                               animated:YES
                             completion:^{
                                          // Do any cleanup here                     
                                         }
            ]; 
        }                       
    }
    

    或者,您可以异步加载它,以免阻塞主线程。

    [NSURLConnection sendAsynchronousRequest:_request 
                                       queue:_browser 
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    
        if (nil != error) {
            // handle error
        } else if (nil != data) {
            PKPass *pass = [[PKPass alloc] initWithData:passData error:&error];
    
            if(error) {
    
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK"otherButtonTitles:nil];
                [alertView show];
    
            } else {
    
                vc = [[PKAddPassesViewController alloc] initWithPass:pass];
                pkvc.delegate = self;
                [self presentViewController:pkvc
                                   animated:YES
                                 completion:^{
                                              // Do any cleanup here                     
                                             }
                ]; 
            }
        }
    }];    
    

    【讨论】:

    • 奇怪的是,我发布的完全相同的代码正在一个全新的项目中工作......
    • 看着它,我看不出它为什么不应该这样做。可能错误与 Pass Kit 无关,而是由原始项目中的其他内容触发。
    • 是的,删除这一行 [[UINavigationBar appearance] setTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"navbar_bg_gen.png"]]];从 appdelegate 中,一切都恢复正常了,你知道为什么吗?
    • 听起来像一个 iOS 错误 - 您的 [UINavigationBar appearance] 应该被应用或忽略,这取决于 Apple 想要锁定 PKAddPassesViewController 的程度,但它不应导致崩溃。
    【解决方案3】:

    所以问题出在 AppDelegate 中的这一行:

    [[UINavigationBar appearance] setTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"navbar_bg_gen.png"]]];
    

    在我添加存折之前完美运行的图像似乎不被显示通行证的控制器所喜欢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-07
      相关资源
      最近更新 更多