1

I'm doing some testing with Apple Wallet. I've got a Pass I'd like to add to the user's Wallet when they tap a button. Here's my code:

        let filePath = Bundle.main.path(forResource: "DealsPasses", ofType: "pkpass")!
        let passData = try? Data(contentsOf: URL.init(fileURLWithPath: filePath), options: .alwaysMapped)
        let pass = PKPass(data: passData!, error: nil)
        let passVC = PKAddPassesViewController(pass: pass)
        navigationController?.pushViewController(passVC, animated: true)

However; when the user tapps the button,

AX Exchange error: Error Domain=Accessibility Code=0 "Remote service does not respond to _accessibilityMachPort" UserInfo={NSLocalizedDescription=Remote service does not respond to _accessibilityMachPort}

is spammed to the console at a rate of ~200/min, and no PKAddPassesViewController is presented (or if it is, it's just got a plain white view)

Running xCode 8 on an iPhone SE (device)

(Side note: dragging the DealsPasses.pkpass into the simulator works just fine)

Kelly Bennett
  • 725
  • 5
  • 27
  • Are you using KIF, Xarmin or other framework? Both use iOS Accessibility (VoiceOver) for locating UI elements, which is not it's normal purpose. When you pass control to a third party controller (in this case the PKAddPassesViewController), accessibility can no longer access the UI element. – PassKit Oct 08 '16 at 00:40
  • This is an interesting point. I'm not using KIF, or Xamarin, but I do have some other frameworks which might be doing similar things. I'll try making a release build without these and see what happens. – Kelly Bennett Oct 08 '16 at 01:41

2 Answers2

3
Please use the following code in swift 4.

Please download sample pass from this Link and keep those passes in the app sandbox.

import PassKit

//Function to open wallet view in your app. 
func loadWalletView() {
        if !PKPassLibrary.isPassLibraryAvailable() {
            let alert = UIAlertController(title: "Error", message: "PassKit not available", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
                switch action.style{
                case .default:
                    print("default")
                case .cancel:
                    print("cancel")
                case .destructive:
                    print("destructive")
                @unknown default:
                    break
                }}))
            self.present(alert, animated: true, completion: nil)
        }
        let resourcePath : String? = Bundle.main.resourcePath

        do {
            let passFiles : NSArray = try FileManager.default.contentsOfDirectory(atPath: resourcePath!) as NSArray
            for  passFile in passFiles {

                let passFileString = passFile as! String
                if passFileString.hasSuffix(".pkpass") {
                    openPassWithName(passName: passFileString)
                }
            }

        }catch {
            print(error.localizedDescription)
        }
    }

func openPassWithName(passName : String) {
        print(passName)

        let passFile = Bundle.main.resourcePath?.appending("/\(passName)")
        let passData = NSData(contentsOfFile: passFile!)

        do {
            let newpass = try PKPass.init(data: passData! as Data)
            let addController =  PKAddPassesViewController(pass: newpass)
            addController?.delegate = self
            self.present(addController!, animated: true)
        } catch {
            let alert = UIAlertController(title: "Error", message: "PassKit not available", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
                switch action.style{
                case .default:
                    print("default")
                case .cancel:
                    print("cancel")
                case .destructive:
                    print("destructive")
                @unknown default:
                    break
                }}))
            self.present(alert, animated: true, completion: nil)

            print(error)
        }
    }
1

The problem turned out to be related to pushing the PKAddPassesViewController to the navigation controller's stack.

replacing navigationController?.pushViewController(passVC, animated: true) with present(passVC, animated: true, completion: nil) fixed the problem!

Kelly Bennett
  • 725
  • 5
  • 27