问题
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