Downloading PKPass in an iOS custom app from my server

孤街醉人 提交于 2020-01-03 03:05:57

问题


I've setup a server which returns a PKPass. If I copy the URL to the browser, a pass is shown (both in my Mac and in my iPhone). The code I'm using to download the pass is the following one:

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
                     }
     ];
}

Anyway, when I run this code I have the following error:

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only support RGBA or the White color space, this method is a hack.'

I don't know what is the bug... The pass seems ok when I download it with Safari and even the code seems ok (there are just 3 simple rows...) Someone experienced with Passkit could help me?

EDIT: the weird thing is that the exact same code is working in a fresh new project

EDIT 2: removing the following line from the AppDelegate, remove the crash, that's weird!

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

回答1:


Your code in it's current state does not make a call to PKAddPassesViewController to present the pass to the user.

Assuming that the Pass Library is available, the following works with the url you provided in iOS6 & iOS7:

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                     
                                     }
        ]; 
    }                       
}

Alternatively, you could load it asynchronously so as not to block the main thread.

[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                     
                                         }
            ]; 
        }
    }
}];    



回答2:


Swift 3

Here is the code to download the .pkpass (passbook file) from server with completion handler and show pkpassviewcontroller for further adding into the apple wallet.

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()



回答3:


So the problem was this line in the AppDelegate:

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

It seems that the image, which work perfectly till I added passbook, is not liked by the controller displaying the pass.



来源:https://stackoverflow.com/questions/17277120/downloading-pkpass-in-an-ios-custom-app-from-my-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!