Niko Zarzani
Niko Zarzani

Reputation: 1402

iOS debug location monitoring when app is closed from simulator

It seems that my app is not launched and called with location updates when it is in a terminated state.

Since it is a little bit hard for me to test what is not working (using a real device is not really easy when you have to move back and forth inside an office trying to trigger a significant location change), is there a way to simulate location changes in the simulator while the app is closed?

I have already tried using the Simulator > Debug > Location > [City Bicyce Ride, ...] but it seems that it works only when the app is running. I even tried creating a scheme where the app is not launch automatically after compiling.

Do you have any suggestion on how to debug this kind of issues? (By now I am just logging on separate files at every application launch, even though unfortunately the app gets not launched in background when is in a closed state )

This is the code in my app delegate:

    lazy var locationManagerFitness: CLLocationManager! = {
        let manager = CLLocationManager()
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.distanceFilter = 1.0
        manager.activityType = CLActivityType.Fitness
        manager.delegate = self
        manager.requestAlwaysAuthorization()
        return manager
    }()

    func startLocationMonitoring()
    {
        locationManagerFitness.stopMonitoringSignificantLocationChanges()
        locationManagerFitness.startUpdatingLocation()
    }

    func startLocationMonitoringSignificantChanges()
    {
        locationManagerFitness.stopUpdatingLocation()
        locationManagerFitness.startMonitoringSignificantLocationChanges()
    }

    // MARK: - CLLocationManagerDelegate

   func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
    {

        if manager == locationManagerFitness
        {
            log.debug("locationManagerFitness:")
        }

        for newLocation in locations
        {
            saveLocation(newLocation)

            if UIApplication.sharedApplication().applicationState == .Active {
                log.debug("App is active. New location is \( newLocation )")
            } else {
                log.debug("App is in background. New location is \( newLocation )")
            }
        }

    }

    func saveLocation(location: CLLocation) -> Location {

        let entity =  NSEntityDescription.entityForName("Location",
                                                        inManagedObjectContext:managedObjectContext)
        let locationCD = NSManagedObject(entity: entity!,
                                         insertIntoManagedObjectContext: managedObjectContext) as! Location

        locationCD.setValue(location.coordinate.latitude, forKey: "latitude")
        locationCD.setValue(location.coordinate.longitude, forKey: "longitude")
        locationCD.setValue(NSDate(), forKey: "creationDate")

        do {
            try managedObjectContext.save()
        } catch let error as NSError  {
            print("Could not save \(error), \(error.userInfo)")
        }

        return locationCD
    }

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?)
-> Bool {


        //Logs
        let documentDirectoryURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)

        let dayTimePeriodFormatter = NSDateFormatter()
        dayTimePeriodFormatter.dateFormat = "hh:mm_dd-MM-yyyy"
        let dateString = dayTimePeriodFormatter.stringFromDate(NSDate())
        let logURL = documentDirectoryURL.URLByAppendingPathComponent("log_\( dateString ).txt")
        log.setup(.Debug, showThreadName: true, showLogLevel: true, showFileNames: true, showLineNumbers: true, writeToFile: logURL, fileLogLevel: .Debug)

        log.debug("Starting app...")

        // StatusBar
        UIApplication.sharedApplication().statusBarStyle = .LightContent

        switch CLLocationManager.authorizationStatus()
        {
        case .AuthorizedAlways:
            if let _ = launchOptions?[UIApplicationLaunchOptionsLocationKey]
            {
                startLocationMonitoringSignificantChanges()
            }
        default:
            break;
        }

        log.debug("App started!")

        return true
    }

    func applicationDidEnterBackground(application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
        log.debug("startLocationMonitoringSignificantChanges")
        startLocationMonitoringSignificantChanges()
    }

    func applicationDidBecomeActive(application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
        log.debug("startLocationMonitoring")
        startLocationMonitoring()
    }

The behavior of the above code is that the app is monitoring user location changes only when it is active. Looking the image below is clear that the simulator seems to continue to move the location of the Bicycle Ride, however the AppDelegate CLLocationManagerDelegate's locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) is not called while the app is terminated or in background:

enter image description here

Upvotes: 3

Views: 1267

Answers (1)

Did you tried the custom Location instead of City Bycle Ride? One of my app I used Region Monitoring and if I give manually the locations then it is work even if i lock the simulator.

Upvotes: 0

Related Questions