1

I'm writing a program similar to runkeeper via Swift that keeps track of a user's movement. I do not have any trouble in monitoring the user's location, however, I am wondering if there is a way to determine whether a user has entered a building or not.

Geofencing crossed my mind but that would mean determining every building a user enters.

Another thought that came to mind was continuously firing code that determines the user's signal (but this seems a bit annoying--although if this is the only choice I'm left with I'll do this). My reasoning behind this is if I cannot determine whether the user has entered a building or not, I can at least detect when they have a poor signal through the CoreTelephony framework.

Whenever a run is initialized (through an object I call WalkingEngine -- note it hasn't been implemented here yet), I use that WalkingEngine as part of my Reachability helper's custom init and begin the process of continuously sending that signal (there might be a better way to do this, such as wait for when the signal actually turns poor?) This is the code:

import Foundation
import CoreTelephony


//When can we detect whether we have a connection or not? You'll have to lose a connection.

//MARK: Initialize the actual enum? We don't know where it's going to implemented otherwise,

enum ConnectionQuality : Int {
        case EBWConnectionQualityZero, EBWConnectionQualityLo, EBWConnectionQualityHi
    }



class ReachabilityHelper {
    //TODO Determine best initialization method. Check 
    //WalkEngine Init for reference


    //MARK: Check Phone's general connection status
//    func checkForGPSConnection () {
//        
//        let reachability: Reachability
//        let networkStatus = reachability.currentReachabilityStatus
//        
//        switch (networkStatus) {
//            case .NotReachable
//            
//        }
//        
//        
//    }



    //MARK: Check for the Phone's Connection Type
    func radioAccessType() -> String {
        //Print the current telephone's connection type for development
        //purposes. 
        var radioTelephoneInfo: CTTelephonyNetworkInfo
        print(radioTelephoneInfo)
        radioTelephoneInfo.currentRadioAccessTechnology
    }

    //MARK: Check for the quality of the Connection Type 
        //TODO This is an incredibly ugly if-else statement. There are much more elegenat ways
        //to express this via Swift. This code was written quickly so as to solve the problem.
    func connectionQualityForTechnology(ebwConnectionQuality: ConnectionQuality) -> (radioAccessTechnology: String) {

        if radioAccessTechnology == CTRadioAccessTechnologyGPRS {
            return ConnectionQuality.EBWConnectionQualityZero
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyEdge{
            return ConnectionQuality.EBWConnectionQualityZero
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyWCDMA {
            return ConnectionQuality.EBWConnectionQualityLo
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyHSDPA {
            return ConnectionQuality.EBWConnectionQualityLo
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyHSUPA {
            return ConnectionQuality.EBWConnectionQualityLo
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyCDMA1x {
            return ConnectionQuality.EBWConnectionQualityZero
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyCDMAEVDORev0 {
            return ConnectionQuality.EBWConnectionQualityLo
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyCDMAEVDORevA {
            return ConnectionQuality.EBWConnectionQualityLo
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyCDMAEVDORevB {
            return ConnectionQuality.EBWConnectionQualityLo
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyeHRPD {
            return ConnectionQuality.EBWConnectionQualityHi
        }
        else if radioAccessTechnology == CTRadioAccessTechnologyLTE {
            return ConnectionQuality.EBWConnectionQualityHi
        }

        return ConnectionQuality.EBWConnectionQualityHi
    }

}
KFDoom
  • 772
  • 1
  • 6
  • 19
  • Hmmm. I had initially answered the question thinking that you were interested in one specific building, but after I posted it and re-read your question, I realized that you meant any building, so I deleted my answer. :) – Eric Galluzzo Jan 08 '16 at 13:22
  • I can't think of any way to reliably do what you're asking specifically, especially since some buildings (e.g. with thick concrete walls) will block radio signals and some (e.g. houses) won't significantly -- and also, the user's signal may attenuate simply due to poor coverage while outside, although usually more gradually. However, would it be sufficient to determine when the user stops moving significantly for a certain period of time? You could accomplish that with regular location updates. – Eric Galluzzo Jan 08 '16 at 13:23
  • @EricGalluzzo Hello Eric! Thank you for your kind response. I'm of the same mindset. I don't know if the former is accomplishable. But your latter proposal--determining when the user stops moving significantly for a certain period of time--sounds promising. What are you thinking? – KFDoom Jan 08 '16 at 13:31
  • Well, you could use `CLLocationManager` to `startUpdatingLocation` with sufficient accuracy (which you can do when your app is in the background, although it's not particularly recommended). Then, if the distance between the lat/long on the events stays within a certain epsilon for a certain period of time (say, 100m for 2 minutes), then the user has stopped and is possibly in a building. Of course, they could also be sitting on a park bench, but I didn't claim this method was foolproof. :) – Eric Galluzzo Jan 08 '16 at 13:38
  • @EricGalluzzo I like it! And things are rarely 100% foolproof so I'm supportive of first finding a solution, than improving it. ;) – KFDoom Jan 08 '16 at 14:03
  • 1
    Sounds good to me! Let me know if you run into any problems. – Eric Galluzzo Jan 08 '16 at 14:08
  • Building now... If all works out rest assured I will return and give you your much deserved check mark! – KFDoom Jan 08 '16 at 14:09
  • gps signals degrade indoors. Maybe there is some way to measure the quality of that signal as an additional factor? – nwales Jan 08 '16 at 15:02
  • @nwales any doc to back this claim up? I can't seem to find something that alludes to that. – KFDoom Jan 08 '16 at 17:14
  • @KacheFlowe not that I know of, but I believe I am generally correct that gps accuracy falls off indoors (in many cases). The extent to which this can be measured and used as a way to detect indoors I have no idea if that's possible or even practical. Just speculating. – nwales Jan 08 '16 at 18:53

0 Answers0