Reputation: 3
let locationManager = CLLocationManager()
@IBOutlet var map: MKMapView!
func getLocation ()-> CLLocation! {
self.locationManager.startUpdatingLocation()
sleep(1)
self.locationManager.stopUpdatingLocation()
var x = locationManager.location
return x
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
var mapCoord:CLLocation! = getLocation()
var mapLat:Double! = mapCoord.coordinate.latitude //Where the thread error is
var mapLong:Double! = mapCoord.coordinate.longitude
//Setup of the rest of the map is completed
My code is as above, in Swift. I am receiving an error:
thread error of an unexpected nil value
while calling for coordinates from the getLocation()
function. I changed both mapLat
and mapLong
to test what is causing the nil. My app will load but I receive a message in the output saying my current location cannot be updated as I have no asked for permission; however, I do have the function to request for permission in the beginning of my viewDiDLoad()
. I have used this format before on a different project and it has worked, so I know I must be missing something obvious, etc. Thank you for any help.
Upvotes: 0
Views: 93
Reputation: 5590
Try this. You'll need to request permission and only when you have a valid permissions can you start updating.
typealias Location = CLLocation
//MARK: Private Variables
private let locationManager = CLLocationManager()
private var currentLocation: Location? {
didSet {
// You have a new location. Use it somehow
}
}
//MARK: View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
}
override func viewWillAppear(animated: Bool) {
// Ask for permission if necessary
let currentStatus = CLLocationManager.authorizationStatus()
if currentStatus == .Restricted || currentStatus == .Denied || currentStatus == .NotDetermined {
locationManager.requestWhenInUseAuthorization()
} else {
locationManager.startUpdatingLocation()
}
}
//MARK: CLLocationManagerDelegate
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .AuthorizedWhenInUse {
locationManager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
newLocation
currentLocation = newLocation
locationManager.stopUpdatingLocation()
}
Upvotes: 0
Reputation: 131471
Your code is very wrong, and won't work.
You can't write procedural code that starts location updates, pauses, stops location updates, and then gets a location.
You have to set yourself up as the location manager's delegate, start location updates, and return.
At some point after that, the system will call your locationManager:didUpdateLocations
method.
Then you need to check the accuracy of the location that you get and make sure it's accurate enough. (Frequently the first several location readings you get when the GPS is first powered up are quite bad, and don't meet your desired accuracy. I suggest a horizontal accuracy of 200 M or so, depending on your app's requirements.
If you get a reading that is accurate enough you can turn off updates and use that location for your needs.
P.S. Never, ever, EVER use the sleep()
function on the main thread. In fact, as a novice iOS Mac OS developer, you should pretend that the sleep function doesn't exist.
Upvotes: 1