iosiphoneswiftconnectivitywatchos-3

swift watch connectivity quits unexpectedly


I made a watchOS connectivity application and it works. Now I'm trying to make a dedicated classes for Connection at iPhone and Watch. For the iPhone connectivity class I have this (I also have other methods for transferring data but the problem is here):

import UIKit
import WatchConnectivity

class iPhoneConnectivity: UIViewController, WCSessionDelegate {

    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {

    }

    func sessionDidBecomeInactive(_ session: WCSession) {

    }

    func sessionDidDeactivate(_ session: WCSession) {

    }

    var session : WCSession!;

    func getPrepared() {
        if (WCSession.isSupported()) { 
            // check if the watch connectivity is suported on device
            self.session = WCSession.default;
            self.session.delegate = self;
            self.session.activate();
        } else {
            print("Session is not supported")
        }
    }
}

The problem is that when I try to call this method in ViewController

connect.getPrepared();

The application quits unexpectedly.

I have a global variable

var connect: iPhoneConnectivity!;

Is that because I didn't initialize the connect variable? If that's the problem, how should I initialized it?

In original application, which works, I have this code of getPrepared() method in ViewController's method didLoad()


Solution

  • The issue is that connect is an implicitly unwrapped optional and you call a function on it without actually initializing it. Implicitly unwrapped optionals are still optionals and hence if you don't give them a value, they are nil by default. Hence when you try to access them without giving them a non-nil value first, you will get a runtime exception.

    Define connect as a singleton and not as a global variable.

    class iPhoneConnectivity: WCSessionDelegate {
    
        static let sharedInstance = iPhoneConnectivity()
    
        func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}
    
        func sessionDidBecomeInactive(_ session: WCSession) {}
    
        func sessionDidDeactivate(_ session: WCSession) {}
    
        var session : WCSession!;
    
        func getPrepared() {
            if (WCSession.isSupported()) { 
                // check if the watch connectivity is suported on device
                self.session = WCSession.default;
                self.session.delegate = self;
                self.session.activate();
            } else {
                print("Session is not supported")
            }
        }
    }
    

    You can access it using iPhoneConnectivity.sharedInstance and call getPrepared() using iPhoneConnectivity.sharedInstance.getPrepared().