Swift 4 CoreLocation not working - ios

why this code does not working? I guess it's something with didUpdateLocations overrated method? How I can correctly connect them with my labels and make them a live :)
import UIKit
import CoreLocation
class MainVC: UIViewController, CLLocationManagerDelegate {
var walking = false
var pause = false
var locationManager: CLLocationManager = CLLocationManager()
var startLocation: CLLocation!
var speed: CLLocationSpeed = CLLocationSpeed()
#IBOutlet weak var latitudeLabel: UILabel!
#IBOutlet weak var longitudeLabel: UILabel!
#IBOutlet weak var horizontalAccuracyLabel: UILabel!
#IBOutlet weak var verticalAccuracyLabel: UILabel!
#IBOutlet weak var distanceLabel: UILabel!
#IBOutlet weak var altitudeLabel: UILabel!
#IBOutlet weak var speedLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
startLocation = nil
// Ask for Authorisation from the User.
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func startDistance(_ sender: UIButton) {
startLocation = nil
walking = true
}
#IBAction func stopDistance(_ sender: UIButton) {
walking = false
}
#IBAction func resetDistance(_ sender: UIButton) {
startLocation = nil
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let latestLocation: AnyObject = locations[locations.count - 1]
latitudeLabel.text = String(format: "%.4f",latestLocation.coordinate.latitude)
longitudeLabel.text = String(format: "%.4f",latestLocation.coordinate.longitude)
horizontalAccuracyLabel.text = String(format: "%.4f",latestLocation.horizontalAccuracy)
verticalAccuracyLabel.text = String(format: "%.4f",latestLocation.verticalAccuracy)
altitudeLabel.text = String(format: "%.4f",latestLocation.altitude)
if walking == true {
if startLocation == nil {
startLocation = latestLocation as! CLLocation
speed = locationManager.location!.speed
speedLabel.text = String(format: "%.0f km/h", speed * 3.6)
}
let distanceBetween: CLLocationDistance =
latestLocation.distance(from: startLocation)
distanceLabel.text = String(format: "%.2f", distanceBetween)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)
{
// capLabel.text = String(format: "%.4f",newHeading.magneticHeading)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
}
}
I also added: Location Always Usage Description in my info.plist
And i allowed Location in the Settings on my simulator too.
Thank you.

To configure always authorization in Swift 4 for location services which I can see you have written in your code self.locationManager.requestAlwaysAuthorization(), do the following:
There is a new key NSLocationAlwaysAndWhenInUsageDescription which is also required in your info.plist
<key>NSLocationAlwaysUsageDescription</key>
<string> location permission text.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string> location permission text.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string> location permission text.</string>
Take a look in the documentation here
You are required to include the NSLocationWhenInUseUsageDescription
and NSLocationAlwaysAndWhenInUsageDescription keys in your app's
Info.plist file. (If your app supports iOS 10 and earlier, the
NSLocationAlwaysUsageDescription key is also required.) If those keys
are not present, authorization requests fail immediately.
So we will have a single prompt now.

Related

UI won't update after getting json data from Openweathermap IOS 4 Xcode 10

my JSON have been printed to console with the correct value request. but label.text and city.text won't update UI in main controller
#IBOutlet weak var icon: UIImageView!
#IBOutlet weak var date: UILabel!
#IBOutlet weak var weatherType: UILabel!
#IBOutlet weak var degree: UILabel!
#IBOutlet weak var city: UILabel!
var currentWeather : CurrentWeather!
override func viewDidLoad() {
super.viewDidLoad()
currentWeather = CurrentWeather()
}
override func viewDidAppear(_ animated: Bool) {
super .viewDidAppear(animated)
locationAuthStatus()
}
func locationAuthStatus() {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
currentLocaion = locationManager.location
//Location.sharedIntance.latitude = currentLocaion.coordinate.latitude
//Location.sharedIntance.longitude = currentLocaion.coordinate.longitude
print(currentLocaion)
currentWeather.downloadWeatherDetail {
downloadForecastData {
self.updateMainUI()
}
}
} else {
locationManager.requestWhenInUseAuthorization()
locationAuthStatus()
}
}
func updateMainUI() {
icon.image = UIImage(named: currentWeather.weatherType)
city.text = currentWeather.cityName
degree.text = "\(currentWeather.currentTemp)"
weatherType.text = currentWeather.weatherType
date.text = currentWeather.date
}
}
I am new to coding and 'm having a hard figuring out why isn't it showing since I confirmed that I am pulling data from Json to my console
These lines won't do what you expect.
locationManager.requestWhenInUseAuthorization()
locationAuthStatus()
Your call to requestWhenInUseAuthorization is asynchronous and should be handled by a CLLocationManagerDelegate which can be your view controller. You can do this like this:
class ViewController: UITableViewController, CLLocationManagerDelegate {
// rest of class
Add these functions to your class
func locationManager(_ manager: CLLocationManager, didUpdateLocations objects: [CLLocation]) {
let location = objects[objects.count-1]
let currentLocation = location
print(currentLocation)
currentWeather.downloadWeatherDetail {
downloadForecastData {
self.updateMainUI()
}
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
// handle error
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
locationManager.startUpdatingLocation()
}

MapView Not Showing Location

I'm currently developing an iOS app, and one of its functions include locating places of interest for nightlife. However, when my MapView loads, current user location is not displayed, even though location access has been granted.
Here is my code:
import UIKit
import MapKit
import CoreLocation
class BarMapVC: UIViewController {
#IBOutlet weak var searchBtn: UIBarButtonItem!
#IBOutlet weak var doneBtn: UIBarButtonItem!
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var locationBtn: UIButton!
#IBOutlet weak var barMapView: MKMapView!
var locationManager = CLLocationManager()
let authorizationStatus = CLLocationManager.authorizationStatus()
let regionRadius: Double = 1000
override func viewDidLoad() {
super.viewDidLoad()
searchBar.isHidden = true
barMapView.delegate = self
locationManager.delegate = self
configureLocationServices()
centerMapOnUserLocation()
}
#IBAction func searchBtnWasPressed(_ sender: Any) {
searchBar.isHidden = false
}
#IBAction func doneBtnWasPressed(_ sender: Any) {
dismiss(animated: true)
}
#IBAction func locationBtnWasPressed(_ sender: Any) {
if authorizationStatus == .authorizedAlways || authorizationStatus == .authorizedWhenInUse {
centerMapOnUserLocation()
}
}
}
extension BarMapVC: MKMapViewDelegate {
func centerMapOnUserLocation() {
guard let coordinate = locationManager.location?.coordinate else { return }
let coordinateRegion = MKCoordinateRegionMakeWithDistance(coordinate, regionRadius * 2.0, regionRadius * 2.0)
barMapView.setRegion(coordinateRegion, animated: true)
}
}
extension BarMapVC: CLLocationManagerDelegate {
func configureLocationServices() {
if authorizationStatus == .notDetermined {
locationManager.requestAlwaysAuthorization()
} else {
return
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
centerMapOnUserLocation()
}
}
I'm using CLLocation Manager, complying to mapViewDelegate, as well as have all needed outlets. Anything I' m doing wrong?
You can set this on your map view:
barMapView.showsUserLocation = true

fatal error: unexpectedly found nil while unwrapping an Optional value while printing on UILabel

I'm trying to display the users current location and calculate the distance he traveled and i'm getting error at displaying it on distance1.text, can somebody please help me. Thanks in advance and I'm very new to iOS app development, currently using swift3
import UIKit
import MapKit
import CoreLocation
class MapView1: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var distance1: UILabel!
let locationManager = CLLocationManager()
var startLocation:CLLocation!
var lastLocation: CLLocation!
var traveledDistance:Double = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
startLocation = nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: Location Delegate Methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center1 = CLLocationCoordinate2D(latitude: location!.coordinate.latitude , longitude: location!.coordinate.longitude)
let region1 = MKCoordinateRegion(center: center1, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region1, animated: true)
self.locationManager.stopUpdatingLocation()
if startLocation == nil {
startLocation = location
}
let distanceBetween: CLLocationDistance =
location!.distance(from: startLocation)
distance1.text = String(format: "%.2f", distanceBetween)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Error: " + error.localizedDescription)
}
}

IOS __connection_block_invoke_2 Swift 2.0 xCode 7.1 El Capitan 10.1

