I am trying to use CoreLocation to get the latitude and longitude coordinates in iOS 8. After looking through a lot of posts, I am still unsure how to go about doing this. Also, I would appreciate a brief explanation of the locationManager() methods as I don't understand what role they play in obtaining the location. Do I ever need to call these methods? Because I never saw them called in any examples.
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationMan = CLLocationManager()
var ourLocation: CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.locationMan.delegate = self
self.locationMan.desiredAccuracy = kCLLocationAccuracyBest
self.locationMan.requestWhenInUseAuthorization()
self.locationMan.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations : [AnyObject]!){
locationMan.stopUpdatingLocation()
ourLocation = locations[0] as! CLLocation
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("Error: " + error.localizedDescription)
}
#IBAction func button(sender: AnyObject) {
var testClass:item = item()
After the next line, the app crashes and I get the error: fatal error: unexpectedly found nil while unwrapping an Optional value. I think this means that ourLocation never actually gets set. (Note that I am casting to float because I need to store the location as a float on my server)
testClass.lat = Float(ourLocation.coordinate.latitude)
println(testClass.lat)
testClass.long = Float(ourLocation.coordinate.longitude)
println(testClass.long)
testClass.name = "Nice"
testClass.description = "Wow this is pretty cool"
testClass.postItemToServer()
}
}
Note that I have updated my plist file appropriately! Location is turned on in the simulator.
Check if the values you are passing to variable are nil or not
if ourLocation.coordinate.latitude != nil
{
testClass.lat = Float(ourLocation.coordinate.latitude)
println(testClass.lat)
}
Also check for longitude.
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate{
var manager:CLLocationManager!
var location : CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.manager = CLLocationManager()
self.manager.delegate = self;
self.manager.desiredAccuracy = kCLLocationAccuracyBest
self.manager.requestWhenInUseAuthorization()
self.manager.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations : [AnyObject]!){
manager?.stopUpdatingLocation()
self.location = locations[0] as CLLocation
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("Error: " + error.localizedDescription)
}
#IBAction func button(sender: AnyObject) {
//check if location is not nil
if self.location != nil {
//assign your loaction values here
let lat = Float(location.coordinate.latitude)
let long = Float(location.coordinate.longitude)
} else {
println("locationManager.location is nil")
}
}
}
The location property is an implicitly unwrapped CLLocation optional, and it is likely nil. You should never access members of implicitly unwrapped optional unless you know it is not nil.
Related
I have an app that finds places near the user’s location, however, the app crashes the second time it runs with the exception:
fatal error: unexpectedly found nil while unwrapping an Optional value.
On line:
self.googleMapView.animate(toLocation: coordinates)
I checked and the googleMapView is nil but I don’t understand how it is nil or how it ran the first time. It only starts crashing on subsequent tries if I delete and reinstall the app it works fine on the first try but after that it keeps crashing even if I restart the app. Full code below
import UIKit
import GoogleMaps
import GooglePlacePicker
import MapKit
class MapViewController: UIViewController, CLLocationManagerDelegate {
var currentLongitude: CLLocationDegrees = 0
var currentLatitude: CLLocationDegrees = 0
var locationManager: CLLocationManager!
var placePicker: GMSPlacePickerViewController!
var googleMapView: GMSMapView!
#IBOutlet weak var mapViewContainer: MKMapView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.googleMapView = GMSMapView(frame: self.mapViewContainer.frame)
self.googleMapView.animate(toZoom: 18.0)
self.view.addSubview(googleMapView)
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager = CLLocationManager()
self.locationManager.delegate = self
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location:CLLocation = locations.last {
self.currentLatitude = location.coordinate.latitude
self.currentLongitude = location.coordinate.longitude
}
else {
print("Location Error")
}
let coordinates = CLLocationCoordinate2DMake(self.currentLatitude, self.currentLongitude)
let marker = GMSMarker(position: coordinates)
marker.title = "I am here"
marker.map = self.googleMapView
self.googleMapView.animate(toLocation: coordinates)
}
private func locationManager(manager: CLLocationManager,
didFailWithError error: Error){
print("An error occurred while tracking location changes : \(error.localizedDescription)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Crash is pretty self-explanatory:
You are setting your location's delegate in the viewDidLoad but creating the map in the viewDidAppear.
If the location was known by iOS, you will receive the message before viewDidAppear call so in the line : self.googleMapView.animate(toLocation: coordinates), your map is still nil
You can either define your map as optional : var googleMapView: GMSMapView?, or you can wait for your map to be defined to create your location Manager.
I am trying to get user location in my iPhone app. It has specified in info.plist needed permission (use location even if app is not offline). But still I do not see that my delegate is triggered at least once meaning I do not get even current location. Here is the code:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager = CLLocationManager();
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.notDetermined) {
self.locationManager.requestAlwaysAuthorization();
}
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0]
let long = userLocation.coordinate.longitude;
let lat = userLocation.coordinate.latitude;
print(lat)
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!)
{
locationManager.stopUpdatingLocation()
if ((error) != nil)
{
print(error)
}
}
Could somebody point me out possible problems?
Try to remove locationManager.stopUpdatingLocation() in locationManager(manager: CLLocationManager!, didFailWithError error: NSError!). It should work.
I have two different classes, one of them, LocationService, is just for determining location. Problem is that I don't know why it doesn't update coordinates variable.
ViewController:
import UIKit
class ViewController: UIViewController {
var coords: (lat: Double, long: Double) = (0,0)
var tracking = LocationServices()
override func viewDidLoad() {
super.viewDidLoad()
tracking.startTracking()
tracking.getLocations()
coordinat = tracking.coordinates
retreiveWeatherForecast()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// retrieveWeatherForecast functions
And simple locationService class:
import UIKit
import CoreLocation
class LocationServices: NSObject, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var coordinates: (lat: Double, long: Double) = (0,0)
func startTracking() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
locationManager.stopUpdatingLocation()
print(error)
}
func getLocations() {
#if os (ios)
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
//println("locations = \(locationManager)")
var latValue = locationManager.location.coordinate.latitude
var lonValue = locationManager.location.coordinate.longitude
coordinates = (latValue,lonValue)
println(latValue)
println(lonValue)
}
#endif
}
}
When I build it, it returns weather with default coordinates = (0,0).
Well, I accidentally made it work. As far as I understand problem was here: func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) locations must be of CLLocation type, not AnyObject.
I'm using Swift 2.0.
I am trying to make a super simple program that will as of right now print the speed from the iPhone's gps. This is my code so far:
//
// ViewController.swift
// GpsSpeed
//
// Created by Jacob Sandum on 4/18/15.
// Copyright (c) 2015 Jacob Sandum. All rights reserved.
//
import UIKit
import CoreLocation
let locationManager = CLLocationManager()
class ViewController: UIViewController, CLLocationManagerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
if CLLocationManager.authorizationStatus() == .NotDetermined {
locationManager.requestAlwaysAuthorization()
}
locationManager.desiredAccuracy=kCLLocationAccuracyBest
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
var speed: CLLocationSpeed = CLLocationSpeed()
speed = locationManager.location.speed
println(speed);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
When I try to run this code I get this fatal exception: unexpectedly found nil while unwrapping an Optional value
(lldb)
I think CLLocationSpeed is nil, but I do not know how to fix this.
First add NSLocationAlwaysUsageDescription in to your info.plist file
Then the full code is
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
if NSString(string:UIDevice.currentDevice().systemVersion).doubleValue > 8 {
locationManager.requestAlwaysAuthorization()
}
locationManager.desiredAccuracy=kCLLocationAccuracyBest
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var speed: CLLocationSpeed = CLLocationSpeed()
speed = locationManager.location.speed
println(speed);
}
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status != CLAuthorizationStatus.Denied{
locationManager.startUpdatingLocation()
}
}
}
Run it on real Device
Your error:
Do not get speed in ViewDidLoad it will only be called once.So,in your code, every time you try to get location before it start updating.
It is better to get speed when location update
It is better to start updating when auth changed
Im learning Xcode 6.3 and swift and following a book from apress Beginning Xcode with swift, in chapter 4 when doing the first tab for the location tracker it shows nothing at all and I'm confused. The code for the first tab is this
import UIKit
import CoreLocation
class TrackViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
#IBOutlet weak var locationText: UITextView!
#IBOutlet weak var toggleSwitch: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func changeToggle(sender: UISwitch) {
if toggleSwitch.on {
self.locationText.text = " "
if (CLLocationManager.locationServicesEnabled() == false) {
self.toggleSwitch.on = false
}
if locationManager == nil {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.distanceFilter = 10.0
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestWhenInUseAuthorization()
UIApplication.sharedApplication().cancelAllLocalNotifications()
NSLog("location is on supposely")
}
locationManager.startUpdatingLocation()
} else {
if locationManager != nil {
locationManager.stopUpdatingLocation()
}
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var location: CLLocation = locations[locations.endIndex - 1] as! CLLocation
self.locationText.text = location.description
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
locationText.text = "failed with error \(error.description)"
}
}
I have activated in the simulator the location services and in info.plist added the NSLocationWhenInUsageDescription and the Privacy - Location..., but nothing happens when toggling the switch I get no feedback that something is on. Any help??