2

I have a pretty basic app configured. It uses a navigation controller, along with a view controller that i have configured as my map view controller.

When the app launches, it launches to the Root View Controller, and from there, i have a button that's configured to segue to the map view controller and display the map. When this happens, the alert view will display, but before i can select allow/don't allow, it disappears and the map loads.

Why does the alert view disappear on its own?

I've configured the info.plist file accordingly, added the necessary frameworks and added the appropriate delegates.

Below is the code i have configured:

import UIKit
import MapKit
import CoreLocation


class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

@IBOutlet weak var map: MKMapView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()

}


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

    let userLocation = locations[0]

    let latitude = userLocation.coordinate.latitude
    let longitude = userLocation.coordinate.longitude
    let latDelta: CLLocationDegrees = 0.01
    let lonDelta: CLLocationDegrees = 0.01
    let coordinate: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
    let span: MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
    let region: MKCoordinateRegion = MKCoordinateRegionMake(coordinate, span)
    map.setRegion(region, animated: true)
}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
    print(error)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

Any help will be greatly appreciated! Thanks in advance!

Don Alejandro
  • 885
  • 1
  • 7
  • 16

2 Answers2

4

Declare your locationManager ivar outside of viewDidLoad. It is being deallocated after viewDidLoad completes because nothing has a strong reference to it. You should probably also only start scanning after your user has granted access.

var locationManager:CLLocationManager!

override func viewDidLoad() {
  super.viewDidLoad()

  locationManager = CLLocationManager()
  locationManager.delegate = self
  locationManager.desiredAccuracy = kCLLocationAccuracyBest
  let authorizationStatus = CLLocationManager.authorizationStatus()
    if (authorizationStatus == CLAuthorizationStatus.NotDetermined) {
      locationManager.requestWhenInUseAuthorization()
    } else if (authorizationStatus == CLAuthorizationStatus.AuthorizedWhenInUse) {
      locationManager.startUpdatingLocation()
    }
}

func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
  if (status == CLAuthorizationStatus.AuthorizedWhenInUse) {
    locationManager.startUpdatingLocation()
  }

}

Keller
  • 17,051
  • 8
  • 55
  • 72
  • Would it be better to use "var locationManager:CLLocationManager?" (with question mark) or "var locationManager:CLLocationManager!" (with the exclamation mark) instead? – Don Alejandro Oct 05 '15 at 18:39
  • if you want to require a locationManager to be initialized. which yes, you probably do. – Keller Oct 05 '15 at 19:17
  • Why is it recommended to initialize it first outside of the viewDidLoad? How come i can't just use var locationManager = CLLocationManager() outside of the viewDidLoad? – Don Alejandro Oct 05 '15 at 22:26
  • 1
    An important distinction is that you aren't initializing locationManager outside of viewDidLoad. You are initializing it inside viewDidLoad. You are declaring a strong-referenced property on a class level. https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html – Keller Oct 06 '15 at 15:03
  • This just blew my mind AND saved my skin. Thanks @Keller! –  Jun 29 '16 at 16:55
0

Because you're doing it wrong. The CLLocationManagerDelegate protocol has a method called didChangeAuthorizationStatus. You should check there if the user allowed or not the app to use location. After checking that, you should call startUpdatingLocation. Be sure to do all UI updates required by this code using dispatch_async on the main queue as well.

Jorge
  • 1,066
  • 8
  • 16