Search code examples
iosswiftreachability

Getting this error: thread 1: exc_bad_instruction(code=exc_i386_invop,subcode=0x0)


I have developed an iOS application in swift 2.0 and have used a class called Reachability to determine whether the user is connected to the internet or not. The application runs, however the compiler stops and outputs this error:

thread 1: exc_bad_instruction(code=exc_i386_invop,subcode=0x0)

here is the code, and error occurs where the comment is.

func updateInterfaceWithReachability (reachability: Reachability)  {

    if reachability == self.hostReachability
    {
        self.checkStatus(reachability)

        let netStatus: NetworkStatus = reachability.currentReachabilityStatus()
        let connectionRequired: Bool = reachability.connectionRequired()

        var baseLabelText: NSString = ""

        if connectionRequired
        {
            baseLabelText = NSLocalizedString("Cellular data network is available.\nInternet traffic will be routed through it after a connection is established.", comment: "Reachability text if a connection is required")
        }
        else
        {
            baseLabelText = NSLocalizedString("Cellular data network is active.\nInternet traffic will be routed through it.", comment: "Reachability text if a connection is not required")
        }
    }


    if reachability == self.internetReachability  // error displayed here
    {
        self.checkStatus(reachability)
    }

    if reachability == self.wifiReachability
    {
        self.checkStatus(reachability)
    }

}

Also I declared internetReachability like this

var internetReachability: Reachability!

Also this is how i Initialized internetReachability in another function called checkStatus()

func checkInternetConnection () {

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("reachabilityChanged"), name: kReachabilityChangedNotification, object: nil)

    let remoteHostName: String = "www.apple.com"


    self.hostReachability = Reachability.init(hostName: remoteHostName)
    self.hostReachability.startNotifier()
    self.updateInterfaceWithReachability(self.hostReachability)

    self.internetReachability = Reachability.reachabilityForInternetConnection()
    self.internetReachability.startNotifier()
    self.updateInterfaceWithReachability(self.internetReachability)

    self.wifiReachability = Reachability.reachabilityForLocalWiFi()
    self.wifiReachability.startNotifier()
    self.updateInterfaceWithReachability(self.wifiReachability)
}

Do not understand what the error is and how to fix it. Help appreciated.


Solution

  • The code crashes on the given line because you declared the variable as implicitly unwrapped optional meaning that the value gets unwrapped in this situation to be able to compare it to reachability. But because you have not set anything to internetReachability yet, it is still nil and the code crashes because nil cannot be unwrapped.

    To fix this you have to either have to

    • explicitly check against nil
    • or declare the variable as var internetReachability: Reachability? and deal with the optionals thorughout your code
    • or make sure that the method checkInternetConnection is invoked before you try to access the internetReachability.

    Luckily there is an easy version of the last option for you here by simply rearranging your code:

    func checkInternetConnection () {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("reachabilityChanged"), name: kReachabilityChangedNotification, object: nil)
    
        let remoteHostName: String = "www.apple.com"
    
        self.hostReachability = Reachability.init(hostName: remoteHostName)
        self.internetReachability = Reachability.reachabilityForInternetConnection()
        self.wifiReachability = Reachability.reachabilityForLocalWiFi()
    
        self.hostReachability.startNotifier()
        self.internetReachability.startNotifier()
        self.wifiReachability.startNotifier()
    
        self.updateInterfaceWithReachability(self.internetReachability)
        self.updateInterfaceWithReachability(self.wifiReachability)
        self.updateInterfaceWithReachability(self.hostReachability)
    }
    

    That way you make sure the three reachability types are all set before the self.updateInterfaceWithReachability tries to access them.