No boarding pass appears

I went through the tutorial at https://www.raywenderlich.com/117329/watchos-2-tutorial-part-4-watch-connectivity and everything works except boarding passes will not show up for checking on flights for some reason ...

Here's my AppDelegate:

import UIKit
import WatchConnectivity

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?

    var session: WCSession? {
        didSet {
            if let session = session {
                session.delegate = self
                session.activate()
            }
        }
    }

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    if WCSession.isSupported() {
        session = WCSession.default()
    }
    return true
  }

}

extension AppDelegate: WCSessionDelegate {
    /** Called when all delegate callbacks for the previously selected watch has occurred. The session can be re-activated for the now selected watch using activateSession. */
    @available(iOS 9.3, *)
    public func sessionDidDeactivate(_ session: WCSession) {

    }

    /** Called when the session can no longer be used to modify or add any new transfers and, all interactive messages will be cancelled, but delegate callbacks for background transfers can still occur. This will happen when the selected watch is being changed. */
    @available(iOS 9.3, *)
    public func sessionDidBecomeInactive(_ session: WCSession) {

    }

    /** Called when the session has completed activation. If session state is WCSessionActivationStateNotActivated there will be an error with more details. */
    @available(iOS 9.3, *)
    public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {

    }

    func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
        if let reference = message["reference"] as? String, let boardingPass = QRCode(reference) {
            replyHandler(["boardingPassData": boardingPass.PNGData as AnyObject])
        }
    }

}

      

Here's my BoardingPassController:

import WatchKit
import Foundation
import WatchConnectivity

class BoardingPassInterfaceController: WKInterfaceController {

    @IBOutlet var originLabel: WKInterfaceLabel!
    @IBOutlet var destinationLabel: WKInterfaceLabel!
    @IBOutlet var boardingPassImage: WKInterfaceImage!

    var flight: Flight? {
        didSet {
            if let flight = flight {
                originLabel.setText(flight.origin)
                destinationLabel.setText(flight.destination)

                if let _ = flight.boardingPass {
                    showBoardingPass()
                }
            }
        }
    }

    var session: WCSession? {
        didSet {
            if let session = session {
                session.delegate = self
                session.activate()
            }
        }
    }

    private func showBoardingPass() {
        boardingPassImage.stopAnimating()
        boardingPassImage.setWidth(120)
        boardingPassImage.setHeight(120)
        boardingPassImage.setImage(flight?.boardingPass)
    }

    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
        if let flight = context as? Flight { self.flight = flight }
    }

    override func didAppear() {
        super.didAppear()
        // 1
        if let flight = flight, flight.boardingPass == nil && WCSession.isSupported() {
            // 2
            session = WCSession.default()
            // 3
            session!.sendMessage(["reference": flight.reference], replyHandler: { (response) -> Void in
                // 4
                if let boardingPassData = response["boardingPassData"] as? NSData, let boardingPass = UIImage(data: boardingPassData as Data) {
                    // 5
                    flight.boardingPass = boardingPass

                    DispatchQueue.main.async(execute: { () -> Void in
                        self.showBoardingPass()
                    })
                }
            }, errorHandler: { (error) -> Void in
                // 6
                print(error)
            })
        }
    }

}

extension BoardingPassInterfaceController: WCSessionDelegate {
    /** Called when the session has completed activation. If session state is WCSessionActivationStateNotActivated there will be an error with more details. */
    @available(watchOS 2.2, *)
    public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {

    }
}

      

Finally, here's what Xcode says:

2017-04-02 12:44:30.355378 Watch Extension[3124:56068] [WC] WCSession has not been activated  
2017-04-02 12:44:30.356432 Watch Extension[3124:56068] [WC] -[WCSession _onqueue_notifyOfMessageError:withErrorHandler:] errorHandler: YES with WCErrorCodeSessionNotActivated  
2017-04-02 12:44:30.357903 Watch Extension[3124:56068] [WC] __60-[WCSession _onqueue_notifyOfMessageError:withErrorHandler:]_block_invoke dropping as pairingIDs no longer match. pairingID (null), client pairingID: (null)  
Error Domain=WCErrorDomain Code=7004 "WatchConnectivity session has not been activated." UserInfo={NSLocalizedRecoverySuggestion=Activate the WatchConnectivity session., NSLocalizedDescription=WatchConnectivity session has not been activated., NSLocalizedFailureReason=Function activateSession has not been called.}

      

How can I change the code to solve this problem?

Many thanks,

Matt

+3


source to share





All Articles