Running Xcode 7.1 on IOS 9.1 on a MBR with El Capitan 10.1. Wrote this simple piece of code that appears run but then doesn't update it would seem and noted this error message; is a silent crash?
"error in __connection_block_invoke_2: Connection interrupted"
Unclear how I can move forward with this? CLLocation does't appear to be updating itself after initially getting a correct value of sorts. Is it related to the above message?
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var Latitude: UILabel!
#IBOutlet weak var Longitude: UILabel!
#IBOutlet weak var HorizontalAccuracy: UILabel!
#IBOutlet weak var CurrentAlltitude: UILabel!
#IBOutlet weak var VerticalAccuracy: UILabel!
#IBOutlet weak var Distance: UILabel!
var locationManager: CLLocationManager = CLLocationManager()
var startLocation: CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
startLocation = nil
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let latestLocation: AnyObject = locations[locations.count - 1]
Latitude.text = String(format: "%.6f",
latestLocation.coordinate.latitude)
Longitude.text = String(format: "%.6f",
latestLocation.coordinate.longitude)
HorizontalAccuracy.text = String(format: "%.4f",
latestLocation.horizontalAccuracy)
CurrentAlltitude.text = String(format: "%.4f",
latestLocation.altitude)
VerticalAccuracy.text = String(format: "%.4f",
latestLocation.verticalAccuracy)
if startLocation == nil {
startLocation = latestLocation as! CLLocation
}
let distanceBetween: CLLocationDistance =
latestLocation.distanceFromLocation(startLocation)
Distance.text = String(format: "%.2f", distanceBetween)
}
func locationManager(manager: CLLocationManager,
didFailWithError error: NSError) {
}
#IBAction func ResetDistance(sender: AnyObject) {
startLocation = nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Doesn't seem to update my location if I walk around with my iPad?
Wrote a comment; double checked and found my target was 8.1; running on an iPad with 9.1. Changed it and now it works!!
Still getting that odd error message; but doesn't seem to stop it working correctly!!

location constantly updating problems iOS Swift

I am getting the users current location and dropping this as a println(). The idea is that I am going to hit a button to get the new location, however currently the app keeps updating constantly (every second) instead. I have tried moving the getLocation() function inside my IBAction but that crashed the thing. I have updated the info.plist so thats not a problem. Heres le code:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate{
#IBOutlet var latitude : UILabel!
#IBOutlet var longitude : UILabel!
var locationManager = CLLocationManager()
var startLocation: CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func findMyLocation(sender: AnyObject){
startLocation = nil
locationManager.startUpdatingLocation()
}
func getLocation(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!){
var userLocation:AnyObject = locations[0] as! CLLocation
var strlat = String(format: "%.4f", userLocation.coordinate.latitude)
var strlong = String(format: "%.4f",userLocation.coordinate.longitude)
latitude.text = String(format: "%.4f", userLocation.coordinate.latitude)
longitude.text = String(format: "%.4f",userLocation.coordinate.longitude)
println("latitude: " + strlat)
println("longitide: " + strlong)
if startLocation == nil {
startLocation = userLocation as! CLLocation
locationManager.stopUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager!,
didFailWithError error: NSError!) {
}
}
Move the locationManager.startUpdatingLocation() to your findMyLocation function. This will start the locationManager when your button is pressed and begin calling the didUpdateLocations Inside your if startLocation == nil add locationManager.stopUpdatingLocation() this will stop the locationManager after you have set your startLocation var. Every time the user presses the button the process will run again.
One additional note, you should add more code into the didUpdateLocations to check the accuracy and timestamp of the location before you use it as it may not be a valid/accurate location for what you are trying to do.
UPDATE:
Had a chance to validate and the code will work with the changes suggested. Here is what your final code should look like. I am also assuming you have set your plist entries for locations services and your simulator is set to simulate locaitons.
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate{
#IBOutlet var latitude : UILabel!
#IBOutlet var longitude : UILabel!
var locationManager : CLLocationManager! = CLLocationManager()
var startLocation: CLLocation!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func findMyLocation(sender: AnyObject){
startLocation = nil
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!){
var userLocation:AnyObject = locations[0] as! CLLocation
var strlat = String(format: "%.4f", userLocation.coordinate.latitude)
var strlong = String(format: "%.4f",userLocation.coordinate.longitude)
latitude.text = String(format: "%.4f", userLocation.coordinate.latitude)
longitude.text = String(format: "%.4f",userLocation.coordinate.longitude)
println("latitude: " + strlat)
println("longitide: " + strlong)
if startLocation == nil {
startLocation = userLocation as! CLLocation
locationManager.stopUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("error with location manager: " + error.description)
}
}

Resources