What code does iPhone Compass use to display location coordinates even without an internet connection? - ios

I have made an app that will display the co-ordinates of the user location. It works fine with Wifi connectivity but fails to display anything despite waiting for 2-3 minutes, when there isn't internet connection. I was curious how Compass, iphone's inbuilt app could display the coordinates in a matter of seconds after calibration.
My following code, which is written in swift, finds the address based on the co-ordinates from GPS. I'm just confused why this code isn't able to display latitude and longitude in the absence of internet connectivity.
Any help is greatly appreciated. Thank you!
import UIKit
import CoreLocation
class ViewController2: UIViewController, CLLocationManagerDelegate
{
#IBOutlet var locality: UILabel?
#IBOutlet var postalCode: UILabel?
#IBOutlet var AdministrativeArea: UILabel?
#IBOutlet var country: UILabel?
#IBOutlet var latitude: UILabel?
#IBOutlet var longitude: UILabel?
var currentLocation = CLLocation()
let locationManager = CLLocationManager()
override func viewDidLoad()
{
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
currentLocation = locationManager.location
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
{
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks, error)->Void in
if (error != nil)
{
println("Error: " + error.localizedDescription)
return
}
if placemarks.count > 0
{
let pm = placemarks[0] as! CLPlacemark
self.displayLocationInfo(pm)
}
else
{
println("Error with the data.")
}
})
}
func displayLocationInfo(placemark: CLPlacemark)
{
/
locality?.text = "\(placemark.locality)"
postalCode?.text = "\(placemark.postalCode)"
AdministrativeArea?.text = "\(placemark.administrativeArea)"
country?.text = "\(placemark.country)"
latitude?.text = "\(currentLocation.coordinate.latitude)"
longitude?.text = "\(currentLocation.coordinate.longitude)"
}

Related

Created a function but in an if statement the function isn't recognized swift

I made the function getLocation() and used it in an else{ getLocation()} which works. Later when I tried to define a new function locationmanager the if...{ getLocation()} gets the error:
Use of unresolved identifier 'getLocation'
I'm not sure if the syntax isn't right or if there's another way to call on the getLocation function.
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate {
var coreLocationManager = CLLocationManager()
var locationManager: LocationManager!
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var location_info: UILabel!
#IBAction func Update_Location(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
coreLocationManager.delegate=self
locationManager = LocationManager.sharedInstance
let authorizationCode = CLLocationManager.authorizationStatus()
if authorizationCode == CLAuthorizationStatus.notDetermined &&
coreLocationManager.responds(to: #selector(CLLocationManager.requestWhenInUseAuthorization))||coreLocationManager.responds(to: #selector(CLLocationManager.requestAlwaysAuthorization)){}
if Bundle.main.object(forInfoDictionaryKey: "NSlocationWhenInUseUsageDescription") != nil{
coreLocationManager.requestWhenInUseAuthorization()
}else{
getLocation()
}
}
func getLocation(){
locationManager.startUpdatingLocationWithCompletionHandler{(latitude, longitude, status, verboseMessage, error)->()in
self.displayLocation(location: CLLocation(latitude: latitude, longitude: longitude))
}
}
func displayLocation(location:CLLocation){
mapView.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude),span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)), animated:true)
let locationPinCoord = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let annotation = MKPointAnnotation()
annotation.coordinate = locationPinCoord
mapView.addAnnotation(annotation)
mapView.showAnnotations([annotation], animated: true)
locationManager.reverseGeocodeLocationWithCoordinates(location) { (reverseGecodeInfo, placemark, error) in
print(reverseGecodeInfo!)
}
}
}
func locationmanager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus){
if status != CLAuthorizationStatus.notDetermined || status != CLAuthorizationStatus.denied || status != CLAuthorizationStatus.restricted {
getLocation()
}
}
Do yourself a favor and use proper indentation.
Try this, select-all, cut, then paste. Xcode will auto indent for you and you will immediately see that the problem is that you have a } in the wrong place.

Swift 4 CoreLocation not working

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.

